简体   繁体   English

Android是否为DatagramSocket排队UDP数据包?

[英]Does Android queue UDP packets for DatagramSocket?

I recently implemented UDP packet sequencing support in my Android (2.3.3 and 4.0.4 specifically) app that broadcasts UDP packets between devices. 我最近在我的Android(特别是2.3.3和4.0.4)应用程序中实现了UDP数据包排序支持,该应用程序在设备之间广播UDP数据包。 The sequencing support basically takes any byte[] and chunks it up into UDP friendly sizes and send them out as UDP packets. 排序支持基本上采用任何byte []并将其组合成UDP友好大小并将其作为UDP数据包发送出去。 There's a header I include that helps with UDP sequence identification. 我包含的标题有助于UDP序列识别。 Right now it appears as if broadcasting a large data set via it works. 现在看起来好像通过它广播大数据集是有效的。 Any peers listening for it can reassemble the sequence fine, then process the data accordingly. 任何监听它的对等体都可以重新组合序列,然后相应地处理数据。 (I'm broadcasting an image taken with the camera and voice clips) (我正在播放用相机和语音片段拍摄的图像)

What I'm finding though is occasionally (often) a packet in the sequence will be dropped. 我发现虽然偶尔(通常)序列中的数据包将被丢弃。 Before anyone says that UDP is not reliable, don't bother. 在有人说UDP不可靠之前,不要打扰。 I'm well aware. 我很清楚。 What's happening here isn't necessarily unreliability. 这里发生的事情不一定是不可靠的。

First the UDP packet sequencing will send out 1 segmented UDP packet every 2 seconds. 首先,UDP数据包排序将每2秒发送1个分段的UDP数据包。 eg if the data is 128K, there will be 3 packets, sent out over a 6 second period. 例如,如果数据是128K,则将有3个数据包,在6秒的时间段内发送出去。 The 2 second number is to help with testing. 2秒的数字是为了帮助测试。

Second, I only have 2 devices in my isolated test environment. 其次,我在隔离的测试环境中只有2个设备。 They're the only ones on the test wifi network. 他们是测试wifi网络中唯一的。

Third, these devices are doing nothing but testing sending and receiving these UDP packets. 第三,这些设备除了测试发送和接收这些UDP数据包之外什么都不做。

Fourth, my logging tracks a unique sequence based ID for each packet. 第四,我的日志记录跟踪每个数据包的唯一基于序列的ID。 It helps with determining which packet the sender sent in a sequence, and which the receiver received. 它有助于确定发送方在序列中发送的数据包以及接收方接收的数据包。

I can't show you logs, it wouldn't help, but the sender will note that every packet has been broadcast, while the receiver will drop one, potentially at any point. 我无法向您显示日志,它无济于事,但发件人会注意到每个数据包都已广播,而接收器将丢弃一个,可能在任何时候。 Sometimes the receiver gets everything, sometimes it's missing one. 有时接收器会获得所有东西,有时它会丢失一个。

NOW that I've explained all that, does Android queue received UDP packets for a processing socket? 现在我已经解释了这一切,Android队列是否收到了处理套接字的UDP数据包?

I don't think the receiver is too busy to accept the UDP packets. 我不认为接收器太忙而无法接受UDP数据包。 (they are sent every 2 seconds) (它们每2秒发送一次)

Currently my service starts a Runnable that basically loops on DatagramSocket.receive(), then processes the received packet accordingly. 目前我的服务启动一个基本上在DatagramSocket.receive()上循环的Runnable,然后相应地处理收到的数据包。

public class MulticastListenerRunnable implements Runnable {
    ...
    public void run() {
        try {
            multicastServer = new DatagramSocket(port, null);
            byte[] buffer = new byte[DatagramSession.DATAGRAM_MAX_SIZE];
            DatagramPacket packet = null;
            byte[] data;

            while(run) {
                try {
                    packet = new DatagramPacket(buffer, buffer.length);
                    packet.setLength(buffer.length);
                    multicastServer.receive(packet);
if(packet.getAddress().getHostAddress().equals("127.0.0.1") || packet.getAddress().getHostAddress().equals(ipAddress)) {
                        continue;
                    }
                    Log.d(TAG, "START PACKET RECEIVE!");
                    processPacket(packet);
            }
        } catch (IOException e) {
            Log.e(TAG, e.getMessage());
        } catch (Exception e) {             
            Log.e(TAG, e.getMessage());
        }
    }
}

In my logs I'll literally see: (it's a clip from my log, not from directly the output of the above code clip) 在我的日志中,我将逐字地看到:(这是我日志中的剪辑,而不是直接来自上面代码片段的输出)

03-21 01:26:35.453: D/CommService(6446): START PACKET RECEIVE!
03-21 01:26:35.507: D/CommService(6446): RECEIVED PACKET:  19 of 28 -> 64977(65000 max)
03-21 01:26:35.515: D/CommService(6446): RECEIVED PACKET: This packet isn't alone. More to come!
03-21 01:26:35.515: D/CommService(6446): END PACKET RECEIVE!


03-21 01:26:39.460: D/CommService(6446): START PACKET RECEIVE!
03-21 01:26:39.468: W/DatagramSession(6446): Warning, this packet's sequence isn't in order, last -> 18, new -> 20
03-21 01:26:39.476: D/CommService(6446): RECEIVED PACKET: This packet isn't alone. More to come!
03-21 01:26:39.476: D/CommService(6446): END PACKET RECEIVE!

Note that packet 20 is missing. 请注意,数据包20缺失。 If I look on my sender device's logs, I'll see him send out all packets every 2 seconds. 如果我查看我的发送方设备的日志,我会看到他每隔2秒发送一次所有数据包。 You can see in the time code that packet 19 is received at 1:26:35, and packet 21 is received 1:26:39. 您可以在时间码中看到在1:26:35收到数据包19,并在1:26:39收到数据包21。 (4 seconds in between) (中间4秒)

I'm kind of at a loss. 我有点不知所措。 Is there a know issue with Android and UDP packet loss? Android和UDP数据包丢失是否存在已知问题? Does the Android/Java UDP stack queue received packets for a period of time is the service is too busy processing other packets? Android / Java UDP堆栈队列在一段时间内收到的数据包是服务是否忙于处理其他数据包?

Any suggestions other than switching to TCP would be helpful. 除了切换到TCP之外的任何建议都会有所帮助。 Thanks in advance! 提前致谢!

Ok, I fixed my issue. 好的,我解决了我的问题。

I switched my straight single ScheduledExecutorService + Runnable thread in my application Service to a Runnable that will spawn new ExecutorService Runnables to process the received DatagramPacket. 我将我的应用程序服务中的直接单个ScheduledExecutorService + Runnable线程切换到Runnable,它将生成新的ExecutorService Runnables来处理收到的DatagramPacket。 I guess there was a little I/O delay/blocking in my receiver and splitting it out into a separate thread to process the packet data appears to work. 我猜我的接收器中有一点I / O延迟/阻塞,并将其分成一个单独的线程来处理分组数据似乎工作。 I've transmitted 1.8MB size data tests between devices using the new approach. 我使用新方法在设备之间传输了1.8MB大小的数据测试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM