一、为什么需要流量控制?

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

二、如何控制?

接收方每次收到数据包,可以在发送确定报文的时候,同时告诉发送方自己缓存区还剩余多少是空闲的,缓存区的剩余大小称之为接收窗口(win)。发送方收到后,便会调整自己的发送速率,即调整自己的发送窗口的大小,当发送方收到接收窗口的大小为0时,发送方停止发送数据,防止出现大量丢包。
image.png

三、发送方何时在继续发送数据?

当发送方停止发送数据,怎样才能知道自己可以继续发送数据?
我们可以采用这样的策略:当接收方处理好数据,接受窗口 win > 0时,接收方发送一个通知报文给发送方,告诉它可以继续发送数据了,当发送方收到窗口大于0的报文,就继续发送数据。
可是,如果接收方发送的通知报文由于某个网络原因而丢失,这个时候会引发一个问题:接收方发送了通知报文后,继续等待发送方发送数据,而发送方则在等待接收方的通知报文,这会陷入一种僵局。
为了解决这个问题,我们可以采用以下策略:
当发送方收到接收窗口 win = 0时,这是发送方停止发送报文,并且开启一个定时器,每隔一段时间就发一个测试报文去询问对方,打听是否可以继续发送数据了。如果可以,接收方告诉它此时接收窗口的大小,如果接收窗口的大小还是为0,则发送方再次刷新启动定时器。
image.png

四、相关问题

  1. 接收窗口的大小固定吗?

接收窗口的大小根据某种算法动态调整的。

  1. 接收窗口越大越好吗?

接收窗口太小,严重浪费链路利用率,增加丢包率;
接收窗口越大,太大也不会降低太多丢包率,而且更为消耗内存

  1. 发送窗口与接收窗口相等吗?

发送窗口根据接收窗口的大小来设置。但当接收方发送确认报文后就已经在处理缓存区的数据了,即接收窗口在增大。所以一般来接收窗口 >= 发送窗口。