浅谈TCP拥塞控制:慢启动和拥塞避免、快速重传和快速恢复
文章对TCP的拥塞控制算法,进行了浅显的描述,便于人们理解。
目录
声明:以下图片来源于网络
1 拥塞的概念
在这里我引用百度百科上面的概念:
拥塞是指到达通信子网中某一部分的分组数量过多,使得该部分网络来不及处理,以致引起这部分乃至整个网络性能下降的现象,严重时甚至会导致网络通信业务陷入停顿,即出现死锁现象。这种现象跟公路网中经常所见的交通拥挤一样,当节假日公路网中车辆大量增加时,各种走向的车流相互干扰,使每辆车到达目的地的时间都相对增加(即延迟增加),甚至有时在某段公路上车辆因堵塞而无法开动(即发生局部死锁 )。
我们熟知的TCP模块还有一个重要的任务,就是提高网络的利用率,降低丢包率,并保证网络资源对每条数据流的公平性。这就是所谓的拥塞控制,在介绍拥塞控制之前,不得不先提一下TCP的流量控制,滑动窗口。
2.流量控制:滑动窗口
一般来说,我们总是希望数据发送的又快又多。但是这样,接收方可能来不及接收。所以要进行流量控制。
滑动窗口有的机制很简单,就是通过设置滑动窗口的大小,来决定每次发送数据的数量。
例如,当前我们的滑动窗口大小为6,那么这将意味着主机每次可以最多发送6个数据段。
以下滑动窗口发送机制参考文章:浅谈TCP滑动窗口机制
第一次发送:
第一次发送前6个数据段,发送之后必须等待主机B的确认。
加入主机只收到段1,2和5,那么主机A接收到主机B的的确认包中有序号为3的段进行确认,确认的是1和2段。此时发送主机的滑动窗口向右滑两个段,加入7和8,进入第二次发送。
第二次发送:
我们假设当前的6个段都被正常发送,且正常接收,那么接收记住发回的包中有序列号为9的段进行确认,即表示前9个段都接受成功。这时滑动窗口向右滑动6个段,进入下一次发送。
第三次发送:
以上三步很具体的概括了滑动窗口的机制。
在了解了滑动窗口以后,能让我们更加深入的理解拥塞控制,因为滑动窗口决定了发送数据量的大小,拥塞控制主要就是在滑动窗口上做文章。
3 拥塞控制
首先规定几个缩写,在下述文章中出现可以进行对照:
- cwnd:拥塞窗口
- SMSS:TCP报文段的最大长度(仅指数据部分)
- ssthresh:慢启动门限,相当于一个阈值。
- RTT:往返时间 (表示从发送端发送数据开始,到发送端收到来自接收端的确认(接收端收到数据后便立即发送确认,不包含数据传输时间,总共经历的时间)。
慢启动和拥塞避免配合使用,快速重传和快速恢复同时使用。
3.1 慢启动
慢启动的机制是这样的:为TCP的发送发增加一个窗口:拥塞窗口(congestion window),记为cwnd。当TCP连接建立之后,cwnd的大小被初始化为1个最大报文段的大小。发送方每收到一次ACK确认之后,就将cwnd的大小增加一个报文段(注意:一个报文段包括不止一个报文)。
增加规则如下:
cwnd += min(N,SMSS)
N为上次发送被确认的字节数。
假设开始cwnd的大小为1,那么经过一次发送之后大小变为2,经过两次发送大小变为4。
cwnd相当于发送方的流量控制。
同时接收方也具有一个窗口叫作通告窗口,作为接收方的流量控制。
发送方发送数据的大小为:在发送方拥塞窗口和接收方通告窗口二者中取最小。即将发送方滑动窗口的大小设置为拥塞控制窗口和通告窗口大小的最小值。
慢启动存在的理由是:tcp刚开始并不知道网络的实际情况,需要用一种试探性的方式平滑的增加cwnd的大小。慢启动算法增加了拥塞窗口,可以反应网络的整体情况,而滑动窗口只能反应主机个体情况。
从上述cwnd的增加规则中可以看出,慢启动中cwnd的大小是呈指数级增长的,因此,慢启动并不慢。如果不进行控制,慢启动最终会导致网络拥塞。为了防止这种情况的发生,TCP在拥塞控制中增加了一个变量ssthresh。并且规定了cwnd的大小要按照下述规则进行:
当cwnd<ssthresh时:进行慢启动算法
当cwnd>ssthresh时:进行拥塞避免算法
当cwnd==ssthresh时::两种皆可
下面介绍拥塞避免。
3.2 拥塞避免
拥塞避免即让cwnd缓慢的增长,在一个RTT时间内,将cwnd的大小增加1,即增加cwnd的初始大小。这样,cwnd的大小就从以前的指数级增长变成现在的线性增长。
通过时规定:
无论时慢开始还是拥塞避免,只要网络出现阻塞,就将ssthresh的值跟新为cwnd的一半,但不能小于2。同时将cwnd的大小跟新为1,即为cwnd的初始大小。
如下图,时一个慢开始与拥避免的应用举例:
从可以清楚的看到cwnd的增长方式以及ssthresh的更新。
3.3 快速重传
在TCP报文段丢失或者接收端收到乱序的TCP报文段等情况下,发送端都会收到重复的确认报文段。
当发送端连续收到3个重复的确认报文端段的时候,tcp就认为拥塞发生了。然后会立即重传丢失的报文段。
这就是快速重传的机制。
3.4 快速恢复
快速恢复机制一般和快速重传机制同时使用。快速恢复机制如下:
- 当发送端收到第三个重复确认的报文时,会更新ssthresh的值,然后立即重传丢失的报文段,并且设置:cwnd = ssthresh+3*SMSS,进入拥塞避免阶段。
- 当收到一个重复确认的报文时,设置cwnd = cwnd +SMSS。此时发送端可以发送新的TCP报文(如果新的cwnd允许)
- 当收到新数据的确认时,设置cwnd=ssthresh。进入拥塞避免阶段。
这里的新数据表示新的报文,而不是丢失的报文。
在旧的tcp拥塞控制算法中,快速重传之后会进入慢启动阶段,而新的tcp拥塞控制算法在快速重传之后进入快速恢复阶段。
如下图:
以上内容有自己的理解,也有网络上的资料,欢迎大家指正。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)