JAVA异步的UDP 通讯-服务端

server/2025/2/9 8:46:49/

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.");}}}
}


http://www.ppmy.cn/server/166175.html

相关文章

C语言的灵魂——指针(3)

前言&#xff1a;上期我们介绍了const修饰指针&#xff0c;saaert断言都是针对指针本身的&#xff0c;文章后面我们用指针与数组建立了联系&#xff0c;这种联系或者是关系就是这篇文章所要介绍的。上一篇文章的传送门&#xff1a;指针2 指针3 一&#xff0c;数组名的含义及理解…

苹果公司宣布正式开源 Xcode 引擎 Swift Build145

2025 年 2 月 1 日&#xff0c;苹果公司宣布正式开源 Xcode 引擎 Swift Build145。 Swift 是苹果公司于 2014 年推出的一种开源编程语言&#xff0c;用于开发 iOS、iPadOS、macOS、watchOS 和 tvOS 等平台的应用程序。 发展历程 诞生&#xff1a;2014 年&#xff0c;苹果在全球…

深度学习 Pytorch 逻辑回归建模实验

接下来进行逻辑回归的建模实验&#xff0c;首先需要导入相关库和自定义的模块。 # 随机模块 import random# 绘图模块 import matplotlib as mpl import matplotlib.pyplot as plt# numpy import numpy as np# pytorch import torch from torch import nn,optim import torch.…

Qwen2-VL多模态大模型

Qwen2-VL多模态大模型 Qwen2-VL 是一个多模态大模型&#xff0c;支持视觉和语言的理解与生成任务。它结合了视觉&#xff08;Vision&#xff09;和语言&#xff08;Language&#xff09;的能力&#xff0c;能够处理图像和文本的联合输入&#xff0c;并生成高质量的文本输出。以…

c#中Thread.Join()方法的经典示例

在 C# 中&#xff0c;Thread.Join 是一个非常有用的方法&#xff0c;它可以让主线程&#xff08;调用线程&#xff09;等待子线程&#xff08;被调用线程&#xff09;执行完毕后再继续执行。 1、经典示例1 using System; using System.Threading;public class Example {stati…

第四十三章:工作变迁与生活新篇:从上海到杭州湾

在经历了那次令人难忘的沪绍骑行之旅后&#xff0c;小冷本以为生活和工作会沿着既定的轨道平稳前行。然而&#xff0c;命运似乎总喜欢给人带来意想不到的转折。随着公司业务的不断拓展和战略布局的调整&#xff0c;小冷发现自己的工作节奏和生活重心正在悄然发生改变。 频繁出差…

mysql系统库介绍,数据字典(介绍,存储方式,常见表,访问权限),系统表(介绍,不同功能的表)

目录 mysql系统库 介绍 数据字典 介绍 不同版本下的存储方式 常见的数据字典表 访问权限 系统表 介绍 权限授予系统表 对象信息系统表 服务器端帮助系统表 时区系统表 mysql系统库 介绍 MySQL 默认创建 的特殊数据库&#xff0c;主要用于存储服务器运行时所需的信…

MySQL InnoDB引擎 高度为3的B+树,可以存储的数据量

一、普通B树 1、B 树结构概述 B 树是一种平衡的多路搜索树&#xff0c;常用于数据库和文件系统中。在 B 树中&#xff0c;所有的数据记录都存储在叶子节点&#xff0c;非叶子节点只存储索引信息。B 树的高度从根节点开始计算&#xff0c;根节点高度为 1。 2、计算所需参数 …