慢启动、拥塞避免、超时重传、快速重传、快速恢复、滑动窗口

慢启动、拥塞避免、超时重传、快速重传、快速恢复、滑动窗口

流量控制
因为数据的发送方和接收方并不一定具有相同的数据处理能力,为了避免数据发送方的数据发送过快,而导致其超过了接受端的数据处理能力,TCP采用了流量控制机制,接收方在TCP的包头里面采用16位RWND,通告发送方自己的接收窗口,也就是还能够接收的最多的数据量,这样发送端就不会过度发包而超过接收方的接收能力。

**滑动窗口:**TCP流量控制的一种手段。这里说的窗口是指接收通告的窗口(RWND),告知对方本端的TCP接收缓冲区还能容纳多少字节的数据,对方就可以控制发送数据的速度。

**拥塞:**当网络中存在过多的报文时,网络的性能就会相应下降,这种现象就被成为拥塞。

TCP拥塞控制
拥塞窗口CWND:窗口值的大小就代表能够发送出去的但还没有收到ACK的最大数据报文段,显然窗口越大那么数据发送的速度也就越快,但是也有越可能使得网络出现拥塞,如果窗口值为1,那么就简化为一个停等协议,每发送一个数据,都要等到对方的确认才能发送第二个数据包,显然数据传输效率低下。TCP的拥塞控制算法就是要在这两者之间权衡,选取最好的CWND值,从而最大化网络吞吐量的同时不产生网络拥塞。

**发送窗口SWND:**拥塞控制最终受控变量是发送端向网络一次连续写入的数据量,即发送窗口(SWND),TCP报文段的最大长度(数据部分)称为SMSS,其值一般等于MSS(MTU-40,20字节的IP头和20字节的TCP头)。发送端需要合理的选择SWND的大小,如果太小,会引起明显的网络延迟,反之,则容易导致网络拥塞。TCP的拥塞控制主要原理依赖于一个拥塞窗口来控制。实际的SWND=min(RWND,CWND)。关于CWND的单位,在TCP中是以字节来做单位的,我们假设TCP每次传输都是按照MSS大小来发送数据的,因此你可以认为CWND按照数据包个数来做单位也可以理解,所以有时我们说CWND增加1也就是相当于字节数增加1个MSS(在TCP连接建立时,收发双方协商通信时每一个报文段所能承载的最大数据长度)大小。

**<1>慢启动:**最初的TCP在连接建立成功后会向网络中发送大量的数据包,这样很容易导致网络中路由器缓存空间耗尽,从而发生拥塞。因此新建立的连接不能够一开始就大量发送数据包,而只能根据网络情况逐步增加每次发送的数据量,以避免上述现象的发生。具体来说,当新建连接时,CWND初始化为2~4个MSS大小,发送端开始按照拥塞窗口大小发送数据,每当有一个报文段被确认,CWND就增加1个MSS大小。这样CWND的值就随着网络往返时间(Round Trip Time,RTT)呈指数级增长,事实上,慢启动的速度一点也不慢,只是它的起点比较低一点而已。我们可以简单计算下:

开始 —> CWND= 1
经过1个RTT后 —> CWND = 1+1 = 2 //12
经过2个RTT后 —> CWND= 2+2 = 4 //2
2
经过3个RTT后 —> CWND= 4+4 = 8 //42
如果带宽为W,那么经过RTT
log2W时间就可以占满带宽。
1
2
3
4
5
**<2>拥塞避免:**从慢启动可以看到,CWND可以很快的增长上来,从而最大程度利用网络带宽资源,但是CWND不能一直这样无限增长下去,一定需要某个限制。TCP使用了一个叫慢启动门限(ssthresh)的变量,当CWND超过该值后,慢启动过程结束,进入拥塞避免阶段。拥塞避免的主要思想是加法增大,也就是CWND的值不再指数级往上升,开始加法增加。此时当窗口中所有的报文段都被确认时,CWND的大小加1,CWND的值就随着RTT开始线性增加,这样就可以避免增长过快导致网络拥塞,慢慢的增加调整到网络的最佳值。

上面讨论的两个机制都是没有检测到拥塞的情况下的行为,那么当发现拥塞了CWND又该怎样去调整呢?

从整体上来讲,TCP拥塞控制窗口变化的原则是加法增大、乘法减小。可以看出TCP的该原则可以较好地保证流之间的公平性,因为一旦出现丢包,那么立即减半退避,可以给其它新建的流留有足够的空间,从而保证整个网络的公平性。

****<3>超时重传:****TCP协议在发送数据以后,每一个报文段都会有一个重传定时器(RTO),在定时器指定的时间内接收端对于这个报文的确认报文如果没有到达,则会重新发送一次,并且这次的定时器时间为上次的两倍。

把ssthresh设置为max(已经发送但是未收到确认的字节数/2,2*MSS)
重新进入慢启动过程。
1
2
**<4>快速重传:**那就是连续收到3个相同的ACK。TCP利用3个相同的ACK来判定数据包的丢失,此时进行快速重传,快速重传做的事情有:

把ssthresh设置为max(已经发送但是未收到确认的字节数/2,2MSS)
把CWND再设置为ssthresh的值(具体实现有些为ssthresh+3
MSS)
每收到一个重复的ack时,就将CWND设置为CWND+MSS
收到新的ack就将CWND设置为ssthresh
重新进入拥塞避免阶段。
1
2
3
4
5
<5>快速恢复:快速恢复算法是在上述的“快速重传”算法后添加的,当收到3个重复ACK时,TCP最后进入的不是拥塞避免阶段,而是快速恢复阶段。快速重传和快速恢复算法一般同时使用。快速恢复的思想是“数据包守恒”原则,即同一个时刻在网络中的数据包数量是恒定的,只有当“老”数据包离开了网络后,才能向网络中发送一个“新”的数据包,如果发送方收到一个新的ACK,那么根据TCP的ACK机制就表明有一个数据包离开了网络,于是CWND加1。如果能够严格按照该原则那么网络中很少会发生拥塞,事实上拥塞控制的目的也就在修正违反该原则的地方。

快速恢复的主要步骤是:
①当收到3个重复ACK时,把ssthresh设置为CWND的一半,把cwnd设置为ssthresh的值加3,然后重传丢失的报文段,加3的原因是因为收到3个重复的ACK,表明有3个“老”的数据包离开了网络。
②再收到重复的ACK时,拥塞窗口增加1。
③当收到新的数据包的ACK时,把CWND设置为第一步中的ssthresh的值。原因是因为该ACK确认了新的数据,说明从重复ACK时的数据都已收到,该恢复过程已经结束,可以回到恢复之前的状态了,也即再次进入拥塞避免状态。

<6>选择性应答(SACK):比如序号1,2,3,5,7的数据收到了,那么普通的ACK只会确认序列号4,而SACK会把当前的5,7已经收到的信息在SACK选项里面告知对端,从而提高性能,当使用SACK的时候,因为SACK本身携带的信息就可以使得发送方有足够的信息来知道需要重传哪些包,而不需要重传哪些包。


版权声明:本文为CSDN博主「我很ran」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_37201462/article/details/79116318

发布了18 篇原创文章 · 获赞 2 · 访问量 3135

猜你喜欢

转载自blog.csdn.net/shiningdreamercaihua/article/details/104918128
今日推荐