使用 DatagramPacket 接收 UDP 数据的核心流程是:创建字节数组缓冲区(如1024字节)→ 用 DatagramSocket 绑定本地端口 → 调用 receive() 阻塞等待 → 用 packet.getLength() 截取有效数据并解析。

使用 DatagramPacket 接收 UDP 数据,核心是配合 DatagramSocket 完成“创建接收缓冲区 → 绑定端口 → 阻塞等待数据 → 解析内容”的流程。关键在于缓冲区大小、端口绑定和字节数组处理,稍有疏忽容易卡住或丢包。
准备一个字节数组作为接收缓冲区
UDP 是无连接、不可靠的协议,每次接收的数据长度不确定,所以必须预先分配足够大的字节数组(通常 1024 或 8192 字节),避免截断:
byte[] buffer = new byte[1024]; // 缓冲区,不能为 null
- 数组大小要覆盖可能的最大 UDP 报文(注意:IPv4 下一般不超过 65507 字节,但实际建议 ≤ 8192)
- 不要重复复用未清空的数组——
DatagramPacket只读取前length字节,不会自动清零 - 如果只关心字符串,后续可用
new String(packet.getData(), 0, packet.getLength(), StandardCharsets.UTF_8)
用 DatagramSocket 绑定本地端口并接收
必须先创建 socket 并明确绑定端口(可指定 IP,不指定则监听所有本地地址),再调用 receive() —— 这个方法会阻塞,直到收到一个 UDP 包:
DatagramSocket socket = new DatagramSocket(8080); // 绑定到本机 8080 端口 DatagramPacket packet = new DatagramPacket(buffer, buffer.length); socket.receive(packet); // 阻塞在此,直到收到数据
- 若端口已被占用,构造
DatagramSocket时抛java.net.BindException -
packet.getAddress()和packet.getPort()可获取发送方地址,用于回包 -
packet.getLength()返回实际接收到的字节数(≤ buffer.length),务必用它截取有效内容
常见易错点和健壮性建议
UDP 没有重传和顺序保证,单纯接收一次远远不够;服务端需循环接收,客户端需考虑超时与异常:
立即学习“Java免费学习笔记(深入)”;
- 用
try-catch包裹receive(),捕获IOException(如 socket 关闭、网络中断) - 设置接收超时:
socket.setSoTimeout(5000),避免无限阻塞;超时后抛SocketTimeoutException - 多线程场景下,每个
DatagramSocket应独占一个线程,不要多个线程并发调用receive() - 接收后立即重置
packet的 length(如packet.setLength(buffer.length)),否则下次 receive 可能受限于上次 length
一个最小可运行接收示例
以下代码监听 9999 端口,打印收到的内容和来源地址:
public static void main(String[] args) throws Exception {
DatagramSocket socket = new DatagramSocket(9999);
byte[] buf = new byte[1024];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
System.out.println("UDP 服务器启动,监听 9999 端口...");
while (true) {
socket.receive(packet);
String msg = new String(packet.getData(), 0, packet.getLength(), StandardCharsets.UTF_8);
String addr = packet.getAddress().getHostAddress();
int port = packet.getPort();
System.out.printf("[%s:%d] %s%n", addr, port, msg);
// 重置 packet 长度,为下次接收准备
packet.setLength(buf.length);
}
}
运行后,可用 echo "hello" | nc -u 127.0.0.1 9999 或任意 UDP 工具发包测试。



















