简介
** 拥塞 ** :即对资源的需求超过了可用的资源。当网络中资源供应不足,导致出现资源竞争时,就会出现拥塞现象,拥塞会降低网络性能和吞吐量。
** 拥塞控制 ** :通过控制数据注入到网络中的速率来尽可能避免网络出现拥塞,从而使网络中的路由器或链路不致过载。前提:网络能够承受现有的网络负荷。拥塞控制是一个全局性的过程,涉及到所有的主机、路由器,以及与降低网络传输性能有关的其他因素。
** 流量控制 ** :流量控制所要做的就是抑制发送端发送数据的速率,以便使接收端来得及接收。是一个端到端的控制过程。
** 拥塞控制代价 ** :拥塞控制需要获得网络内部流量分布的信息。因此在实施拥塞控制之前,需要在结点之间交换信息和各种命令,以便选择控制的策略和实施控制,这样就产生了额外的开销。拥塞控制还需要将一些资源分配给各个用户单独使用,使得网络资源不能更好地实现共享。
控制算法
发送方控制拥塞窗口的 ** 原则 ** 是:只要网络没有出现拥塞,拥塞窗口就再增大一些,以便把更多的分组发送出去。但只要网络出现拥塞,拥塞窗口就减小一些,以减少注入到网络中的分组数。
慢开始
在 TCP 连接开始传输数据时,先将拥塞窗口 cwnd 设为 1 个 MSS(最大报文段),每当收到一个报文段的确认,就将 cwnd+1,因此,每经过一个传输轮次 RTT,cwnd 的大小就加倍,直至 cwnd 大小达到预设的慢开始门限值 ssthresh。
一个传输轮次所需时间为一个往返时间 RTT,但 ** 传输轮次强调的是将一个 cwnd 窗口中所允许发送的报文段全都发送出去并且都接收到对应于最后一个报文段的确认报文 ** 。
慢开始中的“慢”并非指传输速率很慢,而是说开始的时候将 cwnd 设为 1,使得发送方最开始只能发送一个报文段(目的在于试探当前网络的拥塞状况),然后再 ** 指数增长 ** cwnd 的大小。
** 慢开始门限值 ssthresh ** :因为慢开始算法以指数型式增长,所以为了防止后期因为cwnd 窗口增长过快而导致网络出现拥塞,需要设置一个慢开始的门限值,当 cwnd 增长至门限值大小时,停止采用慢开始算法而改用拥塞避免算法。
当 cwnd < ssthresh 时,使用慢开始算法;
当 cwnd > ssthresh 时,停止使用慢开始算法而改用拥塞避免算法;
当 cwnd = ssthresh 时,既可使用慢开始算法,也可使用拥塞控制避免算法。
拥塞避免
让拥塞窗口以 ** 线性增长 ** 的方式缓慢增大,从而减少注入到网络中的数据,以尽量避免网络拥塞。具体而言,每经过一个传输轮次才将发送方的 cwnd+1,而非每接收到一个确认报文就加 1,这样的话,每经过一个传输轮次,拥塞窗口才增长了 1 个 MSS,而非加倍,cwnd 呈线性增长而非指数增长,由此可知,拥塞避免算法的 cwnd 增长速率比慢开始算法慢很多。
“拥塞避免”并非指完全能够避免了拥塞。利用以上的措施要完全避免网络拥塞还是不可能的。“拥塞避免”是说在拥塞避免阶段将拥塞窗口控制为按线性规律增长,使网络比较不容易出现拥塞。
** 注意 ** :无论在慢开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞(根据就是没有收到确认),就要把慢开始门限 ssthresh 设置为出现拥塞时的发送方窗口值的一半(但不能小于 2)。然后把拥塞窗口 cwnd 重新设置为 1,执行慢开始算法。这样做的目的就是要迅速减少主机发送到网络中的分组数,使得发生拥塞的路由器有足够时间把队列中积压的分组处理完毕。
快重传
快重传算法首先要求接收方每收到一个失序的报文段后就 ** 立即 ** 发出重复确认(为的是使发送方及早知道有报文段没有到达对方)而不要等到自己发送数据时才进行捎带确认。快重传算法还规定,发送方只要一连收到 ** 三个重复确认 ** 就应当立即重传对方尚未收到的报文段,而不必继续等待设置的重传计时器到期。由于发送方尽早重传未被确认的报文段,因此采用快重传后可以使整个网络吞吐量提高。
快恢复
当发送方连续收到三个重复确认,就执行“乘法减小”算法,把慢开始门限 ssthresh ** 减半 ** 。这是为了预防网络发生拥塞。由于发送方现在认为网络很可能没有发生拥塞,因此与慢开始不同之处在于现在 ** 不执行慢开始算法 ** (即拥塞窗口 cwnd 现在不设置为 1),而是把 cwnd 值设置为慢开始门限 ssthresh 减半后的数值,然后开始执行 ** 拥塞避免算法 ** (“加法增大”),使拥塞窗口缓慢地线性增大。
基于上述四个算法的拥塞避免流程:
TCP 连接建立后,将发送方 cwnd 设为 1(MSS),并设置慢开始门限值 ssthresh,执行慢开始算法指数增长 cwnd。当 cwnd 达到 ssthresh 时改用拥塞避免算法线性增长 cwnd。如果在数据传输过程中出现超时还未收到确认报文的情况,意味着有可能出现网络拥塞,将ssthresh 设为该时刻的 cwnd 的一半,cwnd 设为 1,重新执行慢开始算法。如果在数据传输过程中接收方收到失序的报文段,就采用快重传算法立即发送重复的确认报文,发送方接收到 3 个相同的确认报文后,意味着有报文丢失,就采用快恢复算法将 ssthresh 和 cwnd 均设为出现拥塞时的cwnd的一半,重新执行拥塞避免算法。转换图如下:(图片来源:TCP的流量控制和拥塞控制)
总结
在采用快恢复算法时,慢开始算法只是在 TCP 连接建立时和网络出现超时时才使用。采用这样的拥塞控制方法使得 TCP 的性能有明显的改进。
接收方根据自己的接收能力设定了接收窗口 rwnd,并把这个窗口值写入 TCP 首部中的窗口字段,传送给发送方,接收窗口又称为 ** 通知窗口 ** 。因此,从接收方对发送方的流量控制的角度考虑,发送方的发送窗口一定不能超过对方给出的接收窗口 rwnd 。所以 ** 发送方窗口的上限值 = Min [ rwnd, cwnd ] :**
当rwnd < cwnd 时,是接收方的接收能力限制发送方窗口的最大值;
当cwnd < rwnd 时,则是网络的拥塞限制发送方窗口的最大值。