网络层数据报分片

      每种分组交换技术都对一个物理帧可传输的数据量规定了一个固定的上界。这种限制称为最大传输单元MTU。以太网的MTU是1500八位组,FDDI的MTU大约为4470八位组。

      互联网设计的主旨是隐藏底层网络技术,因此数据报的大小与物理网络限制越接近传输的资源利用率越高。TCP/IP选择了一种初始数据报大小的机制,在MTU较小的网络上把长数据报划分成更小的部分。此划分的过程称为分片,划分出来的小块称为数据报片。

      分片通常由路由器来完成。分片规则:选择最接近MTU的8倍数的八位组。不一定能保证能把数据报分成大小相同的片,组后一片往往比其他片小。

      在TCP/IP互联网中,一旦数据报分片后,每片都作为独立的数据报传输,直到到达目的站主机后才对他们进行重组。

      接收机器从收到初始片开始就启动一个重组计时器,若有分组到达之前超时,则丢弃所有已收到的分片。

      数据报首部中的标识、标志、片偏移三个字段用来控制数据报分片与重组。

 

      假如一个长数据报分片成n片,前n-1片数据报长度应该是等长的,最后一片与前面的等长或小于前面的分片长。末尾短的分片再加上标志位低2位的标志值,共同确认出分片是否接收完毕?分片传递的路径,到达的次序等都是无序的。以上确认分片接收完毕的确认方式冒似不严密!

 

  

### IP数据报分片例题解析 对于IP数据报分片的理解,可以借助具体的例子来加深印象。假设一台主机PC1向另一台主机PC4发送一个总长度为3500字节的IP数据报,其中首部长度字段值表示该头部占用了20字节(即二进制`1100`转换为十进制等于20),这意味着有效载荷大小为\(3500 - 20 = 3480\)字节[^2]。 由于以太网的最大传输单元(MTU)通常设置为1500字节,因此当遇到大于这个数值的数据包时就需要执行分片处理。考虑到每个IP分片都带有自己的20字节头部信息,实际可用于承载上层协议数据的空间就变成了\(1500 - 20 = 1480\)字节。但是因为分片后的片段除最后一个小于或等于8字节外都要保持8字节边界对齐的要求,所以这里我们取最接近但不超过1480的最大8字节倍数作为单个分片的有效负载尺寸,也就是1472字节(184*8)[^3]。 基于上述分析: - **第一个分片**:携带前1472字节的应用层数据加上20字节的IP头组成完整的1492字节分片; - 对剩余的部分重复相同的过程直到全部数据都被分配到各个分片之中; 具体来说,在这种情况下总共会产生三个分片: 1. 第一分片包含原始消息开头处的1472字节应用层数据以及标准的20字节IP头。 2. 第二分片同样装载着中间部分的另外1472字节应用层数据并附带相应的20字节IP头。 3. 最终形成的第三个小于其他两个的分片则负责传递剩下的\(3480-(1472\times2)=536\)字节应用层数据及其对应的20字节IP头。 至于各分片的具体属性设定如下所示: | 分片编号 | 片偏移 (Offset) | 更多碎片标志 (MF Flag) | | --- | --- | --- | | 1 | \( \frac{0}{8} = 0 \) | 1 | | 2 | \( \frac{1472}{8}=184 \) | 1 | | 3 | \( \frac{(1472+1472)}{8}=368 \) | 0 | 以上就是针对给定条件下的IP数据报分片过程描述。 ```python def calculate_fragments(total_payload, mtu=1500, ip_header_size=20): fragment_size = min(mtu - ip_header_size, total_payload) fragments = [] offset = 0 while total_payload > 0: current_fragment_size = min(fragment_size, max((fragment_size // 8 * 8), 8)) mf_flag = int(total_payload - current_fragment_size > 0) fragments.append({ 'size': current_fragment_size, 'offset': offset // 8, 'mf_flag': mf_flag }) total_payload -= current_fragment_size offset += current_fragment_size return fragments fragments_info = calculate_fragments(3480) for i, info in enumerate(fragments_info, start=1): print(f'Fragment {i}: Size={info["size"]}, Offset={info["offset"]}, MF_Flag={info["mf_flag"]}') ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值