DatagramSocket发送UDP报文

wen java案例 2

本文目录导读:

DatagramSocket发送UDP报文

  1. 基本步骤
  2. 完整示例代码
  3. 重要注意事项
  4. 简化版本(一行发送)

在Java中,使用DatagramSocket发送UDP报文是一个常见的网络编程任务,下面我会详细解释如何实现,包括基本步骤、完整示例代码以及一些重要的注意事项。

基本步骤

  1. 创建DatagramSocket对象(客户端可以指定端口或使用自动分配的端口)
  2. 准备要发送的数据(字符串、二进制等)
  3. 创建DatagramPacket数据包,包含数据、目标地址和端口
  4. 调用send()方法发送数据包
  5. 关闭DatagramSocket(可选)

完整示例代码

发送端(客户端)

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class UDPSender {
    public static void main(String[] args) {
        DatagramSocket socket = null;
        try {
            // 1. 创建DatagramSocket,不指定端口会自动分配一个可用端口
            socket = new DatagramSocket();
            // 2. 准备要发送的数据
            String message = "Hello, UDP Server!";
            byte[] sendData = message.getBytes("UTF-8"); // 指定字符编码,避免乱码
            // 3. 指定目标地址和端口
            InetAddress serverAddress = InetAddress.getByName("localhost"); // 或 IP 地址
            int serverPort = 8888;
            // 4. 创建DatagramPacket
            DatagramPacket packet = new DatagramPacket(
                sendData,          // 数据字节数组
                sendData.length,   // 数据长度
                serverAddress,     // 目标地址
                serverPort         // 目标端口
            );
            // 5. 发送数据包
            socket.send(packet);
            System.out.println("UDP报文发送成功!");
            // 可选:接收响应
            // 准备接收缓冲区
            byte[] receiveBuffer = new byte[1024];
            DatagramPacket receivePacket = new DatagramPacket(receiveBuffer, receiveBuffer.length);
            socket.receive(receivePacket);
            String response = new String(receivePacket.getData(), 0, receivePacket.getLength(), "UTF-8");
            System.out.println("收到服务器响应: " + response);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 6. 关闭socket
            if (socket != null && !socket.isClosed()) {
                socket.close();
            }
        }
    }
}

接收端(服务器)

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class UDPReceiver {
    public static void main(String[] args) {
        DatagramSocket socket = null;
        try {
            // 1. 创建DatagramSocket并绑定到特定端口
            socket = new DatagramSocket(8888);
            System.out.println("UDP服务器启动,监听端口: 8888");
            // 2. 准备接收数据的缓冲区
            byte[] receiveBuffer = new byte[1024];
            // 3. 创建接收数据包
            DatagramPacket receivePacket = new DatagramPacket(receiveBuffer, receiveBuffer.length);
            // 4. 接收数据(阻塞方法)
            socket.receive(receivePacket);
            // 5. 解析接收到的数据
            String message = new String(receivePacket.getData(), 0, receivePacket.getLength(), "UTF-8");
            InetAddress senderAddress = receivePacket.getAddress();
            int senderPort = receivePacket.getPort();
            System.out.println("收到来自 " + senderAddress.getHostAddress() + ":" + senderPort + " 的消息:");
            System.out.println("消息内容: " + message);
            // 6. 发送响应(可选)
            String response = "消息已收到!";
            byte[] responseData = response.getBytes("UTF-8");
            DatagramPacket responsePacket = new DatagramPacket(
                responseData, 
                responseData.length, 
                senderAddress, 
                senderPort
            );
            socket.send(responsePacket);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (socket != null && !socket.isClosed()) {
                socket.close();
            }
        }
    }
}

重要注意事项

字符编码

  • 始终指定字符编码(如UTF-8),避免平台默认编码差异导致乱码

UDP的无连接特性

  • UDP不保证数据包可靠到达
  • 不保证数据包顺序
  • 数据包可能丢失、重复或乱序

数据包大小限制

  • UDP数据包最大理论大小为65535字节(64KB)
  • 实际建议不超过1472字节(避免IP分片)

超时设置

// 设置接收超时(毫秒)
socket.setSoTimeout(5000); // 5秒超时

广播发送

// 启用广播
socket.setBroadcast(true);
// 发送到广播地址
InetAddress broadcastAddress = InetAddress.getByName("255.255.255.255");
// 或子网广播地址,如 192.168.1.255

发送自定义对象示例

// 序列化对象为字节数组发送
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(yourObject);
byte[] data = baos.toByteArray();
// 发送
DatagramPacket packet = new DatagramPacket(data, data.length, address, port);
socket.send(packet);

简化版本(一行发送)

// 使用try-with-resources自动关闭
try (DatagramSocket socket = new DatagramSocket()) {
    byte[] data = "Hello".getBytes("UTF-8");
    socket.send(new DatagramPacket(data, data.length, 
        InetAddress.getByName("localhost"), 8888));
}

这个示例展示了UDP发送的基本模式,UDP适用于实时性要求高、可以容忍少量数据丢失的场景,如视频流、游戏、DNS查询等。

抱歉,评论功能暂时关闭!