发送方发送数据需要考虑接收方的处理能力,如果一直发数据给对方,对方又处理不过来,就会触发很多次重传,导致流量浪费。另外,在通信时接收方如果数据处理不过来会将数据包暂存在缓冲区中,如果缓冲区满了发送方继续向接收方发送数据的话会导致数据包丢失,TCP提供流量控制机制使发送方根据接收方的接收能力控制发送的数据量。
滑动窗口
流量控制是基于滑动窗口的。滑动窗口能够告诉发送方接收方还能接收多少数据。
滑动窗口还有另一个重要的作用:TCP每发送一个数据都要进行一次确认应答,如果在收到应答后再发送下一个数据的话效率太低。引入滑动窗口以后,发送方不需要在对方确认应答后才能继续发送,接收方可以将数据缓存在缓冲区,而窗口大小就是缓冲区大小。
引入滑动窗口以后,提升了数据发送的效率,同时通过窗口大小限制连续发送的数据量,控制流量。
窗口关闭
当窗口缩小为0时,发送方不能再发送数据,成为窗口关闭。
潜在的风险:接收方处理完数据后,向发送方发送ACK报文,报文中包括窗口不为0的信息,但是报文丢失了,发送方一直在等待窗口非0的通知,而接收方则开始等待发送方发送数据,产生死锁。
打破死锁:当一方收到窗口关闭通知时,会开启一个持续计时器,如果计时器超时,会发送一个窗口探测报文,对方收到会告诉探测方现在的窗口大小,如果仍然为0则重启计时器再次计时,如果不为0则可以继续通信。
糊涂窗口
当窗口只剩很小的大小时,发送方直接发送数据,这样可能会导致发送很多小窗口的数据。但是发送数据需要带上TCP和IP头部,相比于小窗口的数据,开销太大。
解决方案有两个:
1、使接收方不通告小窗口;2、发送方避免发送小数据;
不通告小窗口:
当窗口大小小于 min(MSS,1/2缓存空间)时,告诉发送方窗口为0。
避免发送小数据:
当窗口大小或数据大小不小于MSS时,或者收到之前发送的包的ACK报文时可以继续发送数据。