Java案例怎么实现UDP通信?

wen java案例 11

本文目录导读:

Java案例怎么实现UDP通信?

  1. 核心类说明
  2. 完整实现案例
  3. 简单单次通信版本
  4. 多线程版本(支持并发)
  5. 运行步骤
  6. 关键点说明
  7. 常见问题

在Java中实现UDP通信主要使用java.net.DatagramSocketjava.net.DatagramPacket这两个类,UDP是无连接的,发送方和接收方无需建立连接即可通信。

核心类说明

  • DatagramSocket:用于发送和接收UDP数据包的套接字
  • DatagramPacket:表示数据包,包含数据、地址和端口信息

完整实现案例

UDP客户端(发送方)

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class UDPClient {
    public static void main(String[] args) {
        DatagramSocket socket = null;
        try {
            // 1. 创建DatagramSocket(无需指定端口,系统自动分配)
            socket = new DatagramSocket();
            // 2. 准备要发送的数据
            String message = "你好,UDP服务器!";
            byte[] sendData = message.getBytes("UTF-8");
            // 3. 指定服务器地址和端口
            InetAddress serverAddress = InetAddress.getByName("localhost");
            int serverPort = 8888;
            // 4. 创建数据包(数据、长度、地址、端口)
            DatagramPacket packet = new DatagramPacket(
                sendData, 
                sendData.length, 
                serverAddress, 
                serverPort
            );
            // 5. 发送数据包
            socket.send(packet);
            System.out.println("已发送消息: " + message);
            // 6. 接收服务器响应(可选)
            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 {
            // 7. 关闭连接
            if (socket != null && !socket.isClosed()) {
                socket.close();
            }
        }
    }
}

UDP服务器(接收方)

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class UDPServer {
    public static void main(String[] args) {
        DatagramSocket socket = null;
        try {
            // 1. 创建DatagramSocket并绑定到指定端口
            socket = new DatagramSocket(8888);
            System.out.println("UDP服务器已启动,端口: 8888");
            byte[] buffer = new byte[1024];
            // 2. 循环接收数据(使服务器持续运行)
            while (true) {
                // 3. 创建接收数据包
                DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
                // 4. 接收客户端数据(阻塞方法)
                socket.receive(packet);
                // 5. 提取客户端信息
                InetAddress clientAddress = packet.getAddress();
                int clientPort = packet.getPort();
                // 6. 解析接收到的数据
                String receivedMessage = new String(
                    packet.getData(), 
                    0, 
                    packet.getLength(), 
                    "UTF-8"
                );
                System.out.println("收到来自 " + clientAddress.getHostAddress() + 
                                 ":" + clientPort + " 的消息: " + receivedMessage);
                // 7. 发送响应给客户端
                String response = "已收到消息: " + receivedMessage;
                byte[] responseData = response.getBytes("UTF-8");
                DatagramPacket responsePacket = new DatagramPacket(
                    responseData, 
                    responseData.length, 
                    clientAddress, 
                    clientPort
                );
                socket.send(responsePacket);
                System.out.println("已发送响应");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (socket != null && !socket.isClosed()) {
                socket.close();
            }
        }
    }
}

简单单次通信版本

如果只需要发送一次消息就结束的场景:

精简客户端

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class SimpleUDPClient {
    public static void main(String[] args) throws Exception {
        try (DatagramSocket socket = new DatagramSocket()) {
            String message = "Hello UDP";
            DatagramPacket packet = new DatagramPacket(
                message.getBytes(),
                message.length(),
                InetAddress.getLocalHost(),
                9999
            );
            socket.send(packet);
        }
    }
}

精简服务器

import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class SimpleUDPServer {
    public static void main(String[] args) throws Exception {
        try (DatagramSocket socket = new DatagramSocket(9999)) {
            byte[] buffer = new byte[1024];
            DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
            socket.receive(packet);
            System.out.println(new String(packet.getData(), 0, packet.getLength()));
        }
    }
}

多线程版本(支持并发)

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class MultiThreadUDPServer {
    public static void main(String[] args) throws Exception {
        try (DatagramSocket serverSocket = new DatagramSocket(7777)) {
            System.out.println("多线程UDP服务器启动,端口: 7777");
            while (true) {
                byte[] buffer = new byte[1024];
                DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
                serverSocket.receive(packet);
                // 为每个客户端创建新线程处理
                new Thread(new ClientHandler(serverSocket, packet)).start();
            }
        }
    }
}
class ClientHandler implements Runnable {
    private DatagramSocket socket;
    private DatagramPacket packet;
    public ClientHandler(DatagramSocket socket, DatagramPacket packet) {
        this.socket = socket;
        this.packet = packet;
    }
    @Override
    public void run() {
        try {
            String message = new String(packet.getData(), 0, packet.getLength(), "UTF-8");
            InetAddress address = packet.getAddress();
            int port = packet.getPort();
            System.out.println(Thread.currentThread().getName() + 
                             " 收到: " + message);
            // 发送响应
            String response = "已处理: " + message;
            byte[] sendData = response.getBytes("UTF-8");
            DatagramPacket sendPacket = new DatagramPacket(
                sendData, sendData.length, address, port
            );
            socket.send(sendPacket);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

运行步骤

  1. 先启动服务器:运行UDPServer
  2. 再启动客户端:运行UDPClient
  3. 观察控制台输出信息

关键点说明

特性 说明
无连接 发送前不需要建立连接
不可靠 数据可能丢失、重复或乱序
数据包大小 最大64KB(实际建议< 1472字节避免分片)
速度快 比TCP少握手和确认过程
支持广播 可以发送到255.255.255.255或子网广播地址

常见问题

  1. 端口占用:如果出现Address already in use,更换端口或等待端口释放
  2. 数据编码:建议统一使用UTF-8编码,避免乱码
  3. 接收缓冲区receive方法是阻塞的,直到收到数据才返回
  4. 数据边界:UDP保持消息边界,一次send对应一次receive

这个实现可以满足大多数UDP通信场景,如实时游戏、视频流、DNS查询等。

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