【UDP】 |
您所在的位置:网站首页 › udp数据分包 › 【UDP】 |
问题 一开始了解的是 DNS 服务使用的是 UDP 协议,后面看到 DNS 服务主要使用 UDP 协议,在少数情况(传输的数据超过 512 个字节)下也会使用 TCP 协议,因为 UDP 数据包不能超过 512 个字节。 那问题来了,为什么 UDP 数据包不能超过 512 个字节呢? 探索首先,对于传输层,即 UDP 数据包本身来说,Length 字段为 16 位,理论限制为 65535 字节(2^16 - 1),那么能传输的数据为 65535 - IPHeader(20) - UDPHeader(8) = 65507 字节。 其次,对于网络层,以太网规定 MTU 上限为 1500 字节(综合权衡的结果),如果按照 MTU = 1500 计算,那么 UDP 能传输的数据包上限为 MTU(1500) - IPHeader(20) - UDPHeader(8) = 1472 字节。 如果 UDP 数据包小于等于1472 个字节,那么正常发送不用分片如果 UDP 数据包超过 1472 个字节,那么移交网络层进行分片并在接收方进行重组这里补充一下 UDP 超过 1472 字节时的切片处理: 网络层并不会在每个分片里复制一次 UDP 头,它是把完整的 UDP 包切开,加上 IP 头发送出去,除了第一个分片有 UDP 头,后面的分片都不包含 UDP 头。 目的主机的网络层接收到多个 UDP 分片包后,网络层必须重组才能交给上层。因为多个分片包只有第一个是有 UDP 头的,它可以根据 UDP 头里的端口号通知相应的应用取走,但是后面的分片包由于没有 UDP 头,传输层无法把分片包交给正确的应用程序。所以 UDP 分片包必须在网络层重组成一个完整的 UDP 包,再交给传输层处理,耗费资源。 但如果某些分片包没有被目的主机的网络层接收到,造成 UDP 包重组失败,接收方会丢弃整个数据包,这是 UDP 不可靠传输的一个表现。而 TCP 发 生组包错误时,该包会被重传,保证可靠传输。 因此一般建议将 UDP 数据包限制在 1472 字节以下。但是呢,这个限制是在普通局域网(Ethernet v2)环境下的,在非局域网(X.25)环境下则有所不同。 因为 Internet 上的路由器可能会将 MTU 设为不同的值。如果我们假定 MTU 为 1500 字节来发送数据的,而途经的某个网络的 MTU 值小于 1500 字节,那么系统将会使用一系列的机制来调整 MTU 值,使数据报能够顺利到达目的地,这样就会做许多不必要的操作。 鉴于 Internet 上的标准 MTU 值为 576 字节(IPv4 标准规定,每个主机必须能够重新组装 576 字节或更少的数据包),所以建议在进行 Internet 的 UDP 编程时,最好将 UDP 的数据长度控件在 548 字节(MTU(576) - IPHeader(20) - UDPHeader(8))以内。 但这也还是 548 字节,并不是 512 字节。于是又搜索了一番,发现 StackOverflow 上有一个回答提到: 典型的 IPv4 头部是 20 字节,而 UDP 头部是 8 字节。然而,可以包括 IP 选项,该选项可以将 IP头部的大小增加到多达 60 字节(如图 1 所示)。 此外,有时中间节点需要将数据报封装在另一种协议(如IPsec(用于VPN等))中,以便将数据包路由到其目的地。 因此,如果不知道特定网络路径上的 MTU,最好为可能没有预料到的其他头部信息留出合理的余量。512字节的 UDP 有效载荷通常被认为可以做到这一点,尽管即使这样也没有为最大尺寸的 IP报头留下足够的空间。 图1,IPV4 头部字段,来源:Chapter 5. The Internet Protocol (IP) - Shichao's Notes。 通过这个回答我们可以知道,UDP 数据包的最大安全负载应该是 508 字节(MTU(576) - IPHeader(60) - UDPHeader(8)),因为 IP 头部最大时为 60 字节。512 也是一个综合考虑的结果。 总结总的来说,这些数值的限制就是各层之间综合权衡的结果,以在整体上达到最优传输效率。当然,还得提一下,上述讨论针对的是 IPV4,而非 IPV6。 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |