首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >udp文件传输项目-是否需要错误检查?

udp文件传输项目-是否需要错误检查?
EN

Stack Overflow用户
提问于 2013-02-19 16:24:05
回答 4查看 2.3K关注 0票数 5

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

哪一个是对的?我是否需要手动对到达的数据包执行完整性检查,还是已经丢弃了不正确的数据包?

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

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

编辑2:我的教授问我,他们说在IPv4中UDP错误检查是可选的,在IPv6中是默认的。但我还是不知道它是在程序员的控制下,还是操作系统的,还是另一层.

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-04-02 18:13:32

第一个事实:

UDP具有从分组报头的位40开始的16位校验和字段。这方面存在(至少)两个弱点:

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

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

第二个事实:

在传输过程中,一个比数据分离更现实的威胁是分组丢失重新排序: USP没有保证

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

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

结论:

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

如果需要或必须使用UDP来传输文件,则需要构建这些部分,这些部件是TCP的组成部分,而不是应用程序中的UDP。不过,有句话说,这很可能导致TCP的重新实现。

成功的实现包括许多对等文件共享协议,在这些协议中,对于连接中断和数据包丢失或重新排序的保护需要成为筛选功能的一部分,以击败或减轻过滤器。

执行建议:

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

在发送方:

  • UDP消息被初始化,包含这样的块、流中的序列号(不止一次)和校验和或散列。
  • 状态数组使用时间戳将此块标记为“已发送/挂起”。
  • 如果使用了完整的状态数组(发送窗口),则停止发送。

在接收方:

  • 接收到的数据包与它们的校验和一起检查,
  • 如果序列号的所有副本一致,则被破坏的数据包将被否定地确认,否则丢弃。
  • 确定数据包在状态数组中标记为“接收/挂起”,并带有时间戳。
  • 如果接收到足够多的块来填充ack数据包,或者最老的“接收/挂起”的时间戳太老(有些ms到大约100 ms),则确认可以通过发送ack数据包来工作。
  • Ack数据包需要校验和,但不需要排序。
  • 已发送ack的块被标记为“ack/未决”,状态数组中有时间戳。

在发送方:

  • 接收并检查Ack数据包,丢弃损坏的数据包。
  • 接收到ack的块在状态数组中标记为"ack/done“。
  • 如果状态数组中的第一个块标记为"ack/ done ",则状态数组将向上滑动,直到它的第一个块再次没有完成。
  • 这可能会释放要发送的一个或多个未发送的块。
  • 对于状态为“发送/挂起”的块,时间戳上的超时将触发对此块的新发送,因为原始块可能已经丢失。

在接收方:

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

显然,需要从发送端发出一种特殊的消息类型,如果发送窗口滑出文件的末尾,以信号接收一个ack而不发送块N+i,我们只需发送N个块而不是现有的,但是没有负载。

票数 4
EN

Stack Overflow用户

发布于 2013-04-02 17:45:31

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

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

选择UDP而不是TCP的原因是,对于某些应用程序来说,数据排序和数据完整性都不重要。例如,当流AAC音频分组时,单个音频帧非常小,因此可以安全地丢弃或播放其中的少量音频帧,而不会在任何程度上破坏听力体验。如果99.9%的数据包被正确接收和订购,您可以很好地播放流,没有人会注意到。对于某些蜂窝/移动应用程序来说,这很好,您甚至不必担心重发丢失的帧(请注意,Shoutcast和其他一些服务器确实在某些情况下使用TCP进行流传输,以方便带内元数据,但它们不必这样做)。

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

票数 2
EN

Stack Overflow用户

发布于 2013-04-02 18:21:24

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

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

请也考虑到一个包可以发送两次。确保你能相应地处理这件事。

您可以在Wikipedia上检查这两种数据包结构,它们都有校验和:

  • 传输控制协议
  • 用户数据报协议

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

希望这能帮上忙,祝你好运。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14962342

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档