高效地发送UDP数据包流

Efficiently send a stream of UDP packets

本文关键字:数据包 UDP 高效      更新时间:2023-10-16

我知道如何在C++中打开UDP套接字,也知道如何通过它发送数据包。当我发送一个数据包时,我在另一端正确地收到了它,一切都很好。

EDIT:我还建立了一个完全可用的确认系统:数据包被编号、校验和确认,所以我随时都知道我发送的数据包中有多少,比如说,在最后一秒,实际上是从另一个端点接收的。现在,我发送的数据只有在收到所有数据包时才是可读的,所以我真的不在乎数据包排序:我只需要它们全部到达,这样它们就可以按随机顺序到达,而且仍然可以,因为按顺序排序仍然没用。

现在,我必须传输一大块数据(比如1GB),我需要尽快传输。所以我把数据分成512字节的块,然后通过UDP套接字发送。

现在,由于UDP是无连接的,它显然不能提供任何速度或传输效率诊断。因此,如果我只是试图通过我的套接字发送大量数据包,我的套接字就会接受它们,然后它们会同时发送,我的路由器会发送第一对数据包,然后开始丢弃它们。所以这并不是最有效的方法。

当时我所做的是做一个循环:

  • 睡一会儿
  • 发送一堆数据包
  • 再睡一次等等

我试着做了一些校准,我获得了相当好的传输速率,但我有一个线程可以连续地以小束的形式发送数据包,但我对间隔应该是什么和束的大小只有一个实验性的想法。原则上,我可以想象睡一小段时间,那么一次只发送一个数据包将是路由器的最佳解决方案,但就CPU性能而言,这是完全不可行的(我可能需要忙于等待,因为两个连续数据包之间的时间非常短)。

那么,还有其他解决方案吗?有什么被广泛接受的解决方案吗?我假设我的路由器有一个缓冲区或类似的东西,这样它就可以同时接受一些数据包,然后需要一些时间来处理它们。缓冲区有多大?

我不是这方面的专家,所以任何解释都很好。

但是,请注意,由于技术原因,我根本无法使用TCP。

正如其他一些评论中所提到的,您所描述的是一个流控制系统。维基百科的文章很好地概述了实现这一点的各种方法:

http://en.wikipedia.org/wiki/Flow_control_%28data%29

你现有的解决方案(在数据包组之间睡一段硬编码的时间)原则上是可行的,但为了在现实世界中获得合理的性能,你需要能够对网络的变化做出反应。这意味着实现某种反馈,根据网络特性(如吞吐量和数据包丢失)自动调整传出数据速率和数据包大小。

一种简单的方法是使用重新传输的数据包数量作为流控制系统的输入。基本想法是,当你有很多重新传输的数据包时,你会减少数据包大小,降低数据速率,或者两者兼而有之。如果你有很少的重新传输的数据包,你会增加数据包的大小&数据速率,直到您看到重新传输的数据包增加。

这有点过于简单化了,但我想你已经明白了。