【Java 网络编程】UDP 服务器 客户端 通信 ( DatagramSocket | DatagramPacket | UDP 发送数据包 | UDP 接收数据包 | 端口号分配使用机制 )
文章目錄
- I UDP 信息發送接收原理
- II UDP 發送和接收端口相同
- III UDP 發送信息代碼示例
- IV UDP 接收信息代碼示例
- V UDP 服務器端代碼示例
- VI UDP 客戶端代碼示例
- VII 客戶端服務器端通信
I UDP 信息發送接收原理
1. UDP 既有客戶端的功能 , 也有服務器端的功能 ;
2. UDP 發送和接收 : 計算機 A 向 計算機 B 的 X 端口發送消息 , B 不一定能接收到 , B 能收到并處理該消息的前提是 , B 當前正在監聽 X 端口 ;
3. 發送設備個數 : B 監聽 X 端口 , 并接收數據 , 向 B 發送信息的設備可以是多個 , B 可以接收到任何設備向其 X 端口發送的數據 ;
4. 端口號說明 : UDP 報文頭 64 位 , 其中有發送源端口號 , 和接收的目標端口號 , 這個目標端口號是 X 端口號 , 發送源端口號是隨機的動態端口號 ;
5. 相互通信 : B 收到消息時 , 才知道 A 設備發送消息的端口號 ; 如果 B 收到消息 , 然后馬上向 A 的發送源端口號回送一條消息 , 如果 A 計算機正在監聽這個端口號 , 就可以收到 B 計算機發送的消息 ; 如果 A 沒有監聽 , 那么收不到這個消息 ;
II UDP 發送和接收端口相同
UDP 發送和接收使用的是同一個端口 ;
UDP 發送和接收使用的是同一個端口 ;
UDP 發送和接收使用的是同一個端口 ;
重要的事情說三遍
III UDP 發送信息代碼示例
1. 創建 DatagramSocket 對象 : 發送 UDP 數據包 , 首先要創建 DatagramSocket 對象 , 該對象可用于 UDP 數據包的發送和接收 , 創建時如果需要監聽數據的接收 , 可以指定監聽的端口 , 也可以等待系統自動分配一個端口 , 使用該端口進行數據的發送和接收 ;
2. 創建并設置 DatagramPacket 對象 : 發送的數據包實體是 DatagramPacket 對象 , 將目標設備的 IP 地址 , 端口號 , 發送的 byte[] 數組數據 , 設置到該數據包實體中 , 調用 DatagramSocket 對象的 send 方法 , 將該數據包發送出去 ;
3. 動態端口號自動分配 : 這里注意 , 發送的同時 , 系統自動分配了 一個動態端口號 , 該發送端口號就是接受端口號 , UDP 開始監聽該端口號 , 意味著可以從該端口號接受數據包 , 服務器端就是接收到信息后 , 將反饋數據發送到該動態分配的端口中 ;
//I. 創建 DatagramSocket 對象 , 用于 UDP 數據包的發送和接收//1. UDP 數據包套接字 , 客戶端 ,// 無需指定端口 , 讓系統直接分配一個端口 , 使用該端口發送和接收數據DatagramSocket datagramSocket = new DatagramSocket();//II. 發送 UDP 數據包//2. 客戶端發送給服務器端的端口號String sendMessage = "你好, 服務器 !";//3. 將字符串轉為 byte[] 數組byte[] sendData = sendMessage.getBytes();//4. 創建發送數據包 , 需要傳入的參數 1> 數據 2> 數據長度 3> 接收者的地址 4> 接收者的端口號// 向服務器端發送數據 , 發送的端口是自動分配的DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length,InetAddress.getLocalHost(), 8888);//5. 將數據包發送出去datagramSocket.send(sendPacket);IV UDP 接收信息代碼示例
1. 創建 DatagramSocket 對象 : 接收 UDP 數據包 , 首先要創建 DatagramSocket 對象 , 注意必須設置一個監聽的端口號 , 才能接收數據包 ;
客戶端沒有設置監聽端口號 , 接收到了數據 , 是因為其先發送的數據 , 發送數據的同時 , 系統自動為其分配了一個動態端口號 , UDP 中發送和接收使用的是同一個端口號 , 在分配完該動態端口號之后 , 客戶端就開始監聽該端口號了 ;
2. 創建并設置 DatagramPacket 對象 : 接收的數據包實體是 DatagramPacket 對象 , 需要為其設置一個接收數據的緩沖區 , 接收到數據包后 , 系統會自動將發送信息的設備的 IP 地址 , 端口號 , 發送的 byte[] 數組數據 , 設置到該數據包實體中 , 調用 DatagramSocket 對象的 receive 方法 , 會阻塞等待數據包到來 ;
//I. 創建 DatagramSocket 對象 , 用于 UDP 數據包的發送和接收//1. UDP 數據包接收者 , 監聽 8888 端口// 該 DatagramSocket 既可以接收數據包 , 也可以發送數據包DatagramSocket datagramSocket = new DatagramSocket(8888);//II. 接收 UDP 數據包//2. 接收數據包使用的緩沖區byte[] receiveBuffer = new byte[1024];//3. 接收 UDP 數據包使用的 DatagramPacket 對象DatagramPacket receivePacket = new DatagramPacket(receiveBuffer, receiveBuffer.length);//4. 接收 UDP 數據包datagramSocket.receive(receivePacket);V UDP 服務器端代碼示例
import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.SocketException;public class UDPServer {public static void main(String[] args){try {System.out.println("服務器 開始運行");//I. 創建 DatagramSocket 對象 , 用于 UDP 數據包的發送和接收//1. UDP 數據包接收者 , 監聽 8888 端口// 該 DatagramSocket 既可以接收數據包 , 也可以發送數據包DatagramSocket datagramSocket = new DatagramSocket(8888);//II. 接收 UDP 數據包//2. 接收數據包使用的緩沖區byte[] receiveBuffer = new byte[1024];//3. 接收 UDP 數據包使用的 DatagramPacket 對象DatagramPacket receivePacket = new DatagramPacket(receiveBuffer, receiveBuffer.length);//4. 接收 UDP 數據包datagramSocket.receive(receivePacket);//5. 獲取發送端的 IP 地址String sendIP = receivePacket.getAddress().getHostAddress();//6. 獲取發送端的端口號int sendPort = receivePacket.getPort();//7. 獲取接收到的數據的長度int receiveLen = receivePacket.getLength();//8. 獲取接收到的數據 , 并轉為字符串String receiveData = new String(receivePacket.getData(), 0, receiveLen);//9. 打印接收到的數據包信息System.out.println("服務器 接收到 " + sendIP + " : " + sendPort + " 發送的數據 : " + receiveData);//III. 發送 UDP 數據包//10. 將接收到的數據長度回送給發送者String response = "服務器端 收到客戶端發送的 " + receiveLen + " Byte 數據";//11. 將字符串轉為 byte[] 數組byte[] responseData = response.getBytes();//12. 創建發送數據包 , 需要傳入的參數 1> 數據 2> 數據長度 3> 接收者的地址 4> 接收者的端口號DatagramPacket responsePacket = new DatagramPacket(responseData, responseData.length,receivePacket.getAddress(), receivePacket.getPort());//13. 將數據包發送出去datagramSocket.send(responsePacket);System.out.println("服務器 向客戶端 " + sendIP + " : " + sendPort + " 發送的數據 : " + response);} catch (SocketException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {System.out.println("服務器 運行結束");}}}
VI UDP 客戶端代碼示例
import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.SocketException;public class UDPClient {public static void main(String[] args){try {System.out.println("客戶端 開始運行");//I. 創建 DatagramSocket 對象 , 用于 UDP 數據包的發送和接收//1. UDP 數據包套接字 , 客戶端 ,// 無需指定端口 , 讓系統直接分配一個端口 , 使用該端口發送數據DatagramSocket datagramSocket = new DatagramSocket();//II. 發送 UDP 數據包//2. 客戶端發送給服務器端的端口號String sendMessage = "你好, 服務器 !";//3. 將字符串轉為 byte[] 數組byte[] sendData = sendMessage.getBytes();//4. 創建發送數據包 , 需要傳入的參數 1> 數據 2> 數據長度 3> 接收者的地址 4> 接收者的端口號// 向服務器端發送數據 , 發送的端口是自動分配的DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length,InetAddress.getLocalHost(), 8888);//5. 將數據包發送出去datagramSocket.send(sendPacket);System.out.println("客戶端 向服務器 : " +InetAddress.getLocalHost() + " : " + 8888 + " 發送的數據 : " + sendMessage);//III. 接收 UDP 數據包//6. 接收數據包使用的緩沖區byte[] receiveBuffer = new byte[1024];//7. 接收 UDP 數據包使用的 DatagramPacket 對象DatagramPacket receivePacket = new DatagramPacket(receiveBuffer, receiveBuffer.length);//8. 接收 UDP 數據包datagramSocket.receive(receivePacket);//9. 獲取發送端的 IP 地址String sendIP = receivePacket.getAddress().getHostAddress();//10. 獲取發送端的端口號int sendPort = receivePacket.getPort();//11. 獲取接收到的數據的長度int receiveLen = receivePacket.getLength();//12. 獲取接收到的數據 , 并轉為字符串String receiveData = new String(receivePacket.getData(), 0, receiveLen);//13. 打印接收到的數據包信息System.out.println("客戶端 接收到服務器端反饋信息 : " +sendIP + " : " + sendPort + " 發送的數據 : " + receiveData);} catch (SocketException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {System.out.println("客戶端 運行結束");}}}
VII 客戶端服務器端通信
1. 服務器運行 : 先運行服務器 , 此時服務器開始監聽 8888 端口 ,
2. 客戶端發送信息 : 再運行客戶端 , 客戶端向服務器端的 8888 端口發送數據 , 客戶端的發送端口是隨機的 , 本次是 57660 端口 , 這是個動態分配端口 , UDP 的發送和接收端口是同一個端口 , 此時 UDP 開始監聽該端口 ;
3. 服務器端反饋信息 : 服務器端收到客戶端發送的數據 , 處理后將反饋數據再次發送回去 , 這里發送給客戶端的 57660 端口 , 服務器端的發送端口就是 8888 端口 ;
UDP 發送和接收端口是同一個端口 ;
總結
以上是生活随笔為你收集整理的【Java 网络编程】UDP 服务器 客户端 通信 ( DatagramSocket | DatagramPacket | UDP 发送数据包 | UDP 接收数据包 | 端口号分配使用机制 )的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Java 网络编程】UDP API 简
- 下一篇: 【Java 网络编程】UDP 服务器 与