- 拥塞控制是为了降低整个网络的拥塞程度
- 流量控制是为了照顾接收方的接收能力
- 如果网络出现拥塞,分组将会可能丢失,此时发送方会继续重传,从而导致网络拥塞程度更高,因此当出现网络拥塞时,应当控制发送方的速率。
TCP主要通过四种算法来进行拥塞控制:慢开始、拥塞避免、快重传、快恢复
发送方需要维护一个叫做拥塞窗口的状态变量,注意拥塞窗口与发送窗口的区别:拥塞窗口只是一个状态变量,实际决定发送方能发送多少数据的是发送方窗口。
为了方便讨论,做出如下假设:
- 接收方有足够大的接收缓存,因此不会发生流量控制;
- 虽然TCP的窗口基于字节,但是这里设窗口的大小单位为报文段。
总体流程
- 发送方维持一个拥塞窗口cwnd
- cwnd维护原则:网络中没有出现拥塞,拥塞窗口就增大一些;一旦出现网络拥塞,拥塞窗口就减小一些
- 判断出现网络拥塞的依据:有没有按时收到应当到达的确认报文,即发生超时重传。
- 发送方将拥塞窗口作为发送窗口,即swnd=min(cwnd,rwnd);即发送窗口随拥塞窗口变化而变化(rwnd是接收窗口)
- 维护一个慢开始门限ssthresh状态变量(slow start threshold)
- 当cwnd<ssthresh时,使用慢开始算法
- 当cwnd>ssthresh时,使用拥塞避免算法
- 当cwnd=ssthresh时,既可以使用慢开始,也可以使用拥塞避免算法
慢开始算法:
- 起始时将cwnd设置为1;
- 拥塞窗口随指数性增长,即1,2,4,8,16;
拥塞避免算法
- 拥塞窗口随线性增长,每次增加1
出现超时重传,ssthresh置为cwnd的一半,并开始慢开始(cwnd置为1)
快速重传算法
- 快重传就是发送方尽快地重传,而不是等待超时计时器超时后再重传
- 所以要求接收方不要等待自己发送数据时才捎带确认,而是要立即发送确认。
- 即使收到了失序报文段,也要立即发送对已收到的有序的报文段重复确认
- 发送方一旦收到 连续三个重复确认(首次确认不算重复确认)就立即将相应的报文重传,不是等待该报文的超时计数器超时再进行重传
- 所以对与个别丢失的报文段,发送方也不会出现 超时重传 所以也不会误以为出现了拥塞(因为发送方是根据是否产生了超时重传而判断是否出现网络拥塞)
快恢复算法
- 发送方一旦收到三个重复确认,就会知道出现了个别报文段丢失的情况。于是不启动慢开始算法,而是启动快速恢复算法
- 将ssthresh值和拥塞窗口cwnd值调整为当前窗口的一半,然后开始拥塞避免算法
- 也有的快速恢复实现是把快恢复开始时的拥塞窗口cwnd值再增大一点,即等于新的ssthresh+3
- 因为发送方收到三个重复确认,表明有三个数据报文段已经离开网络
- 这三个报文段已经停留再接收方的接收缓存里面了
- 拥塞网络中堆积的报文段应该减少三个报文段,所以可以适当调大拥塞窗口
补充:一定要区分
- 超时重传:触发慢开始算法
- 快速重传:触发拥塞避免算法