求助,TCP启动慢是什么意思(附详情)?

为了防止网络拥塞,TCP提出了一系列拥塞控制机制。TCP的拥塞控制,最初是由V. Jacobson在1988的论文中提出的,由“慢启动”和“拥塞避免”组成。后来在TCP Reno版本中加入了“快速重传”和“快速恢复”算法,然后在TCP NewReno中改进了“快速恢复”算法。近年来,选择性确认(SACK)算法出现,并有其他改进,成为网络研究的热点。

TCP拥塞控制的主要原理依赖于拥塞窗口(cwnd)。在此之前,我们还讨论了TCP也有一个接收窗口(rwnd ),用于流量控制的对等通知。窗口的大小表示可以发送出去但尚未收到ACK的最大数据段。显然,窗口越大,数据传输速度会越快,但也更容易造成网络拥塞。如果窗口值是1,它将被简化为一个停止等待协议。每次发送一个数据,都要等对方确认后再发送第二个数据包。显然,数据传输效率较低。TCP的拥塞控制算法就是平衡两者,选择最佳的cwnd值,使网络吞吐量最大化,不产生拥塞。

因为需要考虑拥塞控制和流量控制,所以TCP的真实传输窗口=min(rwnd,cwnd)。但是rwnd是由对等体决定的,网络环境对其没有影响,所以我们在考虑拥塞时一般不考虑rwnd的值,暂时只讨论如何确定cwnd的值。至于cwnd的单位,在TCP中是以字节为单位的。我们假设TCP每次传输都是按照MSS的大小来发送数据的,那么你可以认为cwnd是按照包的数量以单位来表示是可以理解的,所以有时候我们说cwnd增加1,也就是说字节数增加了1 MSS。

启动慢:初始TCP在连接建立成功后会向网络发送大量数据包,容易导致网络中路由器缓存空间耗尽,从而造成拥塞。因此,新建立的连接在开始时不能发送大量的数据包,只能根据网络情况逐渐增加每次发送的数据量来避免上述现象。具体来说,当一个新的连接建立时,cwnd被初始化为1最大消息段(MSS)的大小,发送方根据拥塞窗口大小开始发送数据。每当确认一个消息段时,cwnd增加1毫秒。这样,cwnd的值随着网络的往返时间(RTT)成指数增加。其实慢启动的速度一点都不慢,只是起点比较低。我们可以简单地计算:

开始-> cwnd = 1

1 RTT之后-> cwnd = 2*1 = 2

经过2个RTT-> cwnd = 2 * 2 = 4

3个RTT之后-> cwnd = 4*2 = 8

如果带宽是w,那么RTT*log2W后带宽可以被完全占用。

拥塞避免:从慢启动可以看出,cwnd可以快速成长,从而最大限度地利用网络带宽资源,但cwnd不可能无限期地这样增长下去,它必然需要一些限制。TCP使用一个称为慢启动阈值(ssthresh)的变量。当cwnd超过该值时,慢启动过程结束,进入拥塞避免阶段。对于大多数TCP实现,ssthresh的值是65536(也以字节计算)。拥塞避免的主要思想是加性增加,即cwnd的值不再呈指数上升,而是开始加性增加。此时,当窗口中的所有报文段都被确认后,cwnd的大小增加1,cwnd的值开始随RTT线性增加,以避免过快增长造成的网络拥塞,慢慢增加并调整到网络的最优值。

上面讨论的两种机制都是没有检测到拥塞时的行为,那么发现拥塞时如何调整cwnd呢?

首先,我们来看看TCP是如何确定网络进入拥塞状态的。TCP认为网络拥塞的主要依据是它重传了一个报文段。如上所述,TCP对每个消息段都有一个计时器,称为重传计时器(RTO)。当RTO超时且数据未被确认时,TCP将重新传输消息段。当超时发生时,很有可能出现拥塞。一个消息段可能在网络的某个地方丢失,后续的消息段没有消息。在这种情况下,TCP的响应是“强有力的”:

1.将ssthresh减少到cwnd值的一半。

2.将cwnd重置为1。

3.重新进入慢启动过程。

总体来说,TCP拥塞控制窗口变化的原理是AIMD原理,即加法增加,乘法减少。可以看出,TCP的这种原理可以更好地保证流之间的公平性,因为一旦发生丢包,可以立即后退一半,可以为其他新创建的流留下足够的空间,从而保证整体的公平性。

其实还有一种情况TCP会重传:就是收到三个相同的ack。当TCP收到无序到达的数据包时,它会立即发送ACK。TCP使用三个相同的ack来确定数据包的丢失。此时,进行快速重传。快速重传的作用如下:

1.将ssthresh设置为cwnd的一半。

2.将cwnd设置为ssthresh的值(有些实现是ssthresh+3)。

3.重新进入拥塞避免阶段。

后来,在上述“快速重传”算法之后,又增加了“快速恢复”算法。当收到三个重复的ack时,TCP最终进入快速恢复阶段,而不是拥塞避免阶段。快速重传和快速恢复算法通常同时使用。快速恢复的思想是“包守恒”原理,即网络中同时存在的包数是不变的,只有当“旧”包离开网络时,才有“新”包发送到网络。如果发送方收到重复的ACK,那么根据TCP的ACK机制,表示有一个包已经离开了网络,所以cwnd加上1。如果能严格遵循这个原则,网络就很少会出现拥塞。事实上,拥塞控制的目的是纠正违反这一原则的地方。

具体来说,快速恢复的主要步骤是:

1.当收到三个重复的ack时,将ssthresh设置为cwnd的一半,并将cwnd设置为ssthresh加3的值,然后重新发送丢失的消息段。添加3的原因是接收到三个重复的ack,指示三个“旧”分组已经离开网络。

2.当接收到重复的ACK时,拥塞窗口将增加1。

3.当接收到新数据包的ACK时,在第一步中将cwnd设置为ssthresh的值。原因是ACK确认了新的数据,说明重复ACK的所有数据都已经收到,恢复过程已经结束,可以回到恢复前的状态,即再次进入拥塞避免状态。

快速重传算法最早出现在Tahoe版本的4.3BSD中,快速恢复最早出现在Reno版本的4.3BSD中,也称为Reno版本的TCP拥塞控制算法。

可以看出,Reno的快速重传算法针对的是一个包的重传。然而,在实践中,重传超时可能导致许多分组的重传,因此当多个分组从数据窗口丢失并且快速重传和快速恢复算法被触发时,问题就出现了。于是出现了NewReno,在Reno快速恢复的基础上稍加修改,可以恢复一个窗口内丢失多个包的情况。具体来说,Reno在接收到新数据的ACK时退出快速恢复状态,而NewReno只会在接收到窗口内所有数据包的确认后才退出快速恢复状态,从而进一步提高吞吐量。

SACK是为了改变TCP的确认机制。一开始TCP只对连续接收的数据进行确认,而SACK会把所有信息乱序的告诉对方,减少数据发送方重传的盲目性。比如接收到序列号1,2,3,5,7的数据,那么普通ACK只会确认序列号4,SACK会在SACK选项中通知对端当前5,7的接收信息,从而提高性能。使用SACK时,不能使用NewReno算法,因为SACK本身携带的信息可以让发送方有足够的信息知道哪些包需要重传,而不是。

也可以参考和;被介绍。