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

时间:2013-09-23 20:20:30

标签: java android udp

我最近在我的Android(特别是2.3.3和4.0.4)应用程序中实现了UDP数据包排序支持,该应用程序在设备之间广播UDP数据包。排序支持基本上采用任何byte []并将其组合成UDP友好大小并将其作为UDP数据包发送出去。我包含的标题有助于UDP序列识别。现在看起来好像通过它广播大数据集是有效的。任何监听它的对等体都可以重新组合序列,然后相应地处理数据。 (我正在播放用相机和语音片段拍摄的图像)

我发现虽然偶尔(经常)序列中的数据包将被丢弃。在有人说UDP不可靠之前,不要打扰。我很清楚。这里发生的事情不一定是不可靠的。

首先,UDP数据包排序将每2秒发送1个分段的UDP数据包。例如如果数据是128K,则将有3个数据包,在6秒的时间内发送出去。 2秒的数字是为了帮助测试。

其次,我在隔离的测试环境中只有2个设备。他们是测试wifi网络中唯一的。

第三,这些设备除了测试发送和接收这些UDP数据包之外什么都不做。

第四,我的日志记录跟踪每个数据包的唯一基于序列的ID。它有助于确定发送方在序列中发送的数据包以及接收方接收的数据包。

我无法向您显示日志,但它无济于事,但发件人会注意到每个数据包都已广播,而接收器将丢弃一个,可能在任何时候。有时接收器会获得所有东西,有时它会丢失一个。

现在我已经解释了这一切,Android队列是否收到了处理套接字的UDP数据包?

我不认为接收器太忙而无法接受UDP数据包。 (它们每2秒发送一次)

目前我的服务启动一个基本上在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());
        }
    }
}

在我的日志中,我会直接看到:(这是我日志中的剪辑,而不是直接来自上面代码片段的输出)

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!

请注意,数据包20缺失。如果我查看我的发送方设备的日志,我会看到他每隔2秒发送一次所有数据包。您可以在时间码中看到在1:26:35收到数据包19,并在1:26:39收到数据包21。 (介于4秒之间)

我有点不知所措。 Android和UDP数据包丢失是否存在已知问题? Android / Java UDP堆栈队列在一段时间内收到的数据包是服务是否忙于处理其他数据包?

除了切换到TCP之外的任何建议都会有所帮助。提前谢谢!

1 个答案:

答案 0 :(得分:1)

好的,我解决了我的问题。

我将我的应用程序Service中的直接单个ScheduledExecutorService + Runnable线程切换到Runnable,它将生成新的ExecutorService Runnables来处理收到的DatagramPacket。我猜我的接收器中有一点I / O延迟/阻塞,并将其分成一个单独的线程来处理分组数据似乎工作。我使用新方法在设备之间传输了1.8MB大小的数据测试。