【计算机网络】区分tcp分段和ip分片

  • tcp分段和ip分片很多人搞不清楚,事实上两者代表的内容并不相同

  • 既然有了tcp分段为什么还要ip分片呢?tcp协议在网络上还会出现ip分片吗?

  • 什么是链路MTU?什么又是MSS?MTU和MSS都是有什么关联?分段和分片究竟有没有可能同时发生?

1.什么是TCP分段?

在学习TCP/IP协议时都知道,TCP协议是基于连接和流的传输协议,当需要传输的TCP报文很大的时候就会发生分段的操作,所谓TCP分段就是将需要传输的大TCP包切割成n个适合链路传输的小段,然后这些小段就称之为TCP分段,这些TCP分段达到目的端可以进行重组,重组后就会构成原来的大TCP包。

既然都指定了是TCP分段,那么很明显,TCP分段的操作发生于传输层,分段的操作只会在TCP协议中发生,同样为传输层的协议,UDP协议不会出现分段操作,只会出现ip分片的行为,具体原因可以见下文介绍

2.什么是IP分片

IP分片和分段行为不同,虽然也是对大数据包切割为n个小片,但是IP分片是工作在网络层,TCP协议和UDP协议的数据包在传输到网络层的时候均有可能发生IP分片的操作,但是IP分片和IP重组会影响数据传输的性能,所以一般情况基于TCP协议工作都会尝试避免IP分片。

这里你一定开始有了几个问题?

  • 什么情况会发生TCP分段和IP分片呢?

  • TCP协议如何避免IP分片?分段和分片会在TCP协议下同时工作吗?

  • UDP协议为什么没有分段操作,只有分片操作呢?

那么,带着问题继续了解下面的内容,能找到你想要的答案!

3.什么是MTU?

最大传输单元(Maximum Transmission Unit),即MTU,为数据链路层的最大载荷上限(即IP数据报最大长度),每段链路的MTU可能都不相同,一条端到端路径的MTU由这条路径上MTU最小的那段链路的MTU决定。

MTU是链路层中的网络对数据帧的一个限制,例如在以太网中,MTU通常为1500字节,如果采用巨帧(Jumbo Frame)时可以达到9000字节。所谓的MTU,是二层协议的一个限制,对不同的二层协议可能有不同的值,只有二层协议为以太网(Ethernet)时,MTU一般才取1500字节,注意它不是物理链路介质的限制,只有工作在二层的设备才需要指定MTU的值,如网卡、转发设备端口(统称为网络接口)等,通过同一段线缆直连的通信端口或网卡,其MTU值一定相同

一个IP数据报在以太网中传输,如果它的长度大于当前链路MTU值,就要进行分片传输(这里指IP层分片),保证每片数据报的长度都不超过MTU。另外需要明确一点的是,分片传输的IP数据报不一定按序到达,乱序的IP分片根据IP首部中的信息,能让这些数据报片按序重组。IP数据报的分片与重组是在网络上层完成的。

4.什么是MSS?

最大报文段长度(Maximum Segment Size),即MSS,为TCP传输层的最大载荷上限(即应用层数据最大长度),TCP三次握手期间通过TCP首部选项中的MSS字段通知对端,通常一条TCP连接的MSS取通信双方较小的那一个MSS值,与MTU的换算关系为:

MTU = MSS + TCP首部长度 + IP首部长度

故在以太网中(网络层以IPv4为例):

MSS = 以太网MTU - TCP首部长度 - IPv4首部长度 = 1500 - 20 - 20 = 1460字节

如果未指定MSS大小时默认值为536字节,这是因为在Internet中标准的MTU值为576字节576字节MTU = TCP首部长度20字节 + IPv4首部长度20字节 + 536字节MSS。

一个应用程序如果要发送超过MSS大小的数据,就要进行分段传输(这里指TCP分段),使得每个报文段长度都不超过MSS。分片传输的TCP报文段也是不一定按序到达,但TCP协议实现了可靠的机制保证乱序的处理,即利用报文段序列号在接收缓冲区进行数据重排以实现重组。TCP分段的重组是在TCP传输层完成的。

正常情况下,IP分片的重组会影响传输的性能,所以在TCP协议下通过保证 MSS<链路最小MTU来避免分片的发生,当MSS总是比MTU小的话,说明每一个分段都可以直接通过传输,但是当MSS>链路最小MTU,超过了传输载荷上线,所以就需要对TCP分段进行IP分片操作,也就是需要对当前的TCP分段切割为多个适合链路MTU传输的IP分片,所以说,分段和分片是会在TCP协议下同时工作的,除非你能保证在TCP三次握手协商的MSS恒小于链路最小MTU

5.分段和分片的发生时机

由上面可知,分段会发生在面向连接、提供可靠传输服务而具备各种复杂机制的TCP协议,但是UDP是简单至极的传输协议,属于不可靠的协议,UDP协议并不会自行分段,也没有所谓的握手操作,当然也就是没有所谓的MSS大小的协商,UDP协议传输数据是如果最终的IP数据报的长度超过了MTU时,就直接交付网络层执行IP分片。同样,(没有分段功能的)ICMP数据在网络层中同样会出现IP分片的情况。

IP分片不仅会发生在在使用UDP、ICMP等没有分段功能的传输层协议的数据发送方,更还会发生在传输途中,甚至有可能都会发生,这是因为原本的大数据报被分片后很可能会经过不同MTU大小的链路,一旦链路MTU大于当前IP分片大小,则需要在当前转发设备(如路由器)中再次分片,但是各个分片只有到达目的地后才会在其网络层重组,而不是像其他网络协议,在下一跳就要进行重组。

  • 分段操作可以说只会发生在TCP协议,其他的协议当IP数据包长度超过MTU,就会触发IP分片的发生

  • TCP分段协商的MSS小于链路最小MTU的时候,TCP分段到达网络层也会发生IP分片的操作

再次强调的点:

在发送端进行TCP分段后就一定不会在IP层进行分片,因为MSS本身就是基于MTU推导而来,TCP层分段满足了MSS限制,也就满足了MTU的物理限制。

但在TCP分段发生后仍然可能发生IP分片,这是因为TCP分段仅满足了通信两端的MTU要求,传输路径上如经过MTU值比该MTU值更小的链路,那么在转发分片到该条链路的设备中仍会以更小的MTU值作为依据再次分片。

当然如果两个通信主机直连,那么TCP连接协商得到的MTU值(两者网卡MTU较小值)就是端到端的路径MTU值,故发送端只要做了TCP分段,则在整个通信过程中一定不会发生IP分片。

例如下面展示的TCP三次握手:

TCP三次握手过程

客户端的网卡MTU设置为1500,服务端网卡MTU设置为1480,中间设备的网卡mtu均设置为1200,当客户端和服务端建立TCP连接的时候,通过三次握手建立连接,建立连接的过程通过wireshake抓包可知:

  • 客户端发起SYN包告诉自己可以接受的MSS=1460,即1500-20TCP报文头-20IP报文头

  • 服务端响应SYN+ACK包也告诉自己可以接受的MSS=1440,即1480-20TCP报文头-20IP报文头

  • 这个属于MSS协商的过程,MSS最终就会取最小的MSS作为连接彼此之间传输的大小,也就是TCP分段大小携带的数据为1440为准

  • 但是这个MSS=1440明显大于中间设备的MTU,所以,当出现大包传输的时候,虽然在C/S两段均只会出现TCP分段,但是在传输到中间设备的时候,通过比较MTU发现1440>1200,所以此时的TCP分段就会在中间设备发生IP分片,一个1440的TCP分段需要被切割为两个IP分片,然后进一步传输到目的端进行IP分片重组才能还原四层报文头,因为IP分片只有首片能访问到传输层的报文头,比如源和目的端口信息。

理论上的tcp分段在该拓补中是会发生IP分片的,但是当你实际搭建拓补并尝试抓包观察,你会发现mss的协商并不如上面所示,最终的mss大小也不是1440,而是1160,这是为什么呢?

其实,这属于mss的自我动态调整,是由Path MTU Discovery(路径mtu发现)机制提供的,它帮助我们发现初始协商的mss比链路中的mtu还大,因此,PMTU Discovery帮我们重新调整了合适的mss,保证mss < pmtu,避免了IP分片的发生,如果想要复现上面的实验,那你可以直接将Path MTU Discovery关闭,下一篇介绍如何搭建网络拓补使tcp分段基础下出现IP分片。因此,tcp分段和IP分片是有可能同时发生的!!!

6.TCP和UDP的分片对比

TCP和UDP均为传输层的协议,最大的不同就是TCP是可靠的协议,具备超时重传等保证可靠传输的机制,而UDP是不可靠的协议,也没有所谓的握手和挥手的操作,因此UDP协议自然也没有TCP协议在三次握手时的MSS协商过程,当UDP传输的数据超过MTU的时候,完全交付网络层直接进行IP分片。

另外,IP分片的传输过程是可能发生丢失的,当IP分片出现丢失的时候,不会重传丢失的IP片,而是会重传一整组的IP分片,这也是IP分片被诟病性能差的原因之一,TCP协议上层实现了超时重传机制,当某一个TCP分段包因为IP分片丢失,可以通过TCP协议要求重传IP分片,从而保证数据可靠性传输。

对于UDP,用UDP协议发送64k的数据,那么如果网络发生了波动,丢失了某个IP分片,它不会反馈丢失了哪个分片给发送方的能力,这就意味着:64k的数据全都丢失了,如果需要重传,就得再次完整的传递这64K数据,因此一般使用UDP协议传输也会避免传输巨大数据,特意控制下单个包体的大小,从而提高传输效率。防止不可靠的性质导致频繁重传。

7.IP报文解析

当IP数据报的长度超过帧的MTU时,会被分片传输。分片可能发生在发送端,也可能发生在中转路由器上,而且可能在传输过程中被多次分片,但只有在最终的目标机器上,这些分片才会被内核中的IP模块重新组装。

IP头部中的三个字段给IP的分片和重组提供了足够的信息:数据报标识、标志和片偏移

一个数据报的每个分片都具有自己的IP头部,它们具有相同的标识值,但具有不同的片偏移。并且除了最后一个分片外,其他分片都将设置MF标识。此外,每个分片的IP头部的总长度字段将被设置为该分片的长度。

IPv4头部结构如下图,其长度通常为20字节,除非含有可变长的选项部分。

IPV4的IP报文

  • 4位版本号(version):指定IP协议的版本,对IPv4来说,值=4。

  • 4位头部长度(header length):标志该IP头部有多少个32bit(4字节)。英文4位最大能表示15,所以IP头部最长位为60字节。

  • 8位服务类型(Type Of Service,TOS):包括一个3位的优先权限字段(现在已经被忽略),4位的TOS字段和1位保留字段(必须置0)。4位的TOS字段分别表示:最小延时、最大吞吐量、最高可靠性和最小费用。一种最多有一个能置为1,应用程序应该根据实际需求来设置它。比如像ssh和telent这样的登录程序需要的是最小延时的服务,而文件传输程序ftp则需要最大吞吐量的服务。

  • 16位总长度(total length):是指整个IP数据报的长度,以字节为单位,以此IP数据报的最大长度为65535字节。但由于MTU的限制,长度超过MTU的数据报将被分片传输,所以实际传输的IP数据报(或分片)的长度都远远没有达到这个最大值。接下来的3个字段则描述了如何实现分片。

  • 16位标志(identification):唯一标志主机发送的每一个数据报。其初始值由系统随机生成,每发送一个数据报,其值就加1。该值在数据分片时,被复制到每个分片中,因此同一个数据报的所有分片都具有相同的标识值。

  • 3位标识字段的第一位保留。第二位Don't Fragement,DF表示“禁止分片”。如果设置了这个位,IP模块将不对数据报进行分片。在这种情况下,如果IP数据报长度超过MTU的话,IP模块将丢弃该数据报并返回一个ICMP差错报文。第三位More Fragment,MF表示“更多分片”。除数据报的最后一个分片外,其他分片都要把它置1。

  • 13位分片偏移(fragmentation offset):分片相对原始IP数据报开始处(仅指数据部分)的偏移。实际的偏移值时该值左移3位(乘8)后得到的。由于这个原因,除了最后一个IP分片外,每个IP分片的数据部分的长度必须是8的整数倍(这样才能保障后面的IP分片拥有一个合适的偏移值)。

  • 8位生存时间(Time To Live,TTL):数据报到达目的地之前允许经过的路由器跳数。TTL值被发送端设置(常见的值是64).数据报在转发过程中没经过一个路由,该值就被路由器减1。当TTL值减为0时,路由器将丢弃数据报,并向源端发送一个ICMP差错报文。TTL值可以防止数据报陷入路由循环。

  • 8位协议(protocol):区分上层协议。/etc/protocls文件定义了所有上层协议对应的protocol字段数值。其中,ICMP=1,TCP=6,UDP=17

  • 16位头部校验和(header checksum):由发送端填充,接收端对其使用CRC算法以检验IP数据报头部(注意,仅检验头部)在传输过程中是否损坏。
    32位源端IP地址和目的端IP地址用来标识数据报的发送端和接收端。一般情况下,这两个地址在整个数据报的传递中保持不变,而不论它中间经过多少个中转路由器。

  • 选项字段(option):可变长的可选信息。这部分最多包含40字节,因为IP头部最长是60个字节(包含前面讨论的20个字节的固定部分)。可用的IP选项包括:

    • 记录路由(record route):告诉数据报途径的所有的路由器都将自己的IP地址填入IP头部的选项部分,这个我们可以跟踪数据报的传递路径。
      时间戳(timestamp),告诉每个路由器都将数据报被转发时的时间(或时间与IP地址对)填入IP头部选项部分,这个就可以测量途径路由之间的数据报传输的时间。

    • 松散源路由选择(loose source routing),指定一个路由器IP地址列表,数据报发送过程中必须经过其中所有的路由器。

    • 严格源路由选择(strict source routing),和松散源路由选择类似,不过数据报只经过被指定的路由器。

我们也可以直接最简单的ICMP协议对IP分片的报文进行进一步的了解:

以太网的MTU是1500字节,所以携带的IP数据报的数据部分最多是1480字节(IP头部占用20字节)。考虑用IP数据报封装一个长度为1481字节的ICMP报文(包括8字节的ICMP头部,所以其数据部分长度为1473字节),则该数据报在使用以太网传输时必须被分片,如下图所示:

ICMP网络层报文

IP分片的报文规律:

  • 同一组IP分片具备相同的identification,是一个无符号的16位整型,可表示65535个id,不代表唯一id

  • 同一组的IP分片只有首片可以访问到传输层的报文头,中间片和尾片只有IP头

  • IP分片的区分规律:

    • 非IP分片DF=1,MF=0,offset=0

    • 首片DF=0,MF=1,offset=0

    • 中间片DF=0,MF=1,offset为对应的偏移值

    • 尾片DF=0,MF=0,offset为对应的偏移值


【计算机网络】区分tcp分段和ip分片
https://littlejoyo.github.io/2021/09/16/network/tcp-ip-frame/
作者
Joyo
发布于
2021年9月16日
许可协议