【问题标题】:Speeding up UDP-based file transfer with loss protection?通过丢失保护加速基于 UDP 的文件传输?
【发布时间】:2011-12-11 19:55:07
【问题描述】:

我正在尝试学习UDP,并制作一个简单的文件传输服务器和客户端。 我知道 TCP 可能会更好,因为它内置了一些可靠性。但是我想自己实现一些基本的可靠性代码。

我决定尝试确定数据包何时丢失,然后重新发送。

我实现的是一个系统,服务器将向客户端发送一个 10 字节块的特定文件。在它发送每个块之后,它等待确认。如果它在几秒钟内没有收到一个,它会再次发送该块。

我的问题是如何快速完成这样的文件传输?如果你发送一个文件,假设他们有 25% 的机会丢失一个数据包,那么等待 ACK 的时间就会很长。

有没有办法解决这个问题?还是认为丢包率高,需要很长时间?确认的可接受超时值是多少?

谢谢!

【问题讨论】:

    标签: c sockets networking udp file-transfer


    【解决方案1】:

    您的帖子中有很多问题,我会尽力解决一些问题。主要是进行基准测试并找到瓶颈。 最慢的操作是什么?

    我现在可以告诉您,您方法的瓶颈是在每个块之后等待 ACK。您想要确认序列,而不是确认块。第二大问题是可笑的小块。在这种大小下,开销比实际数据多(查找 IP 和 UDP 的标头大小)。

    总结:

    我实现的是一个系统,服务器将在其中发送 客户端以 10 字节块为单位的某个文件。

    您可能想尝试几百字节的块。

    发送每个块后,它等待确认。

    在需要确认之前发送更多块,并标记它们。方法不止一种:

    • 不是确认数据块,而是确认数据:“我收到了 5000 字节”(TCP,传统)
    • 在一条消息中确认多个块。 “我收到了 1、5、7、9 块”(带 SACK 的 TCP)

    【讨论】:

    • 如果我在确认之前发送更多块,在高数据包丢失情况下会不会更慢?我猜这个假设是带宽足够高,可以处理更大的块大小。
    • 也没有办法在没有信号的情况下进行确认吗?我不能只使用 recvfrom,因为它只会挂起,但如果有另一种方法可以在没有信号的情况下做到这一点,那将是最好的。
    • @cnicutar,作为优化,OP可能要考虑检测服务器和客户端是否在同一个IP子网上,如果是,这意味着它们在同一个局域网上,并且数据包的机会损失(通常)是微不足道的。在这种情况下,他应该将他的块增加到非常大的大小(可能是 1400 字节,或者如果他对实施 IP 分片感到满意,则可以更大)。进一步的优化可能是检测往返时间和 TTL 减少的数量;更低的往返时间和更少的路由器跳数(即 TTL 递减)也意味着更高的路径可靠性
    • 我喜欢收到多少字节的想法。我将为 ACK 的实现创建一个单独的问题,并认为这个问题得到了回答,因为这两点都很有意义。
    • @Mike Pennington,这是我没有考虑过的一个很好的优化。一旦我在 2 个不同的 IP 上运行良好,我会调查它。
    【解决方案2】:

    您实现的是Stop-and-wait ARQ。在高延迟网络中,它不可避免地会比其他一些更复杂的选项慢,因为它在每次传输时都等待一个完整的周期。

    有关其他可能性,请参阅Sliding Window 并点击其他变体的链接。你得到的基本上是一种退化形式的滑动窗口,窗口大小为 1。

    正如其他答案所指出的,这将涉及向您的数据包添加序列号,在等待确认时发送额外的数据包,并以更复杂的模式重新传输。

    如果你这样做,你实际上是在重新发明 TCP,它使用这些策略来提供可靠的连接。

    【讨论】:

      【解决方案3】:

      您需要某种数据包编号,以便客户端可以通过接收数据包序列中丢失的编号来检测丢失的数据包。然后客户端可以请求重新发送它知道丢失的数据包。

      例子:

      服务器向客户端发送数据包 1,2,3,4,5。客户端收到 1,4,5,所以它知道 2 和 3 丢失了。所以客户端确认 1,4 和 5 并请求重新发送 2 和 3。

      那么你还需要弄清楚如何处理acks/resends等请求。无论如何,为数据包分配一个连续数字的序列,以便可以通过序列中的“间隙”来检测数据包丢失是一个解决这个问题的好方法。

      【讨论】:

        【解决方案4】:

        您的问题准确地描述了 TCP 试图回答的问题之一。 TCP 的答案特别优雅和简洁,imo,因此阅读 TCP 的英文描述可能会给您带来回报。

        只是让您大致了解现实世界中的 UDP:SNMP 是一种网络管理协议,旨在通过 UDP 运行。管理器向受管节点发送的 SNMP 请求(大约 1500 个有效负载字节)永远不会被明确确认,并且工作得很好。 25% 的数据包丢失是一个巨大的数字——现实生活中的数据包丢失要小一个数量级,在最坏的情况下——而且,在那个破碎的环境中,SNMP 几乎无法工作。当然,操作网络管理系统(NMS)的人会很快通过电话获得网络硬件支持。

        当我们使用 SNMP 时,我们通常理解一个好的超时值是三四秒,这意味着托管网络节点中的 SNMP 代理很可能在这段时间内完成了它的工作。

        HTH

        【讨论】:

          【解决方案5】:

          看看TFTP protocol。它是一种基于 UDP 的文件传输协议,具有内置的 ack/resend 规定。

          【讨论】:

            猜你喜欢
            • 2012-04-29
            • 1970-01-01
            • 2013-03-22
            • 2015-03-05
            • 1970-01-01
            • 2010-10-22
            • 1970-01-01
            • 1970-01-01
            • 2011-08-26
            相关资源
            最近更新 更多