如何使用C#UdpClient发送大数据?

时间:2010-02-23 15:52:34

标签: c# udp

我正在尝试使用C#UdpClient发送大量数据(超过50 MB)。

首先,我将数据拆分为65507个字节块并循环发送。

for(int i = 0; i < packetCount; i++)
   myUdpClient.Send(blocks[i], block[i].Length, remoteEndPoint);

我的问题是只能收到第一个数据包。 在发送第一个数据包期间,网络负载迅速增加到100%,然后无法接收其他数据包。

我希望获得尽可能多的数据吞吐量。

对不起我的英语! 感谢您的帮助。

4 个答案:

答案 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来做。

据我了解,这对于一次发送到多台计算机(广播)是有意义的。

在这种情况下,

  • 与每个人建立TCP连接,
  • 将数据拆分成块,
  • 为每个块提供一个ID,
  • 使用TCP连接向每台计算机发送ID列表
  • 使用UDP广播数据
  • 通知客户端(通过TCP)数据传输结束,
  • 比客户端要求重新发送丢弃的数据包