TCP滑动窗口如何实现流控?

TCP流控的最终目的就是要让发送端发送的数据量与接收端的实际接收能力(可用接收缓冲区的大小)相匹配,防止接收方被到来的数据流淹没(没有能力再接受新的数据,进而将其丢弃)。

“淹没”即,当发送方的发送速率高于接收方的受理速率的时候,接受方的接收缓存就会长期处于饱和状态,新到来的数据没地方存放就只能丢弃掉。发送端收不到ACK,就进行重传,重传的数据同样又被收端丢弃,发端再次重发,这样就陷入了一个恶性循环。

通常说的窗口,其大小是固定,所以,普通的“滑动窗口”是无法实现流量控制的。TCP所采用的“滑动窗口”实际上是一种改进版本,其窗口大小是可以动态改变的。

在TCP通信过程中,窗口尺寸由接收方通告给发送方,发送方据此改变自己的发送窗口大小,实现流量控制:

  1. 通告大窗口(接收方的可用接收缓冲区充裕)-> 发送方发送流量增加
  2. 通告小窗口(接收方的可用接收缓冲区紧张)-> 发送方发送流量减少
  3. 通告零窗口(接收方的可用接收缓冲区耗尽)-> 发送方停止发送

处于停止状态的发送方,会采取以下行动来恢复发送状态:

  1. 被动:收到窗口尺寸不为零的通告
  2. 主动:试探性发送,看收方的反应 - 为了避免非零窗口通告丢失导致双方死等
  3. 主动:发送带外数据

TCP滑动窗口机制的局限性:

  1. 流控机制不会立即生效:受制于各网络节点的处理能力,窗口通告可能不会立刻被发送方收到

  2. 控制范围有限:TCP是“端到端”协议,所谓的“流控”仅限于TCP通信两端,看不到两端之间的网络问题

滑窗机制对超时重传的影响

  1. 发送方在重传等待确认的数据时,会根据当前窗口的大小重新打包(缩短或加长报文段)重传报文段。这也就是说,重传的数据与未确认的数据可能不一致。

  2. RTT的改变致使发送端需要对超时周期做出调整。