TheRiver | blog

You have reached the world's edge, none but devils play past here

0%

拥塞控制(慢启动+拥塞避免+超时重传+快速重传+快速恢复)

参考

TCP-IP详解: 慢启动和拥塞控制

TCP/IP之RTO、RTT

如何测量和确定Linux系统中tcp初始发送窗口的大小?

什么是CWND和RWND

TCP复习拥塞控制


拥塞控制

当某一路由器在单位时间内接收到的数据量多于其可发送的数据量时,他就把多余的部分存储起来。假如这种情况持续,存储资源将会耗尽,最后路由器不得不丢弃一部分数据,这种现象成为拥塞。在TCP的两端看到的就是丢包现象,为避免或在一定情况下缓解这种情况,TCP通信的每一方都实行拥塞控制机制。TCP是全双工通信,每一方都可能发送数据,途经路由器,所以两个发送方(server/client)都应该支持拥塞控制,而上一篇文章的滑动窗口是接收方主动的一种行为。


说明

  • Tahoe 提出了 慢启动 拥塞避免 超时重传
  • Reno 在Tahoe的基础上增加了 快速重传 快速恢复
  • 谷歌BBR

TCP的发送窗口

wnd = min(rwnd, cwnd*mss)

rwnd:接收方的窗口大小

cwnd:发送方的窗口大小

cwnd.png


RTT/RTO

RTT(Round Trip Time)

一个连接的往返时间,即数据发送时刻到接收到确认的时刻的差值;

RTO(Retransmission Time Out)

重传超时时间,即从数据发送时刻算起,超过这个时间便执行重传, RTO协议实现值最小1s


状态切换

当cwnd < ssthresh,执行慢启动

当cwnd > ssthresh, 执行拥塞避免

当cwnd = ssthresh, 执行慢启动/拥塞避免的一种

当超过RTO时间,触发超时重传
当收到3个以上的重复ACK,就进入快速重传

拥塞控制状态图.jpg

图片来源
TCP 拥塞控制算法


慢启动

慢启动的时机

  • 当一个新的TCP连接建立
  • 检测到由重传超时(RTO)导致的丢包时
  • TCP发送端长时间处于空闲状态

慢启动的目的

使TCP在用拥塞避免探寻更多可用带宽之前得到CWND(拥塞窗口)值,以及帮助TCP建立ACK时钟。


cwnd变化

在慢启动拥塞控制中,TCP快速增加窗口的大小(指数增加),以尽快达到最大传输速率(指数)

每当收到一个ACK,cwnd + 1;
每当过了一个RTT,cwnd = cwnd*2;

不考虑ack丢失的情况,则是2,4,8的指数增加

慢启动.png

图片来源
TCP复习拥塞控制


拥塞避免

当达到阈值,迅速调整发送速率

If   cwnd < ssthresh then 
        Each time an Ack is received: 
        cwnd = cwnd + 1 
else   /*  cwnd >  ssthresh  */ 
                    Each time an Ack is received: 
        cwnd = cwnd + 1 / [ cwnd ] 
endif

每当收到一个ACK,cwnd = cwnd + 1 / cwnd;

每当过了一个RTT,cwnd = cwnd + 1;


超时重传

最为早期的TCP Tahoe算法使用下面的算法,但效率较差

  • 由于发生丢包,将慢启动阈值ssthresh设置为当前cwnd的一半,即ssthresh = cwnd / 2.
  • cwnd重置为1
  • 进入慢启动过程

ssthresh.png

图片来源
TCP复习拥塞控制


快速重传

Reno算法在超时重传的基础上,对于收到三次以上的重复ack后,直接进行处理,不用等待定时器超时(RTO),并且处理策略也进行了优化

  • cwnd大小缩小为当前的一半
  • ssthresh设置为缩小后的cwnd大小
  • 然后进入快速恢复算法Fast Recovery。

快速恢复

Reno引入了快速恢复算法

  • cwnd = cwnd + 3 * MSS,加3 * MSS的原因是因为收到3个重复的ACK。
  • 重传DACKs(重复确认)指定的数据包。
  • 如果再收到DACKs,那么cwnd大小增加一。
  • 如果收到新的ACK,表明重传的包成功了,那么退出快速恢复算法。将cwnd设置为ssthresh,然后进入拥塞避免算法。

Fast Recovery.jpg

图片来源
TCP 拥塞控制算法

收到第三个重复ack后 
ssthresh=cwnd=6/2=3(快速重传)
cwnd=3+3=6(快速恢复)
如果继续收到ack5,则cwnd++
重传pkt5数据包
如果收到新的ack,则cwnd=ssthresh,进入拥塞避免

快速恢复cwnd>ssthresh属于裸奔状态,是特事特办,在重传的同时可以发送新的包,在重传结束,需要快速切换回拥塞避免状态


ending

76259440_p0_master1200.jpg

----------- ending -----------