本文已参与「新人创作礼」活动,一起开启掘金创作之路。
TCP如何实现流量控制?
使用滑动窗口协议实现流量控制。目的是为了控制发送方的发送速率,保证接收方接收时不会溢出。
接收方会维护一个接收窗口(接收窗口的大小根据自己的资源情况动态调整),在返回确认时将接受窗口大小放在TCP报文的窗口字段告知发送方,发送方收到确认之后,发送窗口才能右移。
发送窗口的上限为接收窗口和拥塞窗口中的较小值。接受窗口表明了接收方的接收能力,拥塞窗口表明了网络的传送能力。
什么是零窗口(接收窗口为0时会怎样)?
如果接收方没有能力接收数据,就会将接收窗口设置为0,这时发送方必须暂停发送数据,但是会启动一个持续计时器(persistence timer),到期后发送一个1字节的探测数据包,以查看接收窗口状态。如果接收方能够接收数据,就会在返回的报文中更新接收窗口大小,恢复数据传送。
TCP的拥塞控制是怎么实现的?
流量控制是为了让接收方能来得及接收,而拥塞控制是为了降低整个网络的拥塞程度。
TCP 主要通过四个算法来进行拥塞控制:慢开始、拥塞避免、快重传、快恢复。
发送方需要维护一个叫做拥塞窗口(cwnd) 的状态变量,注意拥塞窗口与发送方窗口的区别:拥塞窗口只是一个状态变量,实际决定发送方能发送多少数据的是发送方窗口。
真正的发送窗口值=Min(公告窗口值,拥塞窗口值)
拥塞判断:
(1)重传定时器超时:若发生了超时,可能出现了网络拥塞
(2)收到三个相同的ACK:当有个别报文丢失时,接收方会反复发送收不到的序列号,发送方接收到三次相同的缺失序列号表示网络可能会拥塞。
1. 慢开始与拥塞避免
慢开始:发送的最初执行慢开始,令 拥塞窗口cwnd = 1,发送方只能发送 1 个报文段;当收到确认后翻倍,将 cwnd 加倍,因此之后发送方能够发送的报文段数量为:2、4、8 ...
拥塞避免:注意到慢开始每个轮次都将 cwnd 加倍,这样会让 cwnd 增长速度非常快,从而使得发送方发送的速度增长速度过快,网络拥塞的可能性也就更高。设置一个慢开始上限 ssthresh,当 cwnd >= ssthresh 时,进入拥塞避免,每个轮次只将 cwnd 加 1。
如果出现了超时,则令 ssthresh = 拥塞窗口cwnd / 2,然后重新执行慢开始。(拥塞与慢开始循环触发) 。
2. 快重传与快恢复
在接收方,要求每次接收到报文段都应该对最后一个已收到的有序报文段进行确认。例如已经接收到 M1 和 M2,此时收到 M4,应当发送对 M2 的确认。
快重传:在发送方,如果收到三个重复确认-ACK,那么可以知道下一个报文段丢失,此时执行快重传,立即重传下一个报文段。例如收到三个 M2,则 M3 丢失,立即重传 M3。(当M3缺失时,后面接收到M4、M5、M6都只回复M2确认,因此发送方会收到三个M2确认)
快恢复:若只是丢失个别报文段而不是网络拥塞。因此执行快恢复,令 ssthresh = cwnd / 2 ,cwnd = ssthresh(起始高度高于慢开始),注意到此时直接进入拥塞避免(+1+1+1)。
慢开始和快恢复的快慢指的是 cwnd 的设定值,而不是 cwnd 的增长速率。慢开始 cwnd 设定为 1,而快恢复 cwnd 设定为 ssthresh。