我最近在我的 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 秒发送一次)
目前,我的服务启动了一个 Runnable,它基本上在 DatagramSocket.receive() 上循环,然后相应地处理接收到的数据包。
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 秒发送一次所有数据包。您可以在时间码中看到数据包 19 在 1:26:35 收到,数据包 21 在 1:26:39 收到。(中间 4 秒)
我有点不知所措。Android 和 UDP 数据包丢失是否存在已知问题?Android/Java UDP堆栈队列接收数据包一段时间是服务忙于处理其他数据包吗?
除了切换到 TCP 之外的任何建议都会有所帮助。提前致谢!