【问题标题】:udp file transfer project - is error checking necessary?udp 文件传输项目 - 是否需要错误检查?
【发布时间】:2013-02-04 10:05:52
【问题描述】:

我被赋予了使用 UDP 传输文件的经典任务。在不同的资源上,我已经阅读过检查数据包的错误(在数据包中添加 CRC)是必要的,并且 UDP 已经检查损坏的数据包并丢弃它们,所以我只需要担心重新发送丢弃的数据包。

哪一个是正确的?是否需要手动对到达的数据包进行完整性检查,或者不正确的数据包已经被丢弃?

顺便说一下,该项目的语言是 Java。

编辑:一些来源(课程书籍、互联网)说校验和仅涵盖标头,因此确保发送方和接收方 IP 是正确的等。一些来源说校验和 涵盖数据段。一些消息来源说校验和可能覆盖数据段,但它是可选的,由操作系统决定。

编辑 2:问我的教授,他们说数据段的 UDP 错误检查在 IPv4 中是可选的,在 IPv6 中是默认的。但我仍然不知道它是否在程序员的控制,或操作系统,或其他层......

【问题讨论】:

    标签: java file udp protocols transfer


    【解决方案1】:

    UDP 协议使用与 TCP 协议相同的策略来检查包含错误的数据包 - 数据包标头中的 16 位校验和。

    UDP 数据包结构众所周知(与 TCP 一样),因此如果不加密,数据包很容易被篡改,添加另一个校验和(例如 CRC-32)也会使其更加健壮。如果目的是加密数据(手动或通过 SSL 通道),我不会费心添加另一个校验和。

    请注意一个数据包可以发送两次。确保您相应地处理。

    您可以在 Wikipedia 上查看两个数据包结构,两者都有校验和:

    您可以更详细地检查 TCP 数据包结构,以获取有关如何处理丢弃数据包的提示。 TCP 协议为此使用“序列号”和“确认号”。

    我希望这会有所帮助,祝你好运。

    【讨论】:

      【解决方案2】:

      第一个事实:

      UDP 有一个 16 位校验和字段,从数据包头的第 40 位开始。这有(至少)两个弱点:

      • 校验和不是强制性的,所有设置为 0 的位都定义为“无校验和”
      • 这是一个严格意义上的 16 位校验 -sum,因此容易受到未检测到的损坏。

      这意味着,UDP 的内置校验和可能足够可靠,也可能不够可靠,具体取决于您的环境。

      第二个事实:

      比传输过程中的数据损坏更现实的威胁是数据包丢失重新排序:USP 不保证

      • 所有要(最终)到达的数据包
      • 以与发送相同的顺序到达的数据包

      确实,UDP 根本没有内置机制来处理大于单个数据包的有效负载,这是因为它不是为此而构建的。

      结论:

      在没有额外措施的情况下在接收到的数据包后附加数据包必然会产生与发送流不同的接收流,但在最有利的环境中除外。这使其不是直接文件传输的最佳协议。

      如果您确实想要或必须使用 UDP 来传输文件,您需要构建这些部分,它们是 TCP 不可或缺的部分,而不是 UDP 到应用程序中的一部分。不过有一种说法,这很可能会导致 TCP 的重新实现效果不佳。

      成功的实施包括许多对等文件共享协议,其中防止连接中断和数据包丢失或重新排序需要成为应用程序功能的一部分,以击败或减轻过滤器。

      实施建议:

      对我们有用的是分块窗口实现:有效负载被分成固定且方便长度的块,(我们使用 1023 字节)在发送端和接收端保存 N 个这样的块的状态数组。

      发送方:

      • 发起一个 UDP 消息,其中包含这样的块、其在流中的序列号(不止一次)以及校验和或哈希。
      • 状态数组将此块标记为“已发送/待处理”并带有时间戳
      • 如果完整的状态数组(发送窗口)被消耗,发送停止

      在接收方:

      • 收到的数据包会根据它们的校验和进行检查,
      • 如果序列号的所有副本都一致,则损坏的数据包被否定确认,否则丢弃
      • OK 数据包在状态数组中标记为“已接收/待处理”并带有时间戳
      • 如果已接收到足够的块来填充 ack 数据包,或者最旧的“接收/待处理”的时间戳变得太旧(从几毫秒到大约 100 毫秒),则通过发送一个 ack 数据包来进行确认。
      • Ack 数据包需要校验和,但不需要排序。
      • 已发送 ack 的块在状态数组中标记为“ack/pending”并带有时间戳

      发送方:

      • 收到并检查确认数据包,丢弃损坏的数据包
      • 收到 ack 的块在状态数组中被标记为“ack/done”
      • 如果状态数组中的第一个块被标记为“确认/完成”,则状态数组会向上滑动,直到它的第一个块再次未完成。
      • 这可能会释放一个或多个待发送的未发送块。
      • 对于处于“已发送/待处理”状态的块,时间戳超时会触发该块的新发送,因为原始块可能已丢失。

      在接收方:

      • 接收块 i+N(N 是窗口宽度)将块 i 标记为 ack/done,向上滑动接收窗口。如果不是所有滑出接收窗口的块都被标记为“ack/pending”,这构成了一个不可恢复的错误。
      • 对于状态为“ack/pending”的块,时间戳超时会触发该块的新确认,因为原始确认消息可能已丢失。

      显然,发送端需要一个特殊的消息类型,如果发送窗口滑出文件的末尾,表示接收到一个 ack 而不发送块 N+i,我们通过简单地发送 N 来实现它块多于存在,但没有有效负载。

      【讨论】:

      • 这正是我所说的:...使其不是直接文件传输的最佳协议 amd 这很可能会导致重新实现TCP。我的实施建议从 如果您确实想要或必须使用 UDP 开始,所以我完全支持您。 1.你应该使用TCP,2.只有当你必须使用UDP,然后...
      • 感谢您的详尽回答。这种方法是否称为“返回 N ARQ”?
      【解决方案3】:

      您可以确定您收到的数据包与发送的数据包相同(即,如果您发送数据包 A 和接收数据包 A,您可以确定它们是相同的)。对数据包的传输层 CRC 检查确保了这一点。但是,由于 UDP 不保证交付,因此您需要确保收到所有发送的内容,并且需要确保正确订购。

      换句话说,如果数据包 A、B 和 C 按顺序发送,您实际上可能只收到 A 和 B(或没有)。您可能会使它们乱序,C、B、A。因此,您的检查需要注意 TCP 提供的保证交付方面(验证排序,确保所有数据都在那里,并通知服务器重新发送您没有发送的任何内容) t 接收)你需要的任何程度

      首选 UDP 而不是 TCP 的原因是,对于某些应用程序而言,数据排序和数据完整性都不重要。例如,当流式传输 AAC 音频数据包时,单个音频帧非常小,以至于可以安全地丢弃其中的一小部分或乱序播放,而不会在很大程度上破坏聆听体验。如果 99.9% 的数据包被正确接收和排序,你可以很好地播放流并且没有人会注意到。这适用于某些蜂窝/移动应用程序,您甚至不必担心重新发送丢失的帧(请注意,在某些情况下,Shoutcast 和其他一些服务器确实使用 TCP 进行流传输 [以促进带内元数据],但它们不'不必)。

      如果您需要确保所有数据都在那里并且正确排序,那么您应该使用 TCP,它将负责验证数据是否都在那里,正确排序,并在必要时重新发送。

      【讨论】:

      • 没问题,我很高兴能提供帮助。谢谢你的赏金!
      • 我认为这个答案只是关于 TCP 和 UDP 的一般信息(可以在每本网络书籍或互联网上找到),而不是我问题的确切答案。我问UDP是否提供数据错误检查。
      • “数据”是什么意思?我的回答澄清了 UDP 协议基于每个数据包提供完整性检查,但仅此而已。有效负载完整性检查,这意味着 UDP 不提供多个数据包的聚合数据。聚合数据完整性涉及正确排序接收到的数据包并确保所有数据包都已到达给定的有效负载。 TCP 会这样做,UDP 不会。
      • 顺便说一句,您的问题表明您已获得“通过 UDP 传输文件的经典任务”。 UDP适合文件传输。为此,您应该使用 TCP,否则您将只是尝试重新实现 TCP。
      • 通过短语“通过 UDP 传输文件的经典任务”。我的意思是,对于 CS 学生来说,这是一个非常常见的学校项目。目的是重新发明 TCP 轮子,可能有点不同。
      【解决方案4】:

      UDP 将丢弃不符合内部每个数据包校验和的数据包; CRC 检查有助于在应用层确定,一旦有效负载看起来完整,接收的内容是否实际完整(没有丢弃的数据包)并且与发送的内容匹配(没有中间人或其他攻击) .

      【讨论】:

      • 澄清一下,应用层的 CRC 检查应该在有效载荷上进行,以确保数据都在那里并且正确排序,而不是在单个数据包上。您不需要复制传输层的功能。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-08-18
      • 1970-01-01
      • 1970-01-01
      • 2021-07-11
      • 1970-01-01
      • 2016-09-26
      • 2011-06-12
      相关资源
      最近更新 更多