我被赋予了使用UDP传输文件的经典任务。在不同的资源上,我看到了检查数据包上的错误(将CRC和数据一起添加到数据包)是必要的,UDP已经检查了损坏的数据包并丢弃了它们,所以我只需要担心重发丢弃的数据包。
哪一个是对的?我是否需要手动对到达的数据包执行完整性检查,还是已经丢弃了不正确的数据包?
顺便说一下,这个项目的语言是Java。
编辑:一些来源(教材,互联网)说校验和只覆盖标题,因此确保发送方和接收方IP是正确的等等。一些消息来源说校验和也涵盖了数据段。一些消息来源说校验和可能涵盖数据段,但它是可选的,由操作系统决定。
编辑2:我的教授问我,他们说在IPv4中UDP错误检查是可选的,在IPv6中是默认的。但我还是不知道它是在程序员的控制下,还是操作系统的,还是另一层.
发布于 2013-04-02 18:13:32
第一个事实:
UDP具有从分组报头的位40开始的16位校验和字段。这方面存在(至少)两个弱点:
这意味着,UDP的内置校验和可能足够可靠,也可能不够可靠,这取决于您的环境。
第二个事实:
在传输过程中,一个比数据分离更现实的威胁是分组丢失重新排序: USP没有保证
事实上,UDP根本没有内置机制来处理比单个数据包更大的有效负载,这是因为它不是为此而构建的。
结论:
在没有额外措施的情况下,在接收到的数据包之后,必然会产生一个与发送流不同的接收流,但在最有利的环境中除外。这使得它不是直接文件传输的最佳协议。
如果需要或必须使用UDP来传输文件,则需要构建这些部分,这些部件是TCP的组成部分,而不是应用程序中的UDP。不过,有句话说,这很可能导致TCP的重新实现。
成功的实现包括许多对等文件共享协议,在这些协议中,对于连接中断和数据包丢失或重新排序的保护需要成为筛选功能的一部分,以击败或减轻过滤器。
执行建议:
对我们有用的是块窗口实现:将有效负载分成固定和方便长度的块,(我们使用了1023字节)发送和接收端保留了N个这样的块的状态数组。
在发送方:
在接收方:
在发送方:
在接收方:
显然,需要从发送端发出一种特殊的消息类型,如果发送窗口滑出文件的末尾,以信号接收一个ack而不发送块N+i,我们只需发送N个块而不是现有的,但是没有负载。
发布于 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,它将负责验证数据是否都在,正确排序,并在必要时重发。
发布于 2013-04-02 18:21:24
UDP协议使用与TCP协议相同的策略来检查数据包中的错误--数据包报头中的16位校验和。
UDP数据包结构是众所周知的(以及TCP),因此如果不加密,可以很容易地篡改数据包,添加另一个校验和(例如CRC-32)也会使其更健壮。如果目的是加密数据(手动或通过SSL通道),我就不会再添加校验和了。
请也考虑到一个包可以发送两次。确保你能相应地处理这件事。
您可以在Wikipedia上检查这两种数据包结构,它们都有校验和:
您可以更详细地检查TCP数据包结构,以获得有关如何处理丢弃数据包的提示。为此,TCP协议使用“序列号”和“确认号”。
希望这能帮上忙,祝你好运。
https://stackoverflow.com/questions/14962342
复制相似问题