欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 养生 > JAVA异步的UDP 通讯-客户端

JAVA异步的UDP 通讯-客户端

2025/2/7 22:49:41 来源:https://blog.csdn.net/a876106354/article/details/145471689  浏览:    关键词:JAVA异步的UDP 通讯-客户端

1. 使用DatagramSocket的非阻塞模式

Java的DatagramSocket默认是阻塞模式,但可以通过设置Socket选项来启用非阻塞模式。这样可以在发送和接收数据时避免线程阻塞

import java.net.DatagramSocket;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.StandardSocketOptions;public class AsyncUDPClient {public static void main(String[] args) throws Exception {DatagramSocket socket = DatagramSocket.create();socket.setOption(StandardSocketOptions.SO_REUSEADDR, true); // 允许端口复用socket.connect(InetAddress.getByName("localhost"), 12345); // 连接到服务器socket.setSoTimeout(1000); // 设置超时时间// 发送数据String message = "Hello, UDP Server!";byte[] data = message.getBytes();DatagramPacket packet = new DatagramPacket(data, data.length);socket.send(packet);// 接收响应byte[] receiveBuffer = new byte[1024];DatagramPacket receivePacket = new DatagramPacket(receiveBuffer, receiveBuffer.length);socket.receive(receivePacket);String response = new String(receivePacket.getData(), 0, receivePacket.getLength());System.out.println("Received from server: " + response);socket.close();}
}

2. 使用线程池实现异步处理

通过线程池来处理UDP数据的发送和接收,可以避免阻塞主线程,提高程序的响应性。

import java.net.DatagramSocket;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class AsyncUDPClientWithThreadPool {private static final ExecutorService executor = Executors.newFixedThreadPool(4);public static void main(String[] args) throws Exception {DatagramSocket socket = new DatagramSocket();socket.connect(InetAddress.getByName("localhost"), 12345);// 异步发送数据executor.submit(() -> {try {String message = "Hello, UDP Server!";byte[] data = message.getBytes();DatagramPacket packet = new DatagramPacket(data, data.length);socket.send(packet);System.out.println("Message sent to server.");} catch (Exception e) {e.printStackTrace();}});// 异步接收数据executor.submit(() -> {try {byte[] receiveBuffer = new byte[1024];DatagramPacket receivePacket = new DatagramPacket(receiveBuffer, receiveBuffer.length);socket.receive(receivePacket);String response = new String(receivePacket.getData(), 0, receivePacket.getLength());System.out.println("Received from server: " + response);} catch (Exception e) {e.printStackTrace();}});executor.shutdown();socket.close();}
}

3. 使用Selector实现多路复用

Selector可以用于同时监控多个DatagramSocket,从而实现更高效的异步通信。

import java.net.DatagramSocket;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.nio.channels.DatagramChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.ByteBuffer;public class AsyncUDPClientWithSelector {public static void main(String[] args) throws Exception {DatagramChannel channel = DatagramChannel.open();channel.configureBlocking(false);channel.connect(InetAddress.getByName("localhost"), 12345);Selector selector = Selector.open();channel.register(selector, SelectionKey.OP_WRITE | SelectionKey.OP_READ);while (selector.select() > 0) {for (SelectionKey key : selector.selectedKeys()) {if (key.isWritable()) {String message = "Hello, UDP Server!";byte[] data = message.getBytes();DatagramPacket packet = new DatagramPacket(data, data.length);channel.send(ByteBuffer.wrap(data), channel.socket().getRemoteSocketAddress());System.out.println("Message sent to server.");}if (key.isReadable()) {byte[] receiveBuffer = new byte[1024];DatagramPacket receivePacket = new DatagramPacket(receiveBuffer, receiveBuffer.length);channel.receive(receivePacket);String response = new String(receivePacket.getData(), 0, receivePacket.getLength());System.out.println("Received from server: " + response);}selector.selectedKeys().remove(key);}}channel.close();selector.close();}
}

4. 设置合理的超时和缓冲区大小

通过设置setSoTimeoutsetReceiveBufferSize等参数,可以优化UDP客户端的性能。

socket.setSoTimeout(1000); // 设置接收超时时间
socket.setReceiveBufferSize(8192); // 设置接收缓冲区大小
socket.setSendBufferSize(8192); // 设置发送缓冲区大小

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com