高效地发送 UDP 数据包流
Efficiently send a stream of UDP packets
我知道如何在 C++ 中打开 UDP 套接字,我也知道如何通过它发送数据包。当我发送一个数据包时,我在另一端正确地收到了它,并且一切正常。
编辑:我还建立了一个完整的确认系统:数据包被编号、校验和确认,所以在任何时候我都知道我发送了多少数据包,比如,在最后一秒实际上是从另一个端点收到的。现在,我发送的数据只有在收到所有数据包时才可读,所以我真的不关心数据包的顺序:我只需要它们全部到达,这样它们就可以随机顺序到达,而且它仍然会没关系,因为按顺序排列它们仍然没有用。
现在,我必须传输大量数据(比如 1 GB),并且我需要尽快传输这些数据。所以我将数据分成 512 字节的块并通过 UDP 套接字发送它们。
现在,由于 UDP 是无连接的,它显然不提供任何速度或传输效率诊断。因此,如果我只是尝试通过我的套接字发送大量数据包,我的套接字将只接受它们,然后将它们一次全部发送,我的路由器将发送第一对数据包,然后开始丢弃它们。所以这不是完成这项工作的最有效方法。
然后我做了一个循环:
- 睡一会儿
- 发送一堆数据包
- 再睡觉等等
我试着做了一些校准,我获得了很好的传输率,但是我有一个线程不断地以小束发送数据包,但我除了一个关于间隔应该是什么以及什么是什么的实验性想法之外什么都没有束的大小应该是。原则上,我可以想象睡眠时间非常短,然后一次只发送一个数据包将是路由器的最佳解决方案,但是就 CPU 性能而言这是完全不可行的(我可能需要忙等待,因为两个连续数据包之间的时间真的很短)。
那么还有其他解决办法吗?任何被广泛接受的解决方案?我假设我的路由器有一个缓冲区或类似的东西,所以它可以一次接受一些数据包,然后它需要一些时间来处理它们。该缓冲区有多大?
我不是这方面的专家,所以任何解释都很好。
但是请注意,由于技术原因,根本没有办法我可以使用 TCP。
如其他一些评论中所述,您所描述的是流量控制系统。维基百科文章很好地概述了执行此操作的各种方法:
http://en.wikipedia.org/wiki/Flow_control_%28data%29
您现有的解决方案(在数据包组之间休眠一段硬编码时间)原则上是可行的,但为了在现实世界的系统中获得合理的性能,您需要能够对网络的变化。这意味着实施某种反馈,您可以根据网络特性(例如吞吐量和数据包丢失)自动调整传出数据速率和数据包大小。
一个简单的方法是使用重新传输的数据包的数量作为流量控制系统的输入。基本思想是,当您有大量重新传输的数据包时,您将减小数据包大小,降低数据速率,或两者兼而有之。如果重新传输的数据包很少,则可以增加数据包大小和数据速率,直到看到重新传输的数据包增加为止。
这有点过于简单化了,但我想您明白了。
我知道如何在 C++ 中打开 UDP 套接字,我也知道如何通过它发送数据包。当我发送一个数据包时,我在另一端正确地收到了它,并且一切正常。
编辑:我还建立了一个完整的确认系统:数据包被编号、校验和确认,所以在任何时候我都知道我发送了多少数据包,比如,在最后一秒实际上是从另一个端点收到的。现在,我发送的数据只有在收到所有数据包时才可读,所以我真的不关心数据包的顺序:我只需要它们全部到达,这样它们就可以随机顺序到达,而且它仍然会没关系,因为按顺序排列它们仍然没有用。
现在,我必须传输大量数据(比如 1 GB),并且我需要尽快传输这些数据。所以我将数据分成 512 字节的块并通过 UDP 套接字发送它们。
现在,由于 UDP 是无连接的,它显然不提供任何速度或传输效率诊断。因此,如果我只是尝试通过我的套接字发送大量数据包,我的套接字将只接受它们,然后将它们一次全部发送,我的路由器将发送第一对数据包,然后开始丢弃它们。所以这不是完成这项工作的最有效方法。
然后我做了一个循环:
- 睡一会儿
- 发送一堆数据包
- 再睡觉等等
我试着做了一些校准,我获得了很好的传输率,但是我有一个线程不断地以小束发送数据包,但我除了一个关于间隔应该是什么以及什么是什么的实验性想法之外什么都没有束的大小应该是。原则上,我可以想象睡眠时间非常短,然后一次只发送一个数据包将是路由器的最佳解决方案,但是就 CPU 性能而言这是完全不可行的(我可能需要忙等待,因为两个连续数据包之间的时间真的很短)。
那么还有其他解决办法吗?任何被广泛接受的解决方案?我假设我的路由器有一个缓冲区或类似的东西,所以它可以一次接受一些数据包,然后它需要一些时间来处理它们。该缓冲区有多大?
我不是这方面的专家,所以任何解释都很好。
但是请注意,由于技术原因,根本没有办法我可以使用 TCP。
如其他一些评论中所述,您所描述的是流量控制系统。维基百科文章很好地概述了执行此操作的各种方法:
http://en.wikipedia.org/wiki/Flow_control_%28data%29
您现有的解决方案(在数据包组之间休眠一段硬编码时间)原则上是可行的,但为了在现实世界的系统中获得合理的性能,您需要能够对网络的变化。这意味着实施某种反馈,您可以根据网络特性(例如吞吐量和数据包丢失)自动调整传出数据速率和数据包大小。
一个简单的方法是使用重新传输的数据包的数量作为流量控制系统的输入。基本思想是,当您有大量重新传输的数据包时,您将减小数据包大小,降低数据速率,或两者兼而有之。如果重新传输的数据包很少,则可以增加数据包大小和数据速率,直到看到重新传输的数据包增加为止。
这有点过于简单化了,但我想您明白了。