什么是MSS&MTU以及发送窗口&滑动窗口
这两天接了西云的面试,还在准备状态,在这边重新拎一下TCP/IP吧。
在看一本Wireshark的书,可惜本人基础不牢,遇到一些问题还要继续搜寻答案。
- 发送窗口和MSS有什么关系?
- 发送窗口决定了一口气能发多少字节,而MSS决定了这些字节要分多少个包发完。举个例子,在发送窗口为16000字节的情况下,如果MSS是1000字节,那就需要发送16000/1000=16个包;而如果MSS等于8000,那要发送的包数就是16000/8000=2了。
从上面这个问题引出了我的几个问题,MSS是什么,听起来像是一个TCP的切片(不正确)。
1.什么是MSS
找到一篇赛博佛祖的文章,我觉得很棒:什么是 MSS(最大分段大小)?
里面有张图很灵魂,但是我为了迅速我就不贴了。
MSS的全程为maximum segment size
,MSS 测量数据包的非标头部分,称为有效负载。MSS 是联网设备可以接收的最大 TCP(传输控制协议)段大小。MSS 将“段”定义为仅有效负载的长度,而不是任何附加的标头。MSS 以字节为单位。
从上面一段,我理解为,MSS是TCP协议的最大有效负载,一般为MTU - (TCP 标头 + IP 标头) = MSS 1460bytes。
TCP和IP标头一般为20bytes大小。由此可以总结,TCP包的长度为1480(包含了TCP头),IP包的长度为1500(包含了TCP和IP头)。
2.什么是MTU
其实有点自上往下的概念了,我个人认为MTU是以太网的最大传输负载。也就是默认缺省的1500bytes。
MTU是工作在IP层的概念,但是MTU为什么这么大就要看下面这段数据链路层的解析。
以太帧帧长最小为64bytes,最大为1518bytes,可以知道以太帧有效数据部分最最小为64-6-6-2-4 = 46bytes,最大为1518-6bytes目标MAC地址-6bytes源MAC地址-2bytes数据帧类型-4bytes校验 = 1500bytes,这个最大值就称为MTU,所以通常是1500bytes。
1 |
|
如上是我在我的树莓派上运行的命令结果,可以查看所有网络接口的MTU,可以看到除了loopback和tailscale其他的借口都是1500的MTU。
MTU 和 MSS 之间的主要区别之一是,如果数据包超过设备的 MTU,则会分解为更小的部分,或“分段”。相反,如果一个数据包超过 MSS,它就会被丢弃并且不会被传递。
这边是Cloudflare的文章:什么是MTU?
3.发送窗口&接收窗口
回到我们最开始的问题,发送窗口和MSS的区别,现在我们知道了MSS是TCP的最大有效负载,那么发送窗口这个东西就涉及到了拥塞控制以及接受窗口。
按照我的理解,发送窗口的概念无法直接从数据包中看到,并且发送窗口的大小也十分多变,在不考虑网路拥塞的情况下,发送窗口的大小我理解为接受窗口的大小,为了最大的传输效率,我们将接受窗口发满就停止发送。
但是考虑了网络拥塞情况之后,发送窗口的大小就变成了min{拥塞窗口,接收窗口}。
也就是如果网络拥塞的话,发送窗口的长度还会减少。
在TCP三次握手中会发送双方的接收窗口大小,包括TCP正常标头中也带有接收窗口大小。
1 |
|
我们可以从上面的抓包信息中看到,Window: 64240,下面wireshark也给我们计算了实际的窗口大小,至于为什么数值一样是因为SYN包不放大。其计算方式为,下面的window scale字段的shift count值,如上数据2的8次方等于256,再将64240和256相乘便得到了实际的窗口值。
4.滑动窗口
滑动窗口就比较难解释了,以我的理解,所有等待发送的资源,都会发往缓冲区,发送窗口维护着四个概念:
- 已发送并收到确认的数据(不在发送窗口和发送缓冲区之内)
- 已发送但未收到确认的数据(位于发送窗口中)
- 允许发送但尚未发送的数据(位于发送窗口中)
- 不允许发送的数据(不在发送窗口中但在发送缓冲区)
1 |
|
如上所示的5-12可以理解为滑动窗口区域,1-4为已发送并且收到确认的数据,滑动窗口区域是允许发送的数据也就是发送窗口的大小,按照TCP建立连接后接收方的接收窗口大小一致(不拥塞的话)。
当发出的数据包收到确认的ack时,滑动窗口的左沿和右沿都会向前滑动。
当网络出现拥塞时,或者接收端的接收窗口为0时,滑动窗口的右沿则会左移,使滑动窗口减小即发送窗口减小。