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

Java UDP 協議編程完全指南:DatagramSocket 與 DatagramPacket 實戰

     編輯:Java 程式設計入門

UDP 協議特性速覽

  • 無連接、不可靠、無序、無流控——「發後即忘」。
  • 頭部開銷極小(8 字節),延遲低,適合實時音視頻、遊戲狀態同步、日誌傳輸、廣播發現。
  • 單個數據報最大 65,507 字節(IPv4),實際建議 ≤ 1,400 字節避免分片。

核心類速查

類核心作用關鍵構造器/方法
InetAddressIP 地址封裝getByName(host), getLocalHost(), getAllByName(host)
DatagramSocket發送/接收端口new DatagramSocket(), new DatagramSocket(port), new DatagramSocket(port, bindAddr)
receive(p), send(p), setSoTimeout(ms), close()
DatagramPacket數據報封裝new DatagramPacket(buf, len, addr, port) 發送
new DatagramPacket(buf, len) 接收
getData(), getLength(), getAddress(), getPort()

服務端:綁定端口循環接收

public class UdpServer {
    public static void main(String[] args) throws IOException {
        try (DatagramSocket socket = new DatagramSocket(12345)) {
            byte[] buffer = new byte[1024];
            DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
            System.out.println("UDP Server listening on 12345...");
            while (true) {
                socket.receive(packet); // 阻塞
                String msg = new String(packet.getData(), 0, packet.getLength(), "UTF-8");
                System.out.printf("從 %s:%d 收到:%s%n",
                        packet.getAddress(), packet.getPort(), msg);
                // 可選:原路回複
                // socket.send(packet);
            }
        }
    }
}

客戶端:指定目標發送

public class UdpClient {
    public static void main(String[] args) throws IOException {
        InetAddress target = InetAddress.getByName("localhost");
        try (DatagramSocket socket = new DatagramSocket()) { // 隨機端口
            String msg = "Hello UDP!";
            byte[] data = msg.getBytes("UTF-8");
            DatagramPacket packet = new DatagramPacket(data, data.length, target, 12345);
            socket.send(packet);
            System.out.println("已發送:" + msg);
        }
    }
}

進階主題

1. 超時控制

socket.setSoTimeout(3000); // 3 秒無數據拋 SocketTimeoutException
try {
    socket.receive(packet);
} catch (SocketTimeoutException e) {
    // 處理超時邏輯
}

2. 多播/廣播

// 組播
InetAddress group = InetAddress.getByName("239.255.0.1");
MulticastSocket ms = new MulticastSocket(5000);
ms.joinGroup(group);
// 接收/發送同 DatagramSocket
ms.leaveGroup(group);

// 廣播(需網卡支援)
DatagramSocket bc = new DatagramSocket();
bc.setBroadcast(true);
bc.send(new DatagramPacket(data, data.length, InetAddress.getByName("255.255.255.255"), 9999));

3. 可靠性補償(應用層實現)

  • 序號 + ACK + 重傳(類 TCP 滑動窗口簡化版)。
  • FEC 前向糾錯碼(視頻流常用)。
  • NACK 僅重傳丟包(遊戲狀態同步)。

避坑清單

  1. 接收緩衝區過小導致數據截斷:new byte[65507] 或根據 MTU 設置。
  2. 忘記 packet.setLength(buf.length) 重用包時長度不重置。
  3. 多線程共享同一 DatagramSocket 發送安全,接收需同步或單線程輪詢。
  4. 防火牆攔截 UDP,部署時驗證端口通達性。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved