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

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

因此,首先我将数据拆分为65507字节块并将其发送到循环中。

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

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

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

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

我不知道具体的.Net实现,它可能是缓冲你的数据,但是UDP数据报通常受到链路MTU的限制,在正常的以太网上是1500(对于IP报头减去20字节,对UDP报头减去8字节)。

明确允许UDP删除和重新排序数据报,并且没有TCP中的流控制。

超过发送方的套接字发送缓冲区将使网络堆栈忽略发送尝试,直到缓冲区空间再次可用(您需要检查send()的返回值。)

编辑:

我强烈建议使用TCP进行大文件传输。 TCP为您提供排序(您不必跟踪丢弃和重新排序的数据包。)它具有高级流控制(因此快速发送器不会压倒慢速接收器。)它还可以进行路径MTU发现(即找出最佳状态)数据打包并避免IP碎片。)否则,您必须自己重新实现大多数这些function。

对于所有那些说使用TCP的人来说都是愚蠢的错误。 虽然TCP是可靠的,并且内核维护的窗口是相当“设置并忘记”的协议,但是当涉及到想要使用100%吞吐量的人时,TCP不会这样做(它会过度加油,等待由于RTT,ACK会自动将至少50%的流量丢失。

对于原始问题,您在for循环中不间断地发送UDP数据包,窗口填满,然后立即丢弃任何新数据,甚至不尝试上线。 您也将数据拆分得太大了。 我建议建立自己的节流机制,以每秒2k段开始,然后缓慢上升。 每个“段”包含SEQ(确认或ACK的序列标识符)和OFF(该数据集的文件内的偏移)。 在标记数据时,让服务器跟踪这些标记。 当另一方获得它们时,它将SEQ号存储在ACK列表中,并且任何缺失的SEQ号被放入NACK计时器列表中,当计时器用完时(如果它们尚未被接收)它移动到NACK列表。 接收器应该每隔几秒左右在一次传输中从ACK列表发送5个左右的ACK以及最多5个NACK。 如果发送方收到这些消息并且有任何NACK,它应该立即减速并重新发送丢失的片段,然后再继续。 确认的数据可以从内存中释放。

祝好运!

我讨厌说,但你需要睡觉。 您的吞吐量正在超载。 UDP对于无损数据传输不是很好。 当你不介意丢弃一些数据包时,UDP适用于你。

可靠 – 不,你不会用UDP做。

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

在这种情况下,

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