文章目录
MSS 引用
首先,我们知道 MTU 是网卡的参数( MTU详情参考笔记:
MTU-最大传输单元
),是数据链路层对网络层的IP包大小的限制。当网络层的IP包(包括IP头,协议头,VLAN Tag)的大小超过了MTU时,需要先在网络层进行分片,切割成小于MTU的IP包(拆包)
,再发往链路层
试想下,一台主机下的多个应用需要通过TCP协议,发送大量的数据进行通信,然后形成这样一种局面:多个TCP报文,到达网络层时,封装成多个IP包,这些IP包由于数据太大,大于MTU,需要进行分片,才能发往链路层。这么多的数据包都需要在网络层分片切割,效率大大降低。
既然从TCP来的数据由于太大,而全部挤在网络层进行分片,为什么不想一个办法,让TCP来的每一份数据,正好符合在网络层不需要分片,这样岂不是你好我好大家好?
于是出现了MSS
MSS 介绍
Maximum Segment Size,最大报文长度
,它是 TCP Payload (下文描述)的最大值,是TCP协议定义的一个选项,MSS是TCP用来限制应用层
最大发送字节数的
MSS,在TCP连接建立时,发送方和接收方协商,通信的所有报文段,所能承载的最大数据长度
TCP在建立连接时,收发双方根据 MTU
计算出各自的 MSS,通过三次握手把自己的MSS告知对方,互相确认彼此的MSS大小,取较小的MSS值作为双方在TCP层分段的最大Payload
- 如何根据MTU计算MSS?
一般而言默认
MTU数值 = 1500 = IPHeader(20) +TCPHeader(20) + Data
(假设没有 VLAN Tag)
TCP的有效数据Data的最大值就是1500-20-20 = 1460,这就是MSS的值
- 客户端在SYN报文中携带自己的MSS,服务器在回复的ACK+SYN中携带自己的MSS(如下图)
这样就实现了TCP通信时, 在三次握手阶段确定最小MSS
,根据MSS, 传输层把不超过MSS的数据封装,下压给网络层,网络层避免了IP包分片,而接收方也不会出现数据帧超过MTU而无法接收的情况
。
MSS 与 TCP Payload
TCP Payload:TCP报文一次性可传输的最大值。
TCP报文通常有3部分组成: IP Header + TCP Header + Payload
一般而言
可以这么来计算(假设没有 VLAN Tag):
IP报文头长度 + TCP报文头长度 + Payload长度 ≤ MTU
(参考下图)
即左边的三者之和,要小于等于右边MTU的长度,其中:
Internet 路由器接口标准MTU = 1500
IP报文头长度 = 20
TCP报文头长度 = 20
因此:
Payload长度 ≤ MTU – IP报文头长度 – TCP报文头长度 ≤ 1500 -20 -20 ≤ 1460
TCP为了提高传输效率,通常会使用最大上限1460字节来传输应用层数据
TCP Option 选项
当前主流操作系统的TCP/IP协议栈,为了提高传输性能,通常还会使用 TCP Option选项。客户端在TCP握手连接,告诉服务器自己支持以下三个option:
- Maximum Segment Size
- SACK Permitted
- Timestamp
Maximum Segment Size
Maximum Segment Size, 最大报文长度
,MSS的存在是为了通信双方交换各自TCP Payload最大传输长度,这个长度上限一般为1460, 即上文计算的方法。 如果双方的MSS不一样,将选择较小的MSS值,作为接下来通信Payload的长度上限
。
Timestamp
假如服务器支持选项“Timestamp”,那么TCP报文将会包含4部分:
IP Header + TCP Header + TCP Option +Payload
这里的TCP Option为“Timestamp”,长度为 10字节,那么
IP Header + TCP Header + TCP Option +Payload ≤ 1500
Payload ≤ 1450
注意,没有携带option的TCP报文,最大可以支持1460字节的Payload长度。一旦携带option, 由于option需要占用空间,留给payload的空间将会相应减少
,具体减少的空间等于option占用的空间。
TCP payload总结
TCP payload总结:
MSS 是 TCP payload的最大值
MSS 与 Window Size(窗口可用大小)
MSS 可以看成是一个集装箱,
Window Size可以看作双方的仓库大小,用于临时堆放对方运过来的集装箱,在集装箱被客户运走之前,一直会呆在TCP仓库里。
为了更高效地利用仓库,最理想的方法就是,仓库的大小是集装箱的整数倍,这样就不会产生零星的空间。
如果零星的空间
因为不够容纳一个标准集装箱,一直无法使用, 会造成仓库空间的浪费,甚至导致传输效率低下
- 传输效率低下的原因
假设接收方的仓库空间还有200字节,于是通过window size update消息告诉发送方,
发送方心急火燎发200字节,那么一个标准1460报文,将会分成8个小报文发送,这样的传输效率会非常低下。
为了避免这种低效传输场景,TCP协议有了新的严格规定
- 对于接收方
如果接收方 window size < MSS , 不允许更新自己的window
理解为:一旦接收方的仓库空间小于一个标准集装箱,window size update = 0 , 即善意欺骗对方,仓库已经用完,不允许再发货物过来。
- 对于发送方
如果发送方一旦发现对方的window size < MSS,不再发送数据包
理解为:对方的仓库已经占满(剩余空间不足以容纳一个标准集装箱),不会发送任何集装箱。