首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 網路程式設計基礎(下):DatagramSocket 與 UDP 無連線通訊

     編輯:Java 相關知識

為什麼需要 Datagram Socket?

Stream Socket (TCP):連線導向、可靠、有序、流量控制,但建立連線需三次交握、維護狀態、開銷大。
Datagram Socket (UDP):無連線、不可靠、無序、無流控,但延遲低、開銷小、支援一對多 (廣播/多點傳送)。

UDP 封裝結構

+------------------+
|   IP Header      |  (來源/目的 IP)
+------------------+
|   UDP Header     |  (來源/目的 Port, Length, Checksum)
+------------------+
|   Data (≤ 64KB)  |  應用層資料
+------------------+

UDP 標頭僅 8 bytes,極度輕量。Checksum 提供基本錯誤檢測,失敗則靜默丟棄,不重傳、不通知發送端——像寄明信片,投遞不保證。

核心三大類別

  1. DatagramPacket:資料包容器,封裝資料位元組陣列 + 目的地址/埠 (發送) 或 來源地址/埠 (接收)。
  2. DatagramSocket:本地端點,綁定本地埠發送/接收資料包。
  3. MulticastSocket:DatagramSocket 子類,支援多點傳送群組加入/離開。

DatagramPacket 完整用法

建構子選擇指南

建構子適用場景
DatagramPacket(buf, length)接收端:預先分配緩衝區,稍後取得發送者資訊
DatagramPacket(buf, length, addr, port)發送端:一次性指定資料、目的地
DatagramPacket(buf, offset, length)進階:指定緩衝區偏移量 (零拷貝優化)
DatagramPacket(buf, offset, length, addr, port)發送端 + 偏移量

動態修改資料包內容 (發送迴圈優化)

// 建立一次,重複使用
byte[] dummy = new byte[0];
DatagramPacket packet = new DatagramPacket(dummy, 0, groupAddr, port);

for (String msg : messages) {
    byte[] data = msg.getBytes(StandardCharsets.UTF_8); // 指定編碼
    packet.setData(data);
    packet.setLength(data.length);
    socket.send(packet);
}

接收端標準模式

byte[] buffer = new byte[65507]; // UDP 最大承載 (65535 - 8 UDP - 20 IP)
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);

while (running) {
    socket.receive(packet); // 阻塞
    // 處理資料
    String received = new String(packet.getData(), 0, packet.getLength(), StandardCharsets.UTF_8);
    InetAddress senderAddr = packet.getAddress();
    int senderPort = packet.getPort();
    // 回覆可直接用 packet.getAddress()/getPort() 建新包
}

DatagramSocket 關鍵配置

  • setSoTimeout(int ms):設定 receive() 阻塞超時,避免永久阻塞,超時拋 SocketTimeoutException。
  • setBroadcast(true):允許發送廣播封包 (255.255.255.255 或子網廣播位址)。
  • setReuseAddress(true):允許多個 Socket 綁定同一埠 (SO_REUSEADDR),集群部署常用。
  • setTrafficClass(int tc):設定 QoS (DiffServ/ToS),如 IPTOS_LOWDELAY。

UDP 應用場景與避坑指南

適用場景不適用場景
即時語音/視訊 (丟包可容忍,延遲敏感)檔案傳輸、金融交易 (需可靠性)
DNS 查詢、NTP 時間同步 (請求小、單次交互)大數據傳輸 (需分片重組,效率極低)
遊戲狀態同步 (最新狀態覆蓋舊狀態)需要嚴格順序/事務性的操作
服務發現、心跳檢測 (廣播/多點傳送)防火牆嚴格環境 (UDP 常被封鎖)

進階:應用層實現可靠 UDP (RUDP 思想)

若必須用 UDP 又需可靠性,應用層需實現:

  1. 序號:每個封包遞增 ID,接收端去重/排序。
  2. ACK/NACK:接收端確認收到,發送端超時重傳。
  3. 滑動視窗:流控與擁塞控制。
  4. FEC (前向糾錯):冗餘編碼 (Reed-Solomon/XOR),接收端自行修復少量丟包。

不要重複造輪子!成熟專案請直接使用 Netty (UDP 支援)、QUIC/HTTP/3、gRPC over HTTP/2、RTP/RTCP (媒體流) 等標準協議框架。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved