除了最后一个分段外,每个分段必须包含8字节的数据的倍数。
分段偏移可以容纳8192(2^13)个单位,但数据报的大小不能达到8192 * 8 = 65536字节,因为IP头部的"总长度"字段记录了包括头部和数据在内的总大小。
IP头部至少有20字节长,因此"分段偏移"的最大值被限制为8189,这样就为最后一个分段留出3个字节的空间。
希望这会有所帮助。
我并没有从其他答案中获得太多好处。它们似乎只是在次要地解释另一个他们看到的问题,而不是真正的问题。这里是真正的答案:
消息长度字段中的比特数与片段字段中的比特数不同。
[ Length ] <-- 16 bits
[ Flag ][ Fragment ] <-- 3 bits + 13 bits
当发送大数据包时,它会被分成多个片段,所以您需要标记片段并跟踪该片段中消息的部分,并在所有片段到达时将其按顺序放回。您有13位来描述片段的顺序。长度是一个16位整数,因此其容量(16位)为2^16-1
= 65536-1
= 65535
。这给您提供了65535个不同的字节,因此IP消息最多可以长达65535个字节。
理想情况下,我们希望以与长度相同的单位度量片段,即字节。
但是片段只有13位!
他们希望保持片段偏移量的度量单位为字节,因此他们必须想办法将16位装入13位中。他们发明了一种奇怪的位映射方法:
他们意识到,对于每少一个用于表示其最大数字的比特的数字(例如,从16位减少到15位,例如),您可以拥有的唯一索引数量除以2。 15位只能表示2^15-1
= 32768-1
= 32767
个唯一位置。14位 -> 再除以2; 13位 -> 再除以2。为了能够跟踪相同总字节数,它必须跳过某些字节并仅对每个2 ^ n
字节进行索引,其中n是从片段偏移值中去除的比特数。由于片段偏移量必须使用13,因此它会取走3位,因此它只能索引每8字节(2^3),因此索引是针对8字节块的。因此,8 *片段偏移量
用于计算每个片段的实际字节偏移量。
片段值是从第一个片段的第一个字节开始的偏移量。由于字节需要比索引更多的数据,因此出于某种奇怪的原因,他们决定以字节为度量单位而不是片段数量--即使字节需要比索引更多的数据。让片段偏移量成为index value(片段编号)可能更明智--但他们没有这样做!
这里 (https://cs.nyu.edu/courses/fall98/G22.2262-001/class11.txt) 给出了:片段偏移量以8字节(64位)为单位测量。这是因为片段偏移字段比总长度字段短3位,即16位(2 ^ 3为8)。