【问题标题】:Receive UDP packets fast快速接收UDP数据包
【发布时间】:2014-12-14 01:12:01
【问题描述】:

我有一个 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' 是一个自定义视图,带有 receive() 方法。 我也尝试了处理程序和 runOnUiThread() 与 Runnable 但结果相同。 我认为 UI 线程不能更新得这么快或类似的东西。

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

【问题讨论】:

    标签: java android udp


    【解决方案1】:

    我看到这个问题有 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();
                }
            }
        }
    

    【讨论】:

      猜你喜欢
      • 2020-10-24
      • 2018-11-16
      • 2010-12-09
      • 1970-01-01
      • 2013-11-08
      • 2011-03-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多