zoukankan      html  css  js  c++  java
  • IP分片浅析

    在TCP/IP分层中,数据链路层用MTU(Maximum Transmission Unit,最大传输单元)来限制所能传输的数据包大小,MTU是指一次传送的数据最大长度,不包括数据链路层数据帧的帧头,如以太网的MTU为1500字节,实际上数据帧的最大长度为1512字节,其中以太网数据帧的帧头为12字节。

    当发送的IP数据报的大小超过了MTU时,IP层就需要对数据进行分片,否则数据将无法发送成功。

    IP分片的实现

    IP分片发生在IP层,不仅源端主机会进行分片,中间的路由器也有可能分片,因为不同的网络的MTU是不一样的,如果传输路径上的某个网络的MTU比源端网络的MTU要小,路由器就可能对IP数据报再次进行分片。而分片数据的重组只会发生在目的端的IP层。

    在IP首部有4个字节是用于分片的,如下图所示。前16位是IP数据报的标识,同一个数据报的各个分片的标识是一样的,目的端会根据这个标识来判断IP分片是否属于同一个IP数据报。中间3位是标志位,其中有1位用来表示是否有更多的分片,如果是最后一个分片,该标志位为0,否则为1。后面13位表示分片在原始数据的偏移,这里的原始数据是IP层收到的传输的TCP或UDP数据,不包含IP首部。

    标志字段:占16比特。用来唯一地标识主机发送的每一份数据报。通常每发一份报文,它的值会加1。就是IPID
    三个标志位的含义:
    R:保留未用;
    DF:Don’t Fragment,“不分片”位,如果将这一比特置1,IP 层将不对数据报进行分片;相反把数据报丢弃并发送一个I C M P差错报文并通知源主机废弃的原因
    MF:More Fragment,“更多的片”,除了最后一片外,其它每个组成数据报的片都要把比特置1;
    Fragment Offset:该片偏移原始数据包开始处的位置。偏移的字节数是该值乘以8。

    需要注意的,在分片的数据中,传输层的首部只会出现在第一个分片中,如下图所示。因为传输层的数据格式对IP层是透明的,传输层的首部只有在传输层才会有它的作用,IP层不知道也不需要保证在每个分片中都有传输层首部。所以,在网络上传输的数据包是有可能没有传输层首部的。

    避免IP分片

    在网络编程中,我们要避免出现IP分片,那么为什么要避免呢?原因是IP层是没有超时重传机制的,如果IP层对一个数据包进行了分片,只要有一个分片丢失了,只能依赖于传输层进行重传,结果是所有的分片都要重传一遍,这个代价有点大。由此可见,IP分片会大大降低传输层传送数据的成功率,所以我们要避免IP分片。

    对于UDP包,我们需要在应用层去限制每个包的大小,一般不要超过1472字节,即以太网MTU(1500)—UDP首部(8)—IP首部(20)。

    对于TCP数据,应用层就不需要考虑这个问题了,因为传输层已经帮我们做了。在建立连接的三次握手的过程中,连接双方会相互通告MSS(Maximum Segment Size,最大报文段长度),MSS一般是MTU—IP首部(20)—TCP首部(20),每次发送的TCP数据都不会超过双方MSS的最小值,所以就保证了IP数据报不会超过MTU,避免了IP分片。

    IP分片实例

    1. UDP

    从10.224.142.166向10.137.133.101发送3000字节的UDP数据,抓包的结果如下图。从图中可以看到这个UDP数据包被分成了3个IP片,从各分片的偏移量可以看出,3片包含的UDP数据大小分别是1480、1480、48(加上UDP首部8个字节),各分片加上IP首部的大小分别就是1500、1500、68,传送的总的UDP数据大小为3008,由此也看出只有一个分片包含UDP首部。

    2. TCP

    从10.224.142.166向10.137.133.101发送2000字节的TCP数据,抓包的结果如下图。从图中可以看出TCP数据被分成了2个IP片,包含的数据大小分别为1448、552,从三次握手可以看出双方通告的MSS都是1460字节,刚好是MTU(1500)—IP首部(20)—TCP首部(20),但实际为什么第一个分片只发送了1448字节呢,个人觉得应该是TCP首部还有一些选项占用了12个字节,也请知道的达人解释一下。

  • 相关阅读:
    为什么qt成为c++界面编程的第一选择 老夏课堂
    升级 package.json 内所有包的版本号
    小米 pro 双硬盘设置引导盘
    react 疑问集锦
    jmeter 基础使用
    vmware ubuntu 看不到网卡或连接不到网络
    如何在 Windows 11 使用旧的(或完整的)右键菜单
    hbuilder x 连接夜神模拟器
    当初为什么报 软件工程 这个专业?
    sparky 一个趋势图的JavaScript插件
  • 原文地址:https://www.cnblogs.com/diegodu/p/4647644.html
Copyright © 2011-2022 走看看