TCP拥塞控制(Congestion Control)
什么是拥塞控制?
拥塞控制(Congestion Control)主要针对整个网络中的数据传输速率进行调节,防止过多的数据注入网络中,这样可以使网络中的路由器或链路不致于过载,以避免网络拥塞和丢包现象的发生。
拥塞控制是一个全局性的过程,和流量控制(滑动窗口)不同,流量控制指点对点通信量的控制。
为了防止网络的拥塞现象,TCP提出了一系列的拥塞控制机制。最初由VJacobson在1988年的论文中提出的TCP的拥塞控制由“慢启动(Slow start)”和“拥塞避免(Congestion avoidance)”组成,后来TCP Reno版本中又针对性的加入了“**快速重传(Fast retransmit)”“快速恢复(Fast Recovery)**算法。
TCP的拥塞控制主要原理依赖于一个**拥塞窗口(cwnd)**来控制,窗口值的大小就代表能够发送出去的但还没有收到ACK的最大数据报文段,显然窗口越大那么数据发送的速度也就越快,但是也有越可能使得网络出现拥塞。
由于需要考虑拥塞控制和流量控制两个方面的内容,因此TCP的真正的发送窗口=min(rwnd,cwnd)。但是rwnd是由对端确定的,网络环境对其没有影响,所以在考虑拥塞的时候我们一般不考虑rwnd的值我们暂时只讨论如何确定cwnd值的大小。关于cwnd的单位,在TCP中是以字节来做单位的,我们假设TCP每次传输都是按照MSS大小来发送数据的,因此你可以认为cwnd按照数据包个数来做单位也可以理解,所以有时我们说cwnd增加1也就是相当于字节数增加1个MSS大小(Maximum SegmentSize)。
判断出现网络拥塞的依据:当出现丢包事件时,也就是要么出现①超时事件,要么②收到三个ACK(一个正常的ACK+三个冗余的ACK),发送方就认为发送方到接收方的路径上出现拥塞
- 超时:TCP 实现可靠传输依赖的是超时重传机制(Retransmission Timeout)。TCP 在完每个数据包后,会启动一个重传定时器(RTO)。如果在定时器超时前没收到接收方发来的(认为数据丢了),就重传数据。
- 三个连续冗余ACK:当网络不拥塞时,发生报文段丢失(当接收方收到不连续的数据包时),为了让发送方尽早知道发生了个别报文段的丢失,因此立即发送一个重复确认,怎样让发送方知道是哪个报文丢失的方法就是连读发送三个重复确认。然后立即启动快速重传。
拥塞控制算法
TCP通过拥塞控制算法:慢启动、拥寒避免、快速重传和快速恢复算法
慢启动
最初的TCP在连接建立成功后会向网络中发送大量的数据包,这样很容易导致网络中路由器缓存空间耗尽,从而发生拥塞。因此新建立的连接不能够一开始就大量发送数据包,而只能根据网络情况逐步增加每次发送的数据量,以避免上述现象的发生。
具体来说,当新建连接时,cwnd=1,cwnd初始化为1个最大报文段,(MSS)大小,发送端开始按照拥塞窗口大小发送数据,每当有一个报文段被确认,cwnd=cwnd+1,cwnd就增加1个MSS大小。这样cwnd的值就随着网络往返时间(Round Trip Time,RTT)呈指数级增长,事实上,慢启动的速度一点也不慢,只是它的起点比较低而已。
拥塞避免
从慢启动可以看到,cwnd可以很快的增长上来,从而最大程度利用网络带宽资源,但是这样无限增长下去,一定需要某个限制。TCP使用了一个叫慢启动阈值(ssthresh)的变量cwnd>ssthresh后,慢启动过程结束,进入拥塞避免阶段。
对于大多数TCP实现来说,ssthresh的值是65536(同样以字节计算)。拥塞避免的主要思也就是cwnd的值不再指数级往上升,开始加法增加。此时当窗口中所有的报文段都被确大小加1,cwnd的值就随着RTT开始线性增加,这样就可以避免增长过快导致网络拥塞整到网络的最佳值。
上面讨论的两个机制都是没有检测到拥塞的情况下的行为,那么当发现拥塞了cwnd又该怎样去调整呢?
首先来看TCP是如何确定网络进入了拥塞状态的,TCP认为网络拥塞的主要依据是它重传了一个报文段上面提到过,TCP对每一个报文段都有一个定时器,称为重传定时器(RTO),当RTO超时且还没有得到数据确认,那么TCP就会对该报文段进行重传,当发生超时时,那么出现拥塞的可能性就很大,某个报文段可能在网络中某处丢失,并且后续的报文段也没有了消息,在这种情况下,TCP反应比较“强烈”
1.ssthresh=cwnd/2,即把ssthresh降低为cwnd值的一半
2.cwnd=1,即把cwnd重新设置为1
3.重新进入慢启动过程。
从整体上来讲,TCP拥塞控制窗口变化的原则是AIMD原则,即加法增大、乘法减小。可以看出TCP的该原则可以较好地保证流之间的公平性,因为一旦出现丢包,那么立即减半退避,可以给其他新建的流留有足够的空间,从而保证整个的公平性
快速重传
其实TCP还有一种情况会进行重传:那就是收到3个相同的ACK。TCP在收到乱序到达包时就会立即发ACK,TCP利用3个相同的ACK来判定数据包的丢失,此时进行快速重传,快速重传做的事情有:
1.ssthresh=cwnd/2,即把ssthresh设置为cwnd的一半
2.cwnd=ssthresh,即把cwnd再设置为ssthresh的值**(具体实现有些为ssthresh+3)**
3.重新进入拥塞避免阶段
快速恢复
“快速恢复”算法是在上述的“快速重传”算法后添加的,快速重传和快速恢复算法一般同时使用
具体来说快速恢复的主要步骤是:
-
当收到3个重复ACK时,ssthresh=cwnd/2,把ssthresh设置为cwnd的一半,把cwnd设置为ssthresh的值加3,然后重传丢失的报文段,加3的原因是因为收到3个重复的ACK,表明有3个“老的数据包离开了网络。
-
再收到重复的ACK时,cwnd =cwnd +1,拥塞窗口增加1。
-
当收到新的数据包的ACK时,cwnd=ssthresh,把cwnd设置为第一步中的ssthresh的值。原因是因为该ACK确认了新的数据,说明从重复ACK时的数据都已收到,该恢复过程已经结束,可以回到恢复之前的状态了,也即再次进入拥塞避免状态。
拥塞控制流程图
-
无论是在慢启动阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞,就把慢启动阈值设置为出现拥塞时的发送窗口大小的一半。然后把拥塞窗白设置为1,执行慢启动算法。
-
快速恢复是TCP推荐的而非必须的构件。一种称为 TCTahoe的TCP早期版本,不管是发生超时指示的丢包事件,还是发生3个冗余 ACK 指示的丢包事件,都无条件地将其拥塞窗口减至 1个MSS,并进入慢启动阶段。TCP 的较新版本TCP Reno,则综合了快速恢复。
拥塞窗口和滑动窗口的区别:
拥塞窗口和滑动窗口是计算机网络中两种不同的概念,拥塞窗口是用于网络拥塞控制的,而滑动窗口则是用于流量控制的。以下是两者的区别:
- 拥塞窗口(Congestion Window)主要用于TCP拥塞控制,它的作用是限制发送方发送数据的速率以防止网络拥塞。拥塞窗口的大小是动态调整的,取决于网络当前的拥塞状况。如果网络拥堵,拥塞窗口会减小;如果网络畅通,拥塞窗口会增大。拥塞控制的目的是确保网络的稳定和高效运行,避免因为数据传输过快而导致网络资源不足。
- 滑动窗口(Sliding Window)主要用于流量控制,它的作用是控制发送方的数据发送速率,以确保接收方来得及接收数据。滑动窗口的大小由接收方根据其缓存大小和处理能力动态调整,并通过确认报文(ACK)通知发送方。如果接收方缓存已满,它会减小窗口大小,告诉发送方慢下来;如果缓存有空余,接收方会增大窗口大小,允许发送方发送更多数据。滑动窗口的大小是动态改变的,故得名“滑动窗口”
- 简而言之,拥塞窗口关注的是整个网络的拥塞状况,而滑动窗口关注的是发送方和接收方之间的数据流量状况。
更多数据。滑动窗口的大小是动态改变的,故得名“滑动窗口” - 简而言之,拥塞窗口关注的是整个网络的拥塞状况,而滑动窗口关注的是发送方和接收方之间的数据流量状况。