java - 快速接收UDP数据包

标签 java android udp

我有一个 UDP 监听器线程,该线程会循环并在收到数据包后调用一个方法。它工作得很好,只是当多个数据包在第一个数据包之后很快到达时,该方法不会被调用。

两个数据包相继发送,第一个数据包长度为 2 个字节,第二个数据包长度为 3 个字节。 receive() 方法通常在第二个数据包到达时被触发。

这是 UDP 监听器类:

public class UDPListener extends Thread{
    private boolean running = true;
    byte[] data = new byte[1500];
    DatagramPacket packet = new DatagramPacket(data, data.length);

    public void run() {
        Log.v("MR", "Runs");
        try {
            while(running) {
                Log.v("MR", "Listening... ");

                socket.receive(packet);
                Log.v("MR", "Received Data: " + packet.getData()[0] + "; Length: " + packet.getLength());

                device.post(new Runnable() {
                    public void run() {
                        device.receive(packet.getData(), packet.getData().length);                           
                    }
                });

            }
        } catch (Throwable e) {
            e.printStackTrace();
            Log.v("MR", "Failed receiving");
        }

    }
}

这是 device.receive() 方法:

public final void receive(byte[] inData, int length) {
    data = inData;
    dataLength = length;
    Log.v("MR", "Receive(): Data: +" + data[0] + "; Length: " + String.valueOf(data.length));
}

这是日志结果的一部分:

10-18 17:24:34.393  Received Data: 79; Length: 3
10-18 17:24:34.393  Listening...
10-18 17:24:34.393  Receive(): Data: +79; Length: 1500
10-18 17:24:34.393  Receive(): Data: +79; Length: 1500
10-18 17:24:34.413  Received Data: 6; Length: 2
10-18 17:24:34.413  Listening...
10-18 17:24:34.413  Received Data: 79; Length: 3
10-18 17:24:34.413  Listening...
10-18 17:24:34.413  Receive(): Data: +79; Length: 1500
10-18 17:24:34.413  Receive(): Data: +79; Length: 1500
10-18 17:24:34.423  Received Data: 6; Length: 2
10-18 17:24:34.423  Listening...

可以看到数据包实际上正在传入,只是第二个(长度:3)数据包更频繁地调用 receive() 。

'device' 是一个自定义 View ,具有 receive() 方法。 我也尝试使用 handler 和 runOnUiThread() 与 Runnable 但结果相同。 我认为 UI 线程不能更新得这么快或类似的东西。

另外,为什么线程日志中是真实长度的数据包,而resume()日志中是1500字节的数据包?它应该是传递的同一个数据包。

最佳答案

我看到这个问题有 80 多个观点。解决方案是使用处理程序向 UI 发送消息,并在新数据包到来之前重新初始化 data[] 数组和 DatagramPacket。

工作代码是:

public static class UDPListener extends Thread{
        private boolean running = true;
        Message msg;
        byte[] data;
        DatagramPacket packet;

        public void run() {
            try {
                while(running) {
                    data = new byte[1500];
                    packet = new DatagramPacket(data, data.length);

                    //Blocks and waits for a packet
                    socket.receive(packet);

                    //Send packet message to UI
                    msg = UDPReceiveHandler.obtainMessage();
                    msg.obj = packet;
                    UDPReceiveHandler.sendMessage(msg);

                }
            } catch (Throwable e) {
                e.printStackTrace();
            }
        }
    }

关于java - 快速接收UDP数据包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26442179/

相关文章:

java - 编译器错误 : Type mismatch when assigned interface variable to a class

java - 我如何在 libgdx 中设置固定的 shaperenderer 旋转?

c - 每次登录时为服务器分配静态/相同的 IP 地址

c# - 在同一台计算机上的两个程序之间发送和接收 UDP 数据包

c - 套接字编程无法提取从c中的客户端发送的数据

java - 如何在maven程序集中包含rmic包jar

java - LWJGL 3 中的抗锯齿

android - 如何使用数据绑定(bind)初始化 Recycler View 适配器上的点击监听器?

Android Studio 给出关于 JDK 位置的警告

android - 使用动画将 ImageView 从同一 Activity 中的一种布局移动到另一种布局