哪个是按顺序发送大型 UDP 数据包的最佳方法

2022-01-22 00:00:00 sockets networking udp android java

我有一个需要每 100 毫秒通过协议 UDP 发送数据的 android 应用程序.每个 UDP 数据包平均有 15000 字节.数据包以广播方式发送

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

下面的每 100 毫秒行运行一个循环.

Every 100 milliseconds lines below are run through a loop.

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

应用程序开始工作正常,但大约 1 分钟后,接收数据包的频率会降低,直到数据包没有到达目的地.

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

UDP 数据包最大大小的理论限制(在 Windows 上)为 65507 字节

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

我知道网络的媒体 MTU 是 1500 字节,当我发送一个更大的数据包时,它会被分成几个片段,如果一个片段没有到达目的地,整个数据包就会丢失.

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.

我不明白为什么在前 1 分钟数据包被正确发送,而在一段时间后数据包不再到达.所以我想知道解决这个问题的最佳方法是什么?

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?

推荐答案

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

It's exactly the problem you described. Each datagram you broadcast is split into 44 packets. If any one of those is lost, the datagram is lost. As soon as you have enough traffic to cause, say, 1% packet loss, you have 35% datagram loss. 2% packet loss equals 60% datagram loss.

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

You need to keep your broadcast datagrams small enough not to fragment. If you have a stream of 65,507 byte chunks such that you cannot change the fact that you must have the whole chunk for the data to be useful, then naive UDP broadcast was bad choice.

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

I'd have to know a lot more about the specifics of your application to make a sensible recommendation. But if you have a chunk of data around 64KB such that you need the whole chunk for the data to be useful, and you can't change that, then you should be using an approach that divides that data into pieces with some redundancy such that some pieces can be lost. With erasure coding, you can divide 65,507 bytes of data into 46 chunks, each 1,490 bytes, such that the original data can be reconstructed from any 44 chunks. This would tolerate moderate datagram loss with only about a 4% increase in data size.

相关文章