tcp 核心问题 之 流量控制
你将了解
- 什么是 tcp 流量控制
浅聊一下
在我的 tcp 核心问题 之 滑动窗口 一文中我们已经了解了 滑动窗口到底是怎么一回事,而滑动窗口的目的其实就是在做流量的控制,滑动窗口的大小动态变化,取决于接收端 buffer 缓冲区的大小以及应用服务消费报文段的能力。而 拥塞控制不同,其主要影响因素是取决于网络的快慢,而如何判断当前网络的快慢,这是将会是一个很有意思的问题。本篇由此开始
tcp 流量控制
流量控制,其实就是收发双方,对滑动窗口大小的动态控制,也就是说,你当前 buffer 缓冲区所占用的大小,以及你的应用服务处理报文段的能力决定了你 滑动窗口的大小。
对于每次的 ack 我们都会带上 win 去告知对方,我现在还能接收多少数据。
这里有个计算规则
因为在 tcp 头 中只给 滑动窗口留了 16 位的大小,如果仅仅用这 16 位,那么滑动窗口最大不能超过 64 kb,为了打破这个限制,tcp 会在 三次握手的时候协商好 window size scaling factor 滑动窗口乘积因子 这里是 64 ,所以实际的窗口大小为 4096 * 64 = 262144 bit
关于三次握手确认 window size scaling factor
三次握手,tcp option 中双方给出 window scale 6
即 2^6 = 64 和 window scale 7
2^7 = 128 ,最终取最小的 64 作为乘积因子。
回归正题:流量控制
上面补充了一下 窗口大小的细节点,那对于流量控制,以收发双方为例子。
在对报文段的确认中,会有这样的关系,对于发送端
这个窗口会随着报文段的确认即 ack 而整体右移,那么图中绿色部分的未发送的报文就可以变成可发送的报文
当可发送都发送完成后,发送端就不会再发送报文,而是等待接收端的确认。
接收端会根据自身的处理能力动态控制 win 的大小,极端的情况,可能接收端的应用服务一直不读取缓存中数据
来看看接收端
如果应用服务,一直不读取 已接收报确认文段 ,那么 接收窗口的大小就会收缩,而不是平行右移,在下次 ack 时, 就会将 win 的信息同步给,发送端,这时候发送端也会进行收缩,即仅左端右移
极端情况可能会收缩为 0 此时发送端就不会发送新的包,而没有新的包到 接收端,接收端也就不会 ack ,就无法同步 win 的大小,为了防止出现这种僵局,在 win 收缩到 0 时, 发送端会定期发送探测包,来探测更新 win 的大小。
那接收端也并不是有一个空位更新 win 的大小的这样可能马上又填满 buffer,而是会进行一个优化,等待 win 足够大时再一起同步给 发送端。
最后提一点
其实对于发送端和接收端,并不是一个绝对的概念,而是同时存在的,即你在发数据的同时你也要接收数据不是?
所以对于每个端来说,即是发送方也会是接受方。