8

I have an android application that needs to send data through the protocol UDP every 100 milliseconds. Each UDP packet has 15000 bytes average. packets are sent in broadcast

Every 100 milliseconds lines below are run through a loop.

DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, broadcast, 9876); 
clientSocket.send(sendPacket);

Application starts working fine, but after about 1 minute frequency of received packets decreases until the packets do not arrive over the destination.

The theoretical limit (on Windows) for the maximum size of a UDP packet is 65507 bytes

I know the media MTU of a network is 1500 bytes and when I send a packet bigger it is broken into several fragments and if a fragment does not reach the destination the whole package is lost.

I do not understand why at first 1 minute the packets are sent correctly and after a while the packets do not arrive more. So I wonder what would be the best approach to solve this problem?

4

2 回答 2

14

正是你描述的问题。您广播的每个数据报都被分成 44 个数据包。如果其中任何一个丢失,则数据报丢失。一旦你有足够的流量导致 1% 的数据包丢失,你就会有 35% 的数据报丢失。2% 的数据包丢失等于 60% 的数据报丢失。

你需要保持你的广播数据报足够小而不会碎片化。如果您有一个 65,507 字节块的流,这样您就无法更改必须拥有整个块才能使数据有用的事实,那么天真的 UDP 广播是不好的选择。

我必须更多地了解您的应用程序的细节才能提出明智的建议。但是,如果您有一个大约 64KB 的数据块,这样您需要整个数据块才能使数据有用,并且您无法更改它,那么您应该使用一种方法将该数据分成具有一些冗余的片段,这样有些碎片可能会丢失。使用纠删码,您可以将 65,507 字节的数据分成 46 个块,每块 1,490 个字节,这样就可以从任意 44 个块中重构出原始数据。这将容忍适度的数据报丢失,数据大小仅增加约 4%。

于 2013-09-27T18:27:58.050 回答
2

当您需要可靠且正确排序的交付时,专门使用 TCP 而不是 UDP。但假设您确实需要 UDP 进行广播,您可以:

  1. 调试网络以查看数据包丢失的方式和位置,或者可能是接收器阻塞/滞后。但通常你无法控制这些事情。是否涉及 WiFi 网络?如果是这样,很难获得良好的 QoS。

  2. 在应用层做一些事情以确保订购和可靠的交付。例如,SIP 通常使用 UDP,但该协议使用事务和序列号,因此客户端和服务器将根据需要重新传输消息。

  3. 实现丢包隐藏。使用数学,接收器可以重新创建丢失的数据包,类似于 RAID 磁盘设置如何丢失驱动器并仍然运行。

您的设置可以正常工作一分钟,然后并不暗示广播或接收端存在网络拥塞或软件拥塞。

你能用 Wireshark 做一些数据包捕获并分享结果吗?

于 2013-09-27T18:37:13.917 回答