TCP流量控制与滑动窗口

1,974 阅读5分钟

流量控制

为什么需要流量控制?

  • 双方在通信的时候,发送方的速率与接收方的速率是不一定相等,如果发送方的发送速率太快,会导致接收方处理不过来,这时候接收方只能把处理不过来的数据存在缓存区里
  • 如果缓存区满了发送方还在疯狂着发送数据,接收方只能把收到的数据包丢掉,大量的丢包会极大着浪费网络资源,因此,我们需要控制发送方的发送速率,让接收方与发送方处于一种动态平衡才好 ** 对发送方发送速率的控制,我们称之为流量控制。 **

如何控制?

  • 接收方每次收到数据包,可以在发送确定报文的时候,同时告诉发送方自己的缓存区还剩余多少是空闲的,我们也把缓存区的剩余大小称之为接收窗口大小,用变量win来表示接收窗口的大小。
  • 发送方收到之后,便会调整自己的发送速率,也就是调整自己发送窗口的大小,当发送方收到接收窗口的大小为0时,发送方就会停止发送数据,防止出现大量丢包情况的发生

发送方何时再继续传送数据?

  • 当发送方收到接受窗口 win = 0 时,这时发送方停止发送报文,并且同时开启一个定时器,每隔一段时间就发个测试报文去询问接收方,打听是否可以继续发送数据了,如果可以,接收方就告诉他此时接受窗口的大小;如果接受窗口大小还是为0,则发送方再次刷新启动定时器

  1. 发送窗口和接受窗口相等吗? 答:接收方在发送确认报文的时候,会告诉发送发自己的接收窗口大小,而发送方的发送窗口会据此来设置自己的发送窗口,但这并不意味着他们就会相等。首先接收方把确认报文发出去的那一刻,就已经在一边处理堆在自己缓存区的数据了,所以一般情况下接收窗口 >= 发送窗口。

拥塞控制

拥塞控制与网络的拥堵情况相关联,而流量控制与接收方的缓存状态相关联。

一、为何要进行拥塞控制?

  • 两台主机在传输数据包的时候,如果发送方迟迟没有收到接收方反馈的ACK,那么发送方就会认为它发送的数据包丢失了,进而会重新传输这个丢失的数据包。
  • 际情况有可能此时有太多主机正在使用信道资源,导致网络拥塞了,而A发送的数据包被堵在了半路,迟迟没有到达B。这个时候A误认为是发生了丢包情况,会重新传输这个数据包
  • 结果就是不仅浪费了信道资源,还会使网络更加拥塞。因此,我们需要进行拥塞控制

二、如何知道网络的拥塞情况?

为了探测网络的拥塞情况,我们可以采取以下两种策略:

  1. 先发送一个数据包试探下,如果该数据包没有发生超时事件(也就是没有丢包)。那么下次发送时就发送2个,如果还是没有发生超时事件,下次就发送3个,以此类推,即N = 1, 2, 3, 4, 5....
  2. 一个一个增加实在是太慢了,所以可以刚开始发送1个,如果没有发生超时时间,就发送2个,如果还是没有发送超时事件就发送4个,接着8个...,用翻倍的速度类推,即 N = 1, 2, 4, 8, 16... 把第一种方法和第二种方法结合起:我们刚开始可以以指数的速度增长,增长到某一个值,我们把这个值称之为阈值吧,用变量ssthresh代替。当增长到阈值时,我们就不在以指数增长了,而是一个一个线性增长。
  • 前期指数增长,到达阈值之后,就以一个一个线性的速度来增长。
  • 我们也把指数增长阶段称之为慢启动,线性增长阶段称之为拥塞避免

三、到了瓶颈值之后怎么办?

无论是指数增长还是一个一个增长,最终肯定会出现超时事件,总不可能无限增长吧。当出现超时事件时,我们就认为此时网络出现了拥塞了,不能再继续增长了。我们就把这个时候的N的值称之为瓶颈值

  • 当达到最大值MAX之后,我们该怎么办呢?
我们就回到最初的最初的状态,也就是说从1,2,4,8.....开始,不过这个时候我们还会把ssthresh调小,调为MAX值的一半,即ssthresh = MAX / 2

四、超时事件就一定是网络拥塞?

快重传,快恢复

超时事件发送就一定是网络出现了拥堵吗?其实也有可能不是出现了网络拥堵,有可能是因为某个数据包出现了丢失或者损害了,导致了这个数据包超时事件发生了

  • 通过冗余ACK来处理的
  • 数据包是有序号的,如果A给B发送M1, M2, M3, M4, M5...N个数据包,如果B收到了M1, M2, M4....却始终没有收到M3,这个时候就会重复确认M2,意在告诉A,M3还没收到,可能是丢失了。

  • 当A连续收到了三个确认M2的ACK,且M3超时事件还没发生。A就知道M3可能丢失了,这个时候A就不必等待M3设置的计时器到期了,而是快速重传M3。并且把ssthresh设置为MAX的一半,即ssthresh = MAX/2,但是这个时候并非把控制窗口N设置为1,而是让N = ssthresh,N在一个一个增长。
  • 这种情况叫做快速恢复