2.1 流量控制(滑动窗口)
在网络通信中,我们都会希望数据的传输效率更高一些,让通信更加流畅。但是,如果发送方的发送速率太快,可能会导致接收方来不及接收和处理数据。所以需要一种机制控制发送方的传输速率——滑动窗口。
注意,流量控制是一种接收方针对发送方来讲的机制。
流量控制过程中:
-
发送方
:一次发送的字节数量不要太多,要让对方来的及接收。 -
接收方
:通过调整滑动窗口来进行流量控制的。
现在我们假定数据流向是单向的,也就是说实例A
只负责发送数据,不负责处理和接受数据,实例B
只负责处理和接收数据,并且对接收到的数据进行应答(ACK)。B
的接收窗口大小(Rwnd
设置为400
)。
假定A
每次会发送TCP报文段包含数据100字节
,并且A将自己发送窗口大小设置为400字节
。
- A向B连续发送3个TCP报文段,每一个报文段都包含了100字节的数据,其中第3个TCP报文段因某种网络原因丢失。
- B向A发送回复报文ACK=201,Rwnd=300。表示已经接收到1~200字节的数据,下一次从201字节开始发送就行,并表示自己现在能接受300字节。
- A收到了来自B的回复报文,了解到B的接收窗口大小(Rwnd)为300,因为没有收到201-300的确认报文,因此此时滑动窗口的位置是201-500,并且发送301-400和401-500的TCP报文段给B。
- 当201-300的报文段的超时重传计时器到达时,A重新发送201-300的TCP报文段给B。
- A收到了B成功收到401的报文,下一次要从501开始发,而且又进行了一次流量控制rwnd = 100(还能接收100字节的数据)。
- 然后A又继续发送了一个序号为501的报文,然后A停止发送。然后收到了B返回的回复序号为601滑动窗口置为0的报文。
2.2 死锁问题
接上一小节,A需一直等待,直到B新发送的接收窗口大小更新的数据(rwnd > 0)才能继续发送数据。
终于,B意图向A更新自己的rwnd,但是因为网络原因,更新报文段丢失了。此时会出现死锁局面,即A在等待B的rwnd,B在等待A的新数据。
解决方案:
设置A在收到B的0接收窗口大小(rwnd=0)时会自动启动一个“持续计时器”,当持续计时器timeout时,如果还没有收到来自B的rwnd更新报文段,则会发送一个零窗口探测报文段(携带1字节数据),当B接收到这个TCP报文段后,会给A回复一个rwnd的更新,如果此时rwnd > 0,那么A就可以继续发送数据,如果rwnd=0,则重新启动一个持续计时器,重复上述步骤。