UDP 通訊需明確目的位址,InetAddress 提供靜態工廠方法:
// 由主機名稱解析
InetAddress addr = InetAddress.getByName("www.example.com");
// 取得所有 IP(多宿主機)
InetAddress[] addrs = InetAddress.getAllByName("www.example.com");
// 取得本機位址
InetAddress local = InetAddress.getLocalHost();
所有方法均可拋出 UnknownHostException,需妥善處理 DNS 失敗情況。
String msg = "Hello UDP";
byte[] buf = msg.getBytes(StandardCharsets.UTF_8);
InetAddress dst = InetAddress.getByName("192.168.1.100");
int port = 5000;
DatagramPacket packet = new DatagramPacket(buf, buf.length, dst, port);
DatagramSocket socket = new DatagramSocket();
socket.send(packet);
關鍵在於從接收封包提取發送者資訊:
DatagramPacket recv = new DatagramPacket(new byte[512], 512);
socket.receive(recv);
// 取得發送者位址與埠
InetAddress clientAddr = recv.getAddress();
int clientPort = recv.getPort();
// 原封不動回應
DatagramPacket reply = new DatagramPacket(
recv.getData(), recv.getLength(), clientAddr, clientPort);
socket.send(reply);
public class EchoDatagramServer {
public static void main(String[] args) {
try (DatagramSocket socket = new DatagramSocket(4545)) {
byte[] buf = new byte[512];
while (true) {
DatagramPacket recv = new DatagramPacket(buf, buf.length);
socket.receive(recv);
DatagramPacket reply = new DatagramPacket(
recv.getData(), recv.getLength(),
recv.getAddress(), recv.getPort());
socket.send(reply);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
無需連線建立、無狀態維護、單一 Socket 處理所有客戶端,天然適合無狀態高併發場景(DNS、NTP、Syslog)。