Socket編程
目前較為流行的網絡編程模型是客戶機/服務器通信模式
客戶進程向服務器進程發出要求某種服務的請求,服務器進程響應該請求。如圖所示,通常,一個服務器進程會同時為多個客戶端進程服務,圖中服務器進程B1同時為客戶進程A1、A2和B2提供服務。
Socket概述
① 所謂Socket通常也稱作“套接字”,用於描述IP地址和端口,是一個通信鏈的句柄。應用程序通常通過“套接字”向網絡發出請求或者應答網絡請求。
② Socket是連接運行在網絡上的兩個程序間的雙向通信的端點。
③ 網絡通訊其實指的就是Socket間的通訊。
④ 通訊的兩端都有Socket,數據在兩個Socket之間通過IO來進行傳輸。
使用Socket進行網絡通信的過程
① 服務器程序將一個套接字綁定到一個特定的端口,並通過此套接字等待和監聽客戶的連接請求。
② 客戶程序根據服務器程序所在的主機和端口號發出連接請求。
③ 如果一切正常,服務器接受連接請求。並獲得一個新的綁定到不同端口地址的套接字。
④ 客戶和服務器通過讀、寫套接字進行通訊。
基於TCP協議的Socket編程
① 創建TCP服務端步驟:
a) 創建一個ServerSocket對象
b) 調用accept()方法接受客戶端請求
c) 從Socket中獲取I/O流
d) 對I/O流進行讀寫操作,完成與客戶端的交互
e) 關閉I/O流和Socket
② 創建TCP客戶端步驟:
a) 創建一個Socket對象
b) 從Socket中獲取I/O流
c) 對I/O流進行讀寫操作,完成與服務端的交互
d) 關閉I/O流和Socket
注:客戶端和服務端進行數據傳輸時,客戶端的輸入流對應服務端的輸出流,客戶端的輸出流對應服務端的輸入流。
示例:創建一個客戶端與服務端通信的例子
包名:com.iotek.tcpsocket
服務端:
1 // 1.創建一個ServerSocket對象 2 ServerSocket serverSocket = new ServerSocket(8888); 3 // 2.調用accept()方法接受客戶端請求 4 Socket socket = serverSocket.accept(); 5 System.out.println(socket.getInetAddress().getHostAddress() + "連接成功"); 6 // 3.獲取socket對象的輸入輸出流 7 BufferedReader br = new BufferedReader(new InputStreamReader( 8 socket.getInputStream())); 9 10 PrintWriter pw = new PrintWriter(socket.getOutputStream(), true); 11 String line = null; 12 // 讀取客戶端傳過來的數據 13 while ((line = br.readLine()) != null) { 14 if (line.equals("over")) { 15 break; 16 } 17 System.out.println(line); 18 pw.println(line.toUpperCase()); 19 } 20 21 pw.close(); 22 br.close(); 23 socket.close(); 24 System.out.println(socket.getInetAddress().getHostAddress() + "斷開連接");
客戶端:
1 Socket socket = new Socket("127.0.0.1", 8888); 2 BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 3 4 PrintWriter pw = new PrintWriter(socket.getOutputStream(), true); 5 BufferedReader reader = new BufferedReader(new InputStreamReader( 6 socket.getInputStream())); 7 while (true) { 8 String line = br.readLine();// 獲取鍵盤所輸入的字符串 9 pw.println(line); 10 if (line.equals("over")) { 11 break; 12 } 13 System.out.println(reader.readLine());// 獲取服務端傳過來的大寫字符串 14 } 15 reader.close(); 16 br.close(); 17 pw.close(); 18 socket.close();
為了更直觀的看見通信過程,將2個java程序復制到E盤根目錄下,用命令行的形式來運行。
打開cmd,編譯java,步驟
① 進入e盤。 e:
② 編譯所有java文件。 javac –d . *.java
③ 打開服務端。 java com.iotek.tcpsocket.TCPServer
④ 再打開一個cmd命令行用於打開客戶端java com.iotek.tcpsocket.TCPClient
連接成功
在客戶端輸入hello回車之後測試成功。
輸入over,斷開連接
基於UDP協議的Socket編程
① 創建發送端
a) 建立DatagramSocket對象。該端點建立,系統會隨機分配一個端口。如果不想隨機配置,可以手動指定。
b) 將數據進行packet包的封裝,必須要指定目的地地址和端口。
c) 通過socket服務的send方法將該包發出。
d) 將socket關閉。
② 創建接收端
a) 建立DatagramSocket對象。要監聽一個端口。
b) 通過socket的receive方法將數據存入數據包中。
c) 通過數據包dp的方法getData()、getAddress()、getPort()等方法獲取包中的指定信息。
d) 將socket關閉。
示例:創建一個發送與接收的例子
發送端:UDPDemo1
1 DatagramSocket socket = new DatagramSocket(); 2 String str = "i love you"; 3 // 把數據進行封裝到數據報包中 4 DatagramPacket packet = new DatagramPacket(str.getBytes(), 5 str.length(), InetAddress.getByName("localhost"), 6666); 6 socket.send(packet);// 發送 7 8 byte[] buff = new byte[100]; 9 DatagramPacket packet2 = new DatagramPacket(buff, 100); 10 socket.receive(packet2); 11 System.out.println(new String(buff, 0, packet2.getLength())); 12 socket.close();
接收端:UDPDemo2
1 // 先接收數據 2 DatagramSocket socket = new DatagramSocket(6666); 3 byte[] buff = new byte[100]; 4 DatagramPacket packet = new DatagramPacket(buff, 100); 5 socket.receive(packet);// 接受傳來的數據包 6 System.out.println(new String(buff, 0, packet.getLength())); 7 8 // 發送數據 9 String str = "me too"; 10 DatagramPacket packet2 = new DatagramPacket(str.getBytes(), 11 str.length(), packet.getAddress(), packet.getPort()); 12 socket.send(packet2); 13 socket.close();
將2個java程序復制到E盤根目錄下,用命令行的形式來運行。
打開cmd,編譯java,步驟:
① 進入e盤。 e:
② 編譯以UDP開頭的文件。 javac –d . UDP*.java
③ 先運行接收端。 java com.iotek.tcpsocket.UDPDemo2
④ 重新打開一個命令行,運行發送端。 java com.iotek.tcpsocket.UDPDemo1