TCP的MSS(最大报文段长度)与MTU的关系
我们来详细讲解TCP的MSS(最大报文段长度)与MTU(最大传输单元)之间的关系。这是一个在TCP连接建立和数据传输过程中至关重要的概念。
1. 基本概念定义
首先,我们需要明确两个核心概念:
-
MTU (Maximum Transmission Unit, 最大传输单元):
- 定义:MTU指的是在网络层(IP层)上,一个数据帧(或数据包)所能承载的有效载荷的最大长度。它不包括数据链路层的帧头(如以太网帧头14字节)和帧尾(如CRC校验4字节)。
- 作用范围:MTU是数据链路层的特性。它规定了在一条物理链路上,一次能够传输的数据块的最大尺寸。不同的网络技术有不同的MTU值。例如,标准以太网的MTU是1500字节。
- 重要性:如果IP层要发送的数据报长度超过了该链路的MTU,IP层就必须进行分片,将一个大的IP数据报分割成多个小于等于MTU的片段,以便在链路上传输。
-
MSS (Maximum Segment Size, 最大报文段长度):
- 定义:MSS指的是在传输层(TCP层)上,一个TCP报文段中实际应用数据(不包含TCP头部)的最大长度。
- 作用范围:MSS是TCP协议的概念。它在TCP连接建立时,通过三次握手在通信双方之间进行协商。
- 目的:TCP使用MSS的主要目的,就是为了避免IP分片。通过限制单个TCP报文段的大小,确保封装这个报文段的IP数据报的总长度不会超过路径的MTU。
2. 核心关系:MSS 是为了避免 IP 分片
理解了定义后,我们来看它们最核心的关系。这个过程可以看作一个“封装”的过程:
- 你的应用程序通过Socket接口发送数据给TCP层。
- TCP层将应用数据分割成合适大小的数据块,每个数据块加上TCP头部,形成一个TCP报文段。这个“合适的大小”就是MSS。
- TCP层将这个报文段交给IP层。
- IP层给TCP报文段加上IP头部,形成一个IP数据报。
- IP数据报被交给数据链路层。
- 数据链路层给IP数据报加上帧头和帧尾,形成一个数据帧,然后在物理链路上传输。
这个封装过程的尺寸关系是:
IP数据报总长度 = IP头部长度 + TCP头部长度 + 应用数据长度
为了避免IP数据报在数据链路层因为尺寸过大而需要被分片,我们必须保证:
IP数据报总长度 <= 路径MTU
由于IP头部和TCP头部的长度通常是固定的(各20字节,除非有选项),我们可以推导出MSS与MTU的关系式:
MSS = MTU - IP头部长度 - TCP头部长度
3. 计算示例
以最常见的标准以太网环境为例:
- 以太网MTU = 1500 字节
- IP头部标准长度 = 20 字节
- TCP头部标准长度 = 20 字节
那么,理想的MSS值就是:
MSS = 1500 - 20 - 20 = 1460 字节
这意味着,在标准的以太网上,为了确保TCP报文段封装成IP数据报后不会超过1500字节的MTU,通信双方协商的MSS通常会是1460字节。这样,一个TCP报文段(包含1460字节的应用数据、20字节TCP头)交给IP层后,IP层加上20字节的IP头,形成的IP数据报总长度正好是1500字节,完美匹配以太网的MTU。
4. 路径MTU发现(PMTUD)
上面的讨论基于一个假设:通信两端之间的整个网络路径的MTU都是一样的(比如都是1500字节)。但现实中的网络是复杂的,可能会经过MTU更小的链路(例如某些PPPoE或VPN隧道,MTU可能为1492字节或更小)。
如果发送方仍然按照1460字节的MSS发送数据,当数据报到达那个小MTU的链路时,路由器就需要对其进行分片。分片会降低网络性能(加重路由器负担,一个分片丢失会导致整个数据报重传)。
为了解决这个问题,TCP采用了路径MTU发现 机制。其基本原理是:
- 发送方在IP头部设置
DF(Don‘t Fragment,不分片)标志。 - 如果中间路由器的MTU小于IP数据报的大小,它无法对数据报进行分片(因为DF位被设置),于是会丢弃该数据报,并向发送方回送一个ICMP“需要分片”的错误消息,该消息中会告知下一跳的MTU值。
- 发送方收到这个ICMP消息后,就知道了当前路径的实际MTU,并相应地下调自己的MSS值。
通过这种方式,TCP可以动态地适应网络路径的变化,始终使用一个不会引起分片的最优MSS值。
总结
- MTU是数据链路层的概念,限制了一次性能传输的IP数据报的最大尺寸。
- MSS是TCP层的概念,限制了一个TCP报文段中应用数据的最大尺寸。
- 核心关系:
MSS = MTU - IP头 - TCP头。MSS的提出主要是为了避免IP分片,从而提高传输效率。 - 路径MTU发现 是一种动态机制,用于在复杂的网络环境中找到端到端路径上的最小MTU,从而确定最佳的MSS值。