TCP的流量控制和拥塞控制
1 流量控制
1.1 什么是流量控制?
流量控制就是控制发送端发送数据的速率,让接收端来得及接受数据,不至于使得数据丢失,是一种端到端的控制方式。
1.2 如何实现流量控制?
使用滑动窗口机制进行流量控制。
在TCP的确认应答机制中,每发送一次数据,都需要接收端进行一次ACK确认,发送方收到ACK后才可以进行下一次发送,这样做就有一个比较大的缺陷,就是传输性能比较差,特别是在数据往返所需要时间较长的时候。用滑动窗口可以在每次回复ACK的时候,通知接收方剩余数据缓冲区的大小,则发送方可以一次性发送满足缓冲区的数据而不需要中途再进行ACK确认。
流量控制就是使用滑动窗口来通知发送端可以发送数据的大小,进而控制发送端发送数据的速率。
tip:
- 接收端每次将所剩余的缓冲区大小填入TCP首部的滑动窗口字段中,通过ACK来通知发送端
- 窗口越大,说明吞吐量越大
- 窗口大小指的是发送端可以一次性发送给接收端而不需要中途再进行ACK确认的数据大小
- 接收端一旦发现缓冲区快满了,就会设置一个更小的窗口值来通知发送端,发送端进而减慢数据的发送速度
- TCP的首部有一个16字节的窗口字段,存放窗口信息,滑动窗口中的数据类型由两部分组成:
已经发送但是还没收到确认的
、可以发送但是没有发送的
如果接收端的缓冲区满了,就会设置窗口为0,则发送方停止数据发送,但会启动一个计时器,定期发送一个窗口探测的数据段,让接收端把新的窗口大小发给发送端,防止窗口为0导致的死锁
2 拥塞控制
2.1 为什么要有拥塞控制?
流量控制虽然可以高效可靠的传送大量的数据,但是如果在刚开始阶段就发送大量的数据,可能会导致网络拥堵。
2.2 拥塞控制和流量控制的区别?
- 拥塞控制:是为了防止过多的数据注入到网络中,使网络过载,性能变差。拥塞控制是一个全局性的过程,涉及到所有的主机、路由器,以及与降低网络传输性能有关的所有因素,它执行的前提是获取网络信息。
- 流量控制:指端对端的通信量的控制。流量控制所要做的就是抑制发送端发送数据的速率,以便使接收端来得及接收。
2.3 拥塞控制的原理和方式?
拥塞指的是发送的数据量太多,网络来不及处理,从而导致网络拥塞,性能变差的现象。
拥塞控制的方法主要有四种:
- 慢开始( slow-start )
- 拥塞避免( congestion avoidance )
- 快重传( fast retransmit )
- 快恢复( fast recovery )
慢开始算法:当主机开始发送数据时,如果立即所大量数据字节注入到网络,那么就有可能引起网络拥塞,因为现在并不清楚网络的负荷情况。因此,较好的方法是先探测一下,即由小到大逐渐增大发送窗口,也就是说,由小到大逐渐增大拥塞窗口数值。通常在刚刚开始发送报文段时,先把拥塞窗口 cwnd 设置为一个最大报文段MSS的数值。而在每收到一个对新的报文段的确认后,把拥塞窗口增加至多一个MSS的数值。用这样的方法逐步增大发送方的拥塞窗口 cwnd ,可以使分组注入到网络的速率更加合理。
每经过一个传输轮次,拥塞窗口 cwnd 就加倍。一个传输轮次所经历的时间其实就是往返时间RTT。不过“传输轮次”更加强调:把拥塞窗口cwnd所允许发送的报文段都连续发送出去,并收到了对已发送的最后一个字节的确认。另,慢开始的“慢”并不是指cwnd的增长速率慢,而是指在TCP开始发送报文段时先设置cwnd=1,使得发送方在开始时只发送一个报文段(目的是试探一下网络的拥塞情况),然后再逐渐增大cwnd。
为了防止拥塞窗口cwnd增长过大引起网络拥塞,还需要设置一个慢开始门限ssthresh状态变量(如何设置ssthresh)。慢开始门限ssthresh的用法如下:
- 当 cwnd < ssthresh 时,使用上述的慢开始算法。
- 当 cwnd > ssthresh 时,停止使用慢开始算法而改用拥塞避免算法。
- 当 cwnd = ssthresh 时,既可使用慢开始算法,也可使用拥塞控制避免算法。
拥塞避免算法:让拥塞窗口cwnd缓慢地增大,即每经过一个往返时间RTT就把发送方的拥塞窗口cwnd加1,而不是加倍。这样拥塞窗口cwnd按线性规律缓慢增长,比慢开始算法的拥塞窗口增长速率缓慢得多。
无论在慢开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞(其根据就是没有收到确认),就要把慢开始门限ssthresh设置为出现拥塞时的发送方窗口值的一半(但不能小于2)。然后把拥塞窗口cwnd重新设置为1,执行慢开始算法。这样做的目的就是要迅速减少主机发送到网络中的分组数,使得发生拥塞的路由器有足够时间把队列中积压的分组处理完毕。
让拥塞窗口cwnd缓慢地增大,即每经过一个往返时间RTT就把发送方的拥塞窗口cwnd加1,而不是加倍。这样拥塞窗口cwnd按线性规律缓慢增长,比慢开始算法的拥塞窗口增长速率缓慢得多。
快重传: 快重传算法首先要求接收方每收到一个失序的报文段后就立即发出重复确认(为的是使发送方及早知道有报文段没有到达对方)而不要等到自己发送数据时才进行捎带确认。
接收方收到了M1和M2后都分别发出了确认。现在假定接收方没有收到M3但接着收到了M4。显然,接收方不能确认M4,因为M4是收到的失序报文段。根据可靠传输原理,接收方可以什么都不做,也可以在适当时机发送一次对M2的确认。但按照快重传算法的规定,接收方应及时发送对M2的重复确认,这样做可以让发送方及早知道报文段M3没有到达接收方。发送方接着发送了M5和M6。接收方收到这两个报文后,也还要再次发出对M2的重复确认。这样,发送方共收到了接收方的四个对M2的确认,其中后三个都是重复确认。快重传算法还规定,发送方只要一连收到三个重复确认就应当立即重传对方尚未收到的报文段M3,而不必继续等待M3设置的重传计时器到期。由于发送方尽早重传未被确认的报文段,因此采用快重传后可以使整个网络吞吐量提高约20%。
快恢复:快恢复算法是与快重传算法进行搭配使用的。
<1> 当发送方连续收到三个重复确认,就执行“乘法减小”算法,把慢开始门限ssthresh减半。这是为了预防网络发生拥塞。请注意:接下去不执行慢开始算法。
<2> 由于发送方现在认为网络很可能没有发生拥塞,因此与慢开始不同之处是现在不执行慢开始算法(即拥塞窗口cwnd现在不设置为1),而是把cwnd值设置为慢开始门限ssthresh减半后的数值,然后开始执行拥塞避免算法(“加法增大”),使拥塞窗口缓慢地线性增大。
采用这样的拥塞控制方法使得TCP的性能有明显的改进
- 接收方根据自己的接收能力设定了接收窗口rwnd,并把这个窗口值写入TCP首部中的窗口字段,传送给发送方。因此,接收窗口又称为通知窗口。因此,从接收方对发送方的流量控制的角度考虑,发送方的发送窗口一定不能超过对方给出的接收窗口rwnd 。
- 发送方窗口的上限值 = Min [ rwnd, cwnd ]