我读过许多关于UDP数据包大小的文章,但一直无法得出正确的结论。
许多服务将最大的UDP数据包限制在512字节(如dns)
假定internet上的最小MTU是576,IPv4报头的大小是20字节,UDP报头的大小是8字节。这就为用户数据留下了548个字节可用
我是否能够使用548大小的数据包而不产生数据包碎片?或者DNS的创造者知道一些事情,这就是为什么他们把它限制在512字节。
我能安全的把数据设置在548字节以上吗?
我读过许多关于UDP数据包大小的文章,但一直无法得出正确的结论。
许多服务将最大的UDP数据包限制在512字节(如dns)
假定internet上的最小MTU是576,IPv4报头的大小是20字节,UDP报头的大小是8字节。这就为用户数据留下了548个字节可用
我是否能够使用548大小的数据包而不产生数据包碎片?或者DNS的创造者知道一些事情,这就是为什么他们把它限制在512字节。
我能安全的把数据设置在548字节以上吗?
当前回答
UDP报文的最大大小的理论限制(Windows)是65507字节。这是记录在这里:
正确的UDP消息最大大小是65507,由以下公式确定: 0xffff -(sizeof(IP头)+ sizeof(UDP头))= 65535-(20+8)= 65507
也就是说,大多数协议限制的大小要小得多——通常是512或偶尔是8192。如果你在一个可靠的网络上,你通常可以安全地超过548,但如果你在整个互联网上广播,你的频率越大,你就越有可能遇到数据包传输问题和丢失。
其他回答
UDP最大安全负载是508字节。这是一个576(“最小最大重组缓冲区大小”)的数据包大小,减去最大60字节的IP头和8字节的UDP头。
任何这种大小或更小的UDP有效载荷都保证可以通过IP传递(尽管不保证传递)。任何更大的值都允许被任何路由器以任何理由直接丢弃。只有ipv6路由例外,ipv6路由最大负载为1212字节。正如其他人所提到的,在某些情况下可以添加额外的协议头。更保守的大约300-400字节的值可能是首选的。
最大可能的UDP负载是67 KB,分成45个IP包,增加额外的900字节开销(IPv4, MTU 1500,最小20字节IP头)。
任何UDP报文都可能被分片。但这并不太重要,因为丢失一个片段与丢失一个未分片的数据包具有相同的影响:整个数据包被丢弃。使用UDP,这将发生任何一种方式。
IP报文中包含一个分片偏移字段,表示UDP分片相对于其UDP报文的字节偏移量。该字段是13位的,允许8192个值,这些值以8字节为单位。所以IP包可以引用的偏移量范围是0…65528字节。作为偏移量,我们为最后一个UDP片段添加1480,得到67,008。减去第一个片段中的UDP头,我们得到了一个漂亮的约67 KB。
来源:RFC 791, RFC 1122, RFC 2460
本文介绍了最大传输单元(MTU) http://en.wikipedia.org/wiki/Maximum_transmission_unit。它规定IP主机必须能够处理576字节的IP数据包。然而,它指出,最低是68。RFC 791:“每个互联网模块必须能够转发一个68字节的数据报,而不会产生进一步的碎片。这是因为一个互联网报头可能高达60个字节,而最小的片段是8个字节。”
因此,安全数据包大小508 = 576 - 60 (IP头)- 8 (udp头)是合理的。
正如user607811所提到的,其他网络层的碎片必须重新组合。 https://www.rfc-editor.org/rfc/rfc1122#page-56 3.3.2重新组装 IP层必须实现IP数据报的重组。 我们指定可以重新组合的最大数据报大小 通过EMTU_R(“有效MTU接收”);有时候 称为“重组缓冲区大小”。EMTU_R必须更大 大于或等于576
考虑到IPV6的大小为1500,我认为运营商不会为IPV4和IPV6提供单独的路径(它们都是不同类型的IP),迫使它们使用旧的、冗余的、维护成本更高、可靠性更低的IPV4设备。这没有任何意义。此外,这样做可能很容易被认为是为某些流量提供优惠待遇——在他们可能不太关心的规则下(除非他们被抓住),这是不允许的。
因此,1472对于外部使用应该是安全的(尽管这并不意味着像DNS这样的应用程序不知道EDNS将接受它),如果你谈论的是内部网络,你更可能知道你的网络布局,在这种情况下,巨型数据包大小适用于非碎片数据包,因此对于4096 - 4068字节,对于英特尔卡的9014字节缓冲区,包大小为…… 等待……8086字节,是最大的…巧合吗?窃笑
* * * * * * * *更新
各种答案给出软件供应商允许的最大值或假设封装的各种答案。用户并没有要求尽可能低的值(比如安全的UDP大小为“0”),而是要求最大的安全数据包大小。
各个层的封装值可以被多次包含。因为一旦封装了一个流,就没有什么可以禁止的了,比如说,在它下面有一个VPN层,在它上面有一个完全复制的封装层。
由于这个问题是关于最大安全值的,我假设他们谈论的是可以接收的UDP数据包的最大安全值。由于没有UDP数据包是保证的,如果你收到一个UDP数据包,最大的安全大小将是IPv4上的1个数据包或1472字节。
注意——如果你使用IPv6,最大大小将是1452字节,因为IPv6的报头大小是40字节,IPv4是20字节(无论哪种方式,仍然必须允许8字节的UDP报头)。
I've read some good answers here; however, there are some minor mistakes. Some have answered that the Message Length field in the UDP header is a max of 65535 (0xFFFF); this is technically true. Some have answered that the actual maximum is (65535 - IPHL - UDPHL = 65507). The mistake, is that the Message Length field in the UDP Header includes all payload (Layers 5-7), plus the length of the UDP Header (8 Bytes). What this means is that if the message length field is 200 Bytes (0x00C8), the payload is actually 192 Bytes (0x00C0).
固定不变的是IP数据报的最大大小是65535字节。这个数字是L3和L4报头加上5-7层有效载荷的总和。IP头+ UDP头+层5-7 = 65535(最大)。
UDP数据报的最大大小最正确的答案是65515字节(0xFFEB),因为UDP数据报包括UDP头。UDP有效载荷最大大小的最正确答案是65507字节,因为UDP有效载荷不包括UDP头。
UDP不是“安全的”,所以问题不是很大-然而-
如果你使用的是Mac,默认情况下你可以发送的最大大小是9216字节。 如果你在Linux (CentOS/RedHat)或Windows 7上,最大是65507字节。
如果你发送9217或更多(mac)或65508+ (linux/windows),套接字发送函数返回一个错误。
上面讨论碎片和MTU等问题的答案是跑题的——所有这些都发生在较低的级别,对你来说是“看不见的”,并且在很大程度上不会影响典型连接的“安全性”。
要回答实际的问题,不要使用UDP,使用原始套接字,这样你就可以更好地控制一切;因为你是在编写一款游戏,所以你需要深入研究标志以获得流量的优先级,所以你也可以同时摆脱UDP问题。