我读了许多关于UDP数据包大小的文章,但无法得出正确结论。
许多服务限制最大的UDP数据包为512字节(如DNS)。
考虑到互联网上的最小MTU为576,IPv4头部大小为20字节,UDP头部大小为8字节。因此,还剩下548字节可用于用户数据。
如果不需要分片,我是否能够使用大小为548的数据包?或者是DNS创建者知道的某些问题,这就是为什么他们将其限制为512字节。
甚至可以安全地超过548字节吗?
我读了许多关于UDP数据包大小的文章,但无法得出正确结论。
许多服务限制最大的UDP数据包为512字节(如DNS)。
考虑到互联网上的最小MTU为576,IPv4头部大小为20字节,UDP头部大小为8字节。因此,还剩下548字节可用于用户数据。
如果不需要分片,我是否能够使用大小为548的数据包?或者是DNS创建者知道的某些问题,这就是为什么他们将其限制为512字节。
甚至可以安全地超过548字节吗?
576是“最小最大重组缓冲区大小”,即每个实现必须能够重组至少这个大小的数据包。详见IETF RFC 1122。
IPv4的最小重组缓冲区大小为576,IPv6则为1500。从这里减去报文头大小。详见UNIX网络编程(W. Richard Stevens著) :)
512 是您最佳的选择。它在其他地方也被使用,并且是一个漂亮的偶数(1024 的一半)。
因此,任何大于互联网协议最小限制的数据包都有可能因为在传输途中“隐形”地被临时封装到略高于极限的大小而被分段,即使您选择了最小的UDP负载,其大小将为:576-8(UDP头)-20(IPv4)或40(IPv6)=最小528(如果您不确定使用的是v4还是v6)。
避免分段的原因之一是它会增加整个数据包完全丢失的可能性。更多的数据包,仅仅由于更高的开销,就意味着更大的失败可能性,更不用说每个数据包(甚至是一个分段)都代表着另一个“丢失”的机会。当然,如果该数据包恰好被传递到某个因为过大而丢弃它的链路上...
操作系统层面的TCP实现会尝试在TCP层面内选择最高安全MTU,包括动态处理其有时候的变化,因为源和目的地之间的路径的某些部分可能会逐个数据包不同。不幸的是,UDP 头本身就占用了 8 个字节……这意味着,唯一可以 确定地 避免分段的 UDP 数据负载大小是零!(并且只能适合于最小可能的 IPv6 数据包)。
最好 / 合理的做法可能是为您的 UDP 数据报使用 512,并自己检查数据是否在数据报内按顺序传输以及处理到达顺序错误的数据包。(即,不要完全依赖 IP 来为您删除损坏的数据包)。