全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-11 5 分钟 ✍️ juanwangdev

Java UDP协议

UDP(User Datagram Protocol)是无连接、不可靠的传输层协议,适用于实时通信场景。

UDP特点

特点说明
无连接发送前不需建立连接
不可靠不保证送达、不保证顺序
无流量控制可能丢包
速度快无握手开销
消息边界每次发送一个完整消息

UDP vs TCP

特性UDPTCP
连接三次握手
可靠性不保证保证
顺序不保证保证
开销
数据边界流式
适用实时通信精确传输

核心类

作用
DatagramSocketUDP套接字,发送/接收
DatagramPacketUDP数据包

发送数据

Java
public class UdpSender {
    public static void main(String[] args) throws IOException {
        // 创建UDP套接字(不需要指定目标)
        DatagramSocket socket = new DatagramSocket();

        // 准备数据
        String message = "Hello UDP";
        byte[] data = message.getBytes();

        // 创建数据包,指定目标地址和端口
        InetAddress address = InetAddress.getByName("localhost");
        int port = 8888;
        DatagramPacket packet = new DatagramPacket(data, data.length, address, port);

        // 发送
        socket.send(packet);
        System.out.println("已发送: " + message);

        socket.close();
    }
}

接收数据

Java
public class UdpReceiver {
    public static void main(String[] args) throws IOException {
        // 创建UDP套接字,绑定端口
        DatagramSocket socket = new DatagramSocket(8888);
        System.out.println("UDP接收端启动,监听8888端口");

        // 准备接收缓冲区
        byte[] buffer = new byte[1024];
        DatagramPacket packet = new DatagramPacket(buffer, buffer.length);

        // 接收数据(阻塞)
        socket.receive(packet);

        // 解析数据
        String message = new String(packet.getData(), 0, packet.getLength());
        InetAddress senderAddress = packet.getAddress();
        int senderPort = packet.getPort();

        System.out.println("收到: " + message);
        System.out.println("来源: " + senderAddress + ":" + senderPort);

        socket.close();
    }
}

双向通信

Java
public class UdpChat {
    public static void main(String[] args) throws IOException {
        DatagramSocket socket = new DatagramSocket(8888);
        byte[] buffer = new byte[1024];

        // 接收线程
        new Thread(() -> {
            while (true) {
                try {
                    DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
                    socket.receive(packet);
                    String msg = new String(packet.getData(), 0, packet.getLength());
                    System.out.println("收到: " + msg);
                } catch (IOException e) {
                    break;
                }
            }
        }).start();

        // 发送线程
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        InetAddress targetAddress = InetAddress.getByName("localhost");
        int targetPort = 9999;

        while (true) {
            String line = reader.readLine();
            if ("quit".equals(line)) break;

            byte[] data = line.getBytes();
            DatagramPacket packet = new DatagramPacket(data, data.length, targetAddress, targetPort);
            socket.send(packet);
        }

        socket.close();
    }
}

DatagramPacket常用方法

Java
// 创建发送包
DatagramPacket packet = new DatagramPacket(data, data.length, address, port);

// 创建接收包
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);

// 获取数据
byte[] data = packet.getData();
int length = packet.getLength();      // 实际数据长度
int offset = packet.getOffset();      // 数据偏移

// 获取来源信息
InetAddress address = packet.getAddress();
int port = packet.getPort();

// 设置目标
packet.setAddress(address);
packet.setPort(port);
packet.setData(data);
packet.setLength(length);

DatagramSocket常用方法

Java
DatagramSocket socket = new DatagramSocket(8888);

// 基本信息
int localPort = socket.getLocalPort();
InetAddress localAddress = socket.getLocalAddress();

// 超时设置
socket.setSoTimeout(3000);  // 读超时3秒

// 缓冲区大小
socket.setSendBufferSize(64 * 1024);
socket.setReceiveBufferSize(64 * 1024);

// 广播支持
socket.setBroadcast(true);

// 状态
socket.isConnected();  // 是否已关联目标地址
socket.isClosed();     // 是否已关闭

// 绑定特定地址
socket.bind(new InetSocketAddress("192.168.1.1", 8888));

// 关闭
socket.close();

广播发送

Java
// 广播地址:255.255.255.255 或 子网广播地址
DatagramSocket socket = new DatagramSocket();
socket.setBroadcast(true);

String message = "Broadcast Message";
byte[] data = message.getBytes();

// 广播地址
InetAddress broadcastAddress = InetAddress.getByName("255.255.255.255");
DatagramPacket packet = new DatagramPacket(data, data.length, broadcastAddress, 8888);

socket.send(packet);
socket.close();

适用场景

场景说明
实时音视频允许丢包,追求速度
DNS查询单次请求响应,无需连接
游戏同步实时状态更新
日志收集允许偶尔丢失
心跳检测高频率小包

注意事项

UDP数据包大小有限制,超过MTU会被分片或丢弃

receive() 是阻塞方法,可设置超时

UDP不保证送达,应用层需自行实现重传(如DNS)

广播需要 setBroadcast(true)

DatagramPacket.getData() 返回整个缓冲区,需用 getLength() 获取实际长度

要点总结

  1. UDP无连接、不可靠、速度快
  2. 使用DatagramSocket发送/接收,DatagramPacket封装数据
  3. 发送需指定目标地址和端口,接收需绑定本地端口
  4. 适用于实时通信、DNS、游戏等场景
  5. 数据包有边界,每次发送/接收完整消息

📝 发现内容有误?点击此处直接编辑

← 上一篇 Java Socket编程
下一篇 → Java WebSocket
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库