JAVA异步的UDP 通讯-服务端

1. 使用NIO实现非阻塞UDP通信

通过DatagramChannelSelector,可以实现非阻塞的UDP通信,从而高效地处理多个客户端的请求。

示例代码:
java 复制代码
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;

public class AsyncUDPServer {
    public static void main(String[] args) throws IOException {
        DatagramChannel channel = DatagramChannel.open();
        channel.configureBlocking(false);
        channel.bind(new InetSocketAddress(9898));

        Selector selector = Selector.open();
        channel.register(selector, SelectionKey.OP_READ);

        while (selector.select() > 0) {
            for (SelectionKey key : selector.selectedKeys()) {
                if (key.isReadable()) {
                    ByteBuffer buffer = ByteBuffer.allocate(1024);
                    channel.receive(buffer);
                    buffer.flip();
                    String message = new String(buffer.array(), 0, buffer.limit());
                    System.out.println("Received: " + message);

                    // 可以在此处处理消息并发送响应
                    String response = "Echo: " + message;
                    buffer.clear();
                    buffer.put(response.getBytes());
                    buffer.flip();
                    channel.send(buffer, key.channel().socket().getRemoteSocketAddress());
                }
                selector.selectedKeys().remove(key);
            }
        }
    }
}

2. 设置超时和缓冲区大小

为了优化性能,可以设置接收超时时间以及调整接收和发送缓冲区的大小。

示例代码:
java 复制代码
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

public class OptimizedUDPServer {
    public static void main(String[] args) throws Exception {
        DatagramSocket socket = new DatagramSocket(9898);
        socket.setSoTimeout(5000); // 设置接收超时时间为5000毫秒
        socket.setReceiveBufferSize(8192); // 设置接收缓冲区大小
        socket.setSendBufferSize(8192); // 设置发送缓冲区大小

        byte[] receiveBuffer = new byte[1024];
        DatagramPacket receivePacket = new DatagramPacket(receiveBuffer, receiveBuffer.length);

        while (true) {
            try {
                socket.receive(receivePacket);
                String message = new String(receivePacket.getData(), 0, receivePacket.getLength());
                System.out.println("Received: " + message);

                // 发送响应
                String response = "Echo: " + message;
                DatagramPacket sendPacket = new DatagramPacket(response.getBytes(), response.getBytes().length,
                        receivePacket.getAddress(), receivePacket.getPort());
                socket.send(sendPacket);
            } catch (Exception e) {
                System.out.println("Error: " + e.getMessage());
            }
        }
    }
}

3. 使用线程池处理请求

通过线程池可以高效地处理多个客户端的请求,避免阻塞主线程。

示例代码:
java 复制代码
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadedUDPServer {
    private static final ExecutorService executor = Executors.newFixedThreadPool(10);

    public static void main(String[] args) throws Exception {
        DatagramSocket socket = new DatagramSocket(9898);

        while (true) {
            byte[] receiveBuffer = new byte[1024];
            DatagramPacket receivePacket = new DatagramPacket(receiveBuffer, receiveBuffer.length);
            socket.receive(receivePacket);

            executor.submit(() -> {
                try {
                    String message = new String(receivePacket.getData(), 0, receivePacket.getLength());
                    System.out.println("Received: " + message);

                    // 发送响应
                    String response = "Echo: " + message;
                    DatagramPacket sendPacket = new DatagramPacket(response.getBytes(), response.getBytes().length,
                            receivePacket.getAddress(), receivePacket.getPort());
                    socket.send(sendPacket);
                } catch (Exception e) {
                    System.out.println("Error: " + e.getMessage());
                }
            });
        }
    }
}

4. 异步处理和超时机制

在异步处理中,可以设置超时机制,以便在长时间未收到响应时进行处理。

示例代码:
java 复制代码
import java.net.DatagramSocket;
import java.net.DatagramPacket;
import java.util.concurrent.*;

public class AsyncUDPServerWithTimeout {
    public static void main(String[] args) throws Exception {
        DatagramSocket socket = new DatagramSocket(9898);
        ExecutorService executor = Executors.newSingleThreadExecutor();

        while (true) {
            byte[] receiveBuffer = new byte[1024];
            DatagramPacket receivePacket = new DatagramPacket(receiveBuffer, receiveBuffer.length);

            Future<String> future = executor.submit(() -> {
                socket.receive(receivePacket);
                return new String(receivePacket.getData(), 0, receivePacket.getLength());
            });

            try {
                String message = future.get(5, TimeUnit.SECONDS); // 设置超时时间为5秒
                System.out.println("Received: " + message);

                // 发送响应
                String response = "Echo: " + message;
                DatagramPacket sendPacket = new DatagramPacket(response.getBytes(), response.getBytes().length,
                        receivePacket.getAddress(), receivePacket.getPort());
                socket.send(sendPacket);
            } catch (TimeoutException e) {
                System.out.println("Timeout occurred. No data received within 5 seconds.");
            }
        }
    }
}
相关推荐
李少兄3 分钟前
解决 MySQL Lock wait timeout exceeded 报错
java
va学弟4 分钟前
Java 语言特性:泛型(Generics)
java·泛型
Data_Journal23 分钟前
使用 AutoScraper 进行网页抓取:分步教程
大数据·开发语言·数据库·python·scrapy
yume_sibai40 分钟前
12-Rust 性能优化指南(性能分析 + 内存优化 + SIMD + 并发优化 + 编译器优化 + 基准测试)
开发语言·性能优化·rust
SL_staff1 小时前
插单风险的数据闭环治理:JVS-BI 在制造业实时预警中的技术实践
java·数据分析·数据可视化
萧瑟余晖1 小时前
Hibernate 核心原理与架构详解
开发语言·架构·hibernate
爱喝水的鱼丶1 小时前
SAP-ABAP:SAP MM 模块物料主数据批量导入与增强开发:字段扩展、校验逻辑与批量导入工具开发
开发语言·性能优化·sap·abap·增强·经验交流·mm
geovindu1 小时前
rust:Builder Pattern
开发语言·设计模式·rust·建造者模式
白远山1 小时前
健身场馆无人自动化解决方案:从架构到落地实践
java·开发语言·数据库·数据挖掘·需求分析
user_admin_god1 小时前
第 01 篇:OpenAI 兼容 API 初探 —— 用 curl 跑通第一次对话
java·人工智能·spring boot·语言模型·devops