跳到主要内容

5.6 TCP 的流量控制

由于 TCP 使用滑动窗口实现数据收发的管理,因此利用滑动窗口就很容易实现流量控制。

流量控制是一种确保数据完整性的方法

此小节中发送方指发送 TCP 报文段一方,接收方指接收 TCP 报文的一方,而非特指服务端和客户端。

TCP 报头中有一个“窗口”字段(Window),此字段代表发送当前报文的一方的接收窗口的大小,因为流量控制是利用滑动窗口实现的,于是调整此字段即可完成流量控制。具体的,例如:

  1. 假设接收方原始接收窗口大小为 500(实践中接收窗口大小可能远大于此值,此处仅为举例)。
  2. 接收方的应用程序来不及处理数据,而此时接收窗口内已存放了 200 字节数据,于是接收窗口剩余空间为 300,即接收方 ACK 报文 rwnd=300
  3. 发送方减小自身的发送窗口使其不大于对方的接收窗口,并继续发送了 300 字节数据。
  4. 接收方的应用程序实在来不及处理数据,此前存放的 200 字节仍未处理,于是此时接受窗口已填满,即接收方 ACK 报文 rwnd=0
  5. 此时发送方收到接收方的零窗口通知,即 rwnd=0 的报文,不再继续发送数据。

可以看到:

  • 当接收方突然减小其接收窗口,而发送方来不及减小其发送窗口,导致发送了多余的数据时,接收方会将多余的数据丢弃,即丢弃接收窗口以外的数据,并向发送方回应一个 ACK 确认当前已正确接收的数据。

  • 当接收方设置其接收窗口为 0 时,发送方会启动一个持续计时器(Persistence Timer),当计时器到期时,会向对方发送探测报文段,即仅携带 1 字节数据的报文,当对方回复的报文中窗口字段仍为 0,则重启持续计时器,如果不为 0 则继续发送数据。

    持续计时器的存在是为了打破死锁的局面,即当接收方扩大了其接收窗口,向对方发送了窗口字段不为 0 的 TCP 报文,而此报文不幸丢失了,就会造成发送方一直等待对方的非零窗口通知,而接收方一直等待对方继续发送数据。