一、创建一个UDP接收工具类
接收数据将数据存入一个消息队列中。然后创建后台线程循环处理消息队列中的数据,处理完成一个报文后就将数据发布出去,由订阅者进行自定义的处理。从而实现了数据接收和处理的解耦。以下是工具类的代码。
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.ArrayList;
import java.util.List;
public class UdpReceiver {
// 声明事件和监听器接口
public interface DataReceivedListener {
void onDataReceived(String data);
}
private DatagramSocket udpSocket;
private int port;
private ConcurrentLinkedQueue<String> dataQueue;
private List<DataReceivedListener> dataReceivedListeners;
public UdpReceiver(int port) {
this.port = port;
this.dataQueue = new ConcurrentLinkedQueue<>();
this.dataReceivedListeners = new ArrayList<>();
}
public void start() {
try {
udpSocket = new DatagramSocket(port);
// 启动后台线程处理缓冲队列中的数据
new Thread(this::processDataQueueInBackground).start();
// 开始接收UDP数据包
receiveData();
} catch (Exception ex) {
System.err.println("启动UDP接收端出错:" + ex.getMessage());
}
}
private void receiveData() {
try {
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
while (true) {
udpSocket.receive(packet);
String receivedData = new String(packet.getData(), 0, packet.getLength());
dataQueue.add(receivedData);
}
} catch (Exception ex) {
System.err.println("接收UDP数据出错:" + ex.getMessage());
}
}
private void processDataQueueInBackground() {
while (true) {
if (!dataQueue.isEmpty()) {
String data = dataQueue.poll();
onDataReceived(data);
} else {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
// 添加多个监听者
public void addDataReceivedListener(DataReceivedListener listener) {
dataReceivedListeners.add(listener);
}
// 解除监听者
public void removeDataReceivedListener(DataReceivedListener listener) {
dataReceivedListeners.remove(listener);
}
private void onDataReceived(String data) {
for (DataReceivedListener listener : dataReceivedListeners) {
listener.onDataReceived(data);
}
}
// 停止UDP接收端
public void stop() {
if (udpSocket != null) {
udpSocket.close();
}
}
}
二、主程序中测试
public class Main {
public static void main(String[] args) {
int port = 12345;
UdpReceiver receiver = new UdpReceiver(port);
// 添加多个事件监听者
DataReceivedListener listener1 = new DataReceivedListener() {
@Override
public void onDataReceived(String data) {
System.out.println("监听者1接收到数据:" + data);
// 在这里进行数据处理
}
};
DataReceivedListener listener2 = new DataReceivedListener() {
@Override
public void onDataReceived(String data) {
System.out.println("监听者2接收到数据:" + data);
// 在这里进行其他数据处理
}
};
receiver.addDataReceivedListener(listener1);
receiver.addDataReceivedListener(listener2);
// 启动UDP接收端
receiver.start();
// 等待一段时间后解除监听者listener2
try {
Thread.sleep(5000);
receiver.removeDataReceivedListener(listener2);
System.out.println("监听者2已解除");
} catch (InterruptedException ex) {
ex.printStackTrace();
}
System.out.println("按回车键停止UDP接收端...");
try {
System.in.read();
} catch (Exception ex) {
ex.printStackTrace();
}
// 停止UDP接收端
receiver.stop();
}
}
以上引自无敌的ChatGPT。当作工具类记录下。