在网络实际的传输过程中,会出现拥塞的现象,网络上充斥着非常多的数据包,但是却不能按时被传送,形成网络拥塞,其实就是和平时的堵车一个性质了。TCP设计中也考虑到这一点,使用了一些算法来检测网络拥塞现象,如果拥塞产生,变会调整发送策略,减少数据包的发送来缓解网络的压力。
拥塞控制主要有四个算法:
1. 慢启动
2. 拥塞避免
3. 拥塞发生时,快速重传
4. 快速恢复
慢启动算法
之前介绍的滑动窗口能够让协议栈同时发送多个报文段,这样可以提高网络通信的效率,对于一些处理能力不佳的中间路由器,很可能会导致存储被耗尽的状况,从而严重降低了TCP连接的吞吐量,不断的重传. 非常的可怕, 介于此,引入了慢启动这个算法。
慢启动为发送方的TCP增加了一个窗口:拥塞窗口,记为cwnd,,初始化之后慢慢增加这个cwnd的值来提升速度。同时也引入了ssthresh门限值,如果cwnd达到这个值会让cwnd的增长变得平滑,算法如下
1. 连接建好的开始先初始化cwnd = 1,表明可以传一个MSS大小的数据
2. 每当收到一个ACK,cwnd++; 呈线性上升
3. 每当过了一个RTT,cwnd = cwnd*2; 呈指数让升
4. 当cwnd >= ssthresh时,就会进入“拥塞避免算法”
拥塞避免算法
算法:
1)收到一个ACK时,cwnd = cwnd + 1/cwnd
2)当每过一个RTT时,cwnd = cwnd + 1
图示
结合图来看下数据发送过程中慢启动和拥塞避免算法的使用情况
1. 连接建立,开始传输数据,cwnd = 1 , ssthresh的初始值为16,发送第一个包
2. 发送端收到一个确认后,cwnd加1,于是可以 发送2个数据包
3. 收到2个ACK之后,这个时候cwnd + 2 , 于是可以发送4个数据包
4. 收到4个ACK后,这个时候cwnd + 4 ,于是可以发送8个数据包, 可以看到这个时间段,cwnd随着传输轮次的增长,成指数增长
5. 当拥塞的窗口达到ssthresh后,慢启动算法结束,开始进入拥塞避免算法
6. cwnd按照一个RTT进行+1的线性增加,假设到达24时,出现网络拥塞
7. ssthresh = 1/2 * cwnd = 12, cwnd = 1 继续重新执行慢启动算法
8. 同样当cwnd = 12时 执行拥塞避免算法
其中第7步属于对网络拥塞的一种处理, 什么状态下才会认为是拥塞? 基本上就认为是有丢包产生,在前面知道丢包产生会有2中处理方法超时重传和快速重传,其中如果RTO超时的时候,TCP认为环境已经很糟糕了,
a .sshthresh = cwnd /2
b. cwnd 重置为 1
c.进入慢启动过程
如果是快速重传,则:
TCP Tahoe的实现和RTO超时一样。
TCP Reno的实现是:
a. cwnd = cwnd /2
b. sshthresh = cwnd
c. 进入快速恢复算法——Fast Recovery【下一篇文章介绍】
简单的来说,发送的速率总是在不断的增长,只不过一开始增长比较快,指数增长,到达门限值的时候,切换增长模式,变成线性增长,当系统中出现了丢包重传现象,判断已经网络已经发送阻塞,要重新设定参数,进入慢启动状态。