UDP(User Datagram Protocol,使用者資料報協議)位於 OSI 第 4 層傳輸層,IP 協議之上。特點:無連線、不可靠、無序、無流量控制。發送後不保證送達、不重組、不排序。優點:開銷小、速度快。適用場景:音視訊串流、即時通訊(如 ICQ/QQ)、允許少量丟包的資料傳輸。
InetAddress:封裝 IP 位址,靜態工廠方法 getLocalHost()、getByName(host)、getAllByName(host)。DatagramSocket:收發 UDP 封包的端點。
DatagramSocket()(客戶端,臨時埠)、DatagramSocket(port)(伺服端固定埠)、DatagramSocket(port, InetAddress)(多網卡綁定特定 IP)。receive(p)(阻塞接收)、send(p)(發送)、setSoTimeout(ms)(設定超時)、close()(釋放資源)。DatagramPacket:封裝資料緩衝區、目標位址/埠。
(buf, length, addr, port)、(buf, offset, length, addr, port);接收用 (buf, length)、(buf, offset, length)。getData() 取得位元組陣列。TCP/IP 規定 UDP 封包最大 65,507 位元組。實務上多數主機支援 548 位元組,現代平台通常支援 8,192 位元組。超過 MTU 會分片,增加丟包風險,建議應用層控制在 1,400 位元組以內。
public class UdpServer {
public static void main(String[] args) throws Exception {
byte[] buf = new byte[1024];
DatagramSocket socket = new DatagramSocket(12345);
DatagramPacket packet = new DatagramPacket(buf, buf.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("From %s:%d -> %s%n", packet.getAddress(), packet.getPort(), msg);
}
}
}
public class UdpClient {
public static void main(String[] args) throws Exception {
InetAddress target = InetAddress.getByName("localhost");
DatagramSocket socket = new DatagramSocket(); // 任意埠
String msg = "Hello, UDP!";
byte[] buf = msg.getBytes("UTF-8");
DatagramPacket packet = new DatagramPacket(buf, buf.length, target, 12345);
socket.send(packet);
System.out.println("Sent: " + msg);
socket.close();
}
}
MulticastSocket 加入群組 joinGroup()。DatagramChannel + Selector 實作高併發。setSoTimeout 導致 receive() 永久阻塞。SocketException(埠被佔用)。