我正在尝试使用C#UdpClient发送大量数据(超过50 MB)。
首先,我将数据拆分为65507个字节块并循环发送。
for(int i = 0; i < packetCount; i++)
myUdpClient.Send(blocks[i], block[i].Length, remoteEndPoint);
我的问题是只能收到第一个数据包。 在发送第一个数据包期间,网络负载迅速增加到100%,然后无法接收其他数据包。
我希望获得尽可能多的数据吞吐量。
对不起我的英语! 感谢您的帮助。
答案 0 :(得分:10)
对于所有那些说使用TCP的人来说都是愚蠢的错误。虽然TCP是可靠的,并且内核维护的窗口是相当“设置并忘记”的协议,但是当涉及到想要使用100%吞吐量的人时,TCP不会这样做(它节制太大,等待由于RTT,ACK会自动至少丢失50%。
对于原始问题,您将在for循环中不间断地发送UDP数据包,窗口填满,然后立即删除任何新数据,甚至不尝试继续使用。您还将数据拆分得太大了。我建议建立自己的节流机制,每秒开始2k段,慢慢上升。每个“段”包含SEQ(确认或ACK的序列标识符)和OFF(该数据集的文件内的偏移)。在标记数据时,让服务器跟踪这些标记。当另一方获得它们时,它将SEQ号存储在ACK列表中,并且任何缺失的SEQ号被放入NACK计时器列表中,当计时器用完时(如果它们尚未被接收)它将移动到NACK列表。接收器应每隔几秒左右在一次传输中从ACK列表发送5个左右的ACK以及最多5个NACK。如果发送方收到这些消息并且有任何NACK,它应该立即减速并重新发送丢失的片段,然后再继续。确认的数据可以从内存中释放。
祝你好运!答案 1 :(得分:2)
我讨厌说出来,但你需要睡觉。您的吞吐量正在超载。 UDP对于无损数据传输不是很好。当你不介意丢弃一些数据包时,UDP适用于你。
答案 2 :(得分:2)
我不知道具体的.Net实现,它可能是缓冲你的数据,但是UDP数据报通常受到链路MTU的限制,在正常以太网上是1500(对于IP报头减去20字节,对UDP报文减去8字节)标题。)
明确允许UDP删除和重新排序数据报,并且没有TCP中的流控制。
超过发送方的套接字发送缓冲区将使网络堆栈忽略发送尝试,直到缓冲区空间再次可用(您需要检查send()
的返回值。)
我强烈建议使用TCP进行大型文件传输。 TCP为您提供排序(您不必跟踪丢弃和重新排序的数据包。)它具有高级流控制(因此快速发送器不会压倒慢速接收器。)它还可以进行路径MTU发现(即找出最佳状态)数据打包并避免IP碎片化。)否则,您必须自己重新实现大部分功能。
答案 3 :(得分:0)
可靠 - 不,你不会用UDP来做。
据我了解,这对于一次发送到多台计算机(广播)是有意义的。
在这种情况下,