高效地发送UDP数据包流
Efficiently send a stream of UDP packets
我知道如何在C++中打开UDP套接字,也知道如何通过它发送数据包。当我发送一个数据包时,我在另一端正确地收到了它,一切都很好。
EDIT:我还建立了一个完全可用的确认系统:数据包被编号、校验和确认,所以我随时都知道我发送的数据包中有多少,比如说,在最后一秒,实际上是从另一个端点接收的。现在,我发送的数据只有在收到所有数据包时才是可读的,所以我真的不在乎数据包排序:我只需要它们全部到达,这样它们就可以按随机顺序到达,而且仍然可以,因为按顺序排序仍然没用。
现在,我必须传输一大块数据(比如1GB),我需要尽快传输。所以我把数据分成512字节的块,然后通过UDP套接字发送。
现在,由于UDP是无连接的,它显然不能提供任何速度或传输效率诊断。因此,如果我只是试图通过我的套接字发送大量数据包,我的套接字就会接受它们,然后它们会同时发送,我的路由器会发送第一对数据包,然后开始丢弃它们。所以这并不是最有效的方法。
当时我所做的是做一个循环:
- 睡一会儿
- 发送一堆数据包
- 再睡一次等等
我试着做了一些校准,我获得了相当好的传输速率,但我有一个线程可以连续地以小束的形式发送数据包,但我对间隔应该是什么和束的大小只有一个实验性的想法。原则上,我可以想象睡一小段时间,那么一次只发送一个数据包将是路由器的最佳解决方案,但就CPU性能而言,这是完全不可行的(我可能需要忙于等待,因为两个连续数据包之间的时间非常短)。
那么,还有其他解决方案吗?有什么被广泛接受的解决方案吗?我假设我的路由器有一个缓冲区或类似的东西,这样它就可以同时接受一些数据包,然后需要一些时间来处理它们。缓冲区有多大?
我不是这方面的专家,所以任何解释都很好。
但是,请注意,由于技术原因,我根本无法使用TCP。
正如其他一些评论中所提到的,您所描述的是一个流控制系统。维基百科的文章很好地概述了实现这一点的各种方法:
http://en.wikipedia.org/wiki/Flow_control_%28data%29
你现有的解决方案(在数据包组之间睡一段硬编码的时间)原则上是可行的,但为了在现实世界中获得合理的性能,你需要能够对网络的变化做出反应。这意味着实现某种反馈,根据网络特性(如吞吐量和数据包丢失)自动调整传出数据速率和数据包大小。
一种简单的方法是使用重新传输的数据包数量作为流控制系统的输入。基本想法是,当你有很多重新传输的数据包时,你会减少数据包大小,降低数据速率,或者两者兼而有之。如果你有很少的重新传输的数据包,你会增加数据包的大小&数据速率,直到您看到重新传输的数据包增加。
这有点过于简单化了,但我想你已经明白了。
- boost::asio UDP 广播客户端仅接收"fast"数据包
- 发送固定大小的 UDP 数据包
- 使用C++将UDP数据包存储在Structure中
- 在高数据包速率下最大限度地减少丢弃的 UDP 数据包 (Windows 10)
- Qt 在可预测的秒数后跳过 UDP 数据包
- 高频接收UDP数据包:丢包?
- C++ 通过 UDP 发送数据包,但不接收数据包
- 为 posix recv 设置超时会导致 udp 数据包丢失吗?
- 了解 UDP 数据包大小限制的 TCP 数据包大小限制以及它在 boost::asio 编程级别的含义
- 获取进入UDP数据包的目标端口
- 操纵Windows Explorer窗口时,UDP数据包会掉落
- 如何模拟QT UDP程序的数据包丢失
- C++ 使用 recvmmsg 丢弃 UDP 数据包
- 使用 UDP 协议从 Windows 套接字发送到 Qt 套接字的网络数据包上的结构编码和解码
- 如何在QT中接收适当的UDP数据包
- 使用ASIO捕获大量UDP数据包
- 如何正确接收多播UDP数据包
- C++ - 构造带有标头的数据包并通过 UDP 套接字发送
- 通过RecvFrom(UDP)接收数据包的一部分
- 服务器未收到UDP数据包,花费数小时试图找出问题所在