为什么ip片段必须是8个字节的倍数

use*_*482 9 ip networking

在教科书计算机网络 James F.Kurose Fifth Ed,ch4中提到过

的IP片段必须是8个字节的倍数,并且由于标志IP报头中需要3个比特.我不明白为什么ip碎片必须是8个字节的倍数.

Leg*_*989 13

除最后一个之外的每个片段必须包含8个字节数据的倍数.

片段偏移可以容纳8192(2 ^ 13)个单位,但数据报不能有8192*8 = 65536个字节的数据,因为IP头的"总长度"字段记录包括标题和数据的总大小.

IP报头长度至少为20个字节,因此"Fragment Offset"的最大值限制为8189,这为最后一个片段留出了3个字节的空间.

希望这可以帮助.

  • 谢谢你回答@Wayne Shears,正如你所说:Fragment Offset可以容纳8192(2 ^ 13)个单位[**什么是平均单位?你的意思是字节?**]但数据报不能有8192*8 = 65536字节数据[**为什么?**]因为IP头的"总长度"字段记录了包括标题和数据的总大小[**我所知道的是总长度=标题大小+有效负载.并且总legth是16,所以值将达到2 ^ 16,这是65536,我认为有什么不对吗?**]. (2认同)

Rya*_*yan 7

我没有从这里的其他答案中获得太多好处。他们似乎只是顺便触及真正的问题,同时试图解释他们看到的另一个问题,所以这是真正的答案:

消息长度字段中的位数与片段字段中的位数不同。

[        Length        ] <-- 16 bits
[ Flag ][   Fragment   ] <-- 3 bits + 13 bits
Run Code Online (Sandbox Code Playgroud)

消息长度字段测量整个消息以及该消息的所有片段

发送大数据包时,它会被分成多个片段,因此您需要标记片段并跟踪该片段中的消息部分,并在所有片段到达时将其恢复顺序。您将获得 13 位来描述片段序列。长度是一个16位整数,所以它的容量(16位)是2^16 - 1== 。这为您提供了 65535 个不同的字节,因此 IP 消息的长度最多为 65535 个字节。65536-165535

片段偏移量是字节的度量,但无法容纳消息中的字节数

理想情况下,我们希望以与Length相同的单位来测量片段,即字节

但我们只有 13 位用于 Fragment!

他们希望以字节为单位保存片段偏移量,因此必须想办法将 16 位装入 13 位。他们发明了一种奇怪的位映射来为他们做到这一点:

奇怪的位映射

他们意识到,数字每减少 1 位来表示其最大数字(例如,通过去掉一位,从 16 位降到 15 位),可以拥有的唯一索引的数量将除以 2 . 15位只能代表2^15 - 1==唯一32768-132767位置。14位-->再除以2;13 位 --> 再次除以 2。为了能够跟踪相同的总字节数,它必须跳过一些字节并仅对每个2^n字节进行索引,其中 n 是从片段偏移值中取出的位数。由于片段偏移量需要使用 13,因此它占用了 3 位,因此它只能每第 8 (2^3) 个字节进行索引,因此索引适用于 8 字节块。这样就8 * Fragment Offset可以计算每个片段的实际字节偏移量。

注意事项

片段值是距第一个片段的第一个字节的偏移量。由于某些奇怪的原因,他们决定以字节为单位来测量偏移量,而不是片段的数量——尽管字节需要比索引更多的数据。简单地使片段偏移量成为索引(片段编号)可能更聪明——但他们没有这样做!


Rur*_*rre 5

请注意,Fragment Offset 字段以 8 字节为单位表示,而不是字节。这就是为什么除了最后一个片段之外的每个片段内的有效负载大小必须是 8 字节的倍数的原因。

由于片段偏移量以 13 位编码,因此其范围在 0 到 8191 个 8 字节单位之间。但是,由于总长度还考虑了 IP 标头,因此片段偏移最大限制实际上是 8189 个单位,而不是 8191 个单位,请参见下文:

总长度以 16 位编码,这意味着它限制为 65535 字节。然后,由于 IP 标头至少为 20 字节,因此有效负载被限制为最大 65535 字节 - 20 字节 = 65515 字节。将这 65515 字节划分为 8 字节单元,结果最多可以有 8189 个单元,因此碎片偏移量限制为最大 8189 个单元。

片段偏移值设置为最大值 8189 的 IP 片段可以具有最大 3 个字节的有效负载:

最大 65535 字节 - 最小 20 字节 - (8189 个单元 * 每个单元 8 个字节) = 最大 3 个字节

鲁尔