Java UDP接收数据并发布监听

一、创建一个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。当作工具类记录下。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值