在网络传输中,为了实现可靠传输,发送方发送一个分组之后,维持一个计时器,等待接收方传过来的ACK分组。如果计时器内没有收到分组,则将分组重传。
这样的“停止和等待”的协议明显是低效率的,让网络经常处于一个空闲的状态。
所以为了提高吞吐量,我们允许多个分组同时进入网络。
但这会带来一些问题:
- 发送方需要考虑什么时间注入一个分组到网络中,还要考虑注入多少个。
- 在等待ACK时,怎么维持计时器,需要保存一个还没确认的分组的副本以防需要重传。
- 接收方需要区分哪些分组已经收到,哪些还没有。
- 接收方需要一个缓存来维护乱序接收到的分组。
- 如果接收方的接收速率比发送方的发送速率要慢,可能导致接收方因为内存限制而丢弃分组。
- 网络中的路由器等中间设备的处理速度慢于发送方的发送速率,也会导致丢包。
为了解决上面的问题,我们定义一个分组窗口(window)作为已被发送方注入,但还没完成确认的分组。
这个窗口中的分组数量称为窗口大小(window size)。

如图所示,该窗口中有3个分组。3号分组已经被发送和确认,7号分组在发送方已经准备好,但还没被发送。
发送方可能下一步就接收到4号分组的ACK确认。这样,窗口向右边“滑动”一个分组,而4号分组的副本可以被释放,7号分组可以被发送了。
窗口的这种滑动,就被称为滑动窗口(sliding window)协议。
为了处理接收方相对于发送方太慢时产生的问题,我们需要一种方法,来强迫发送方慢下来。这种行为称为流量控制(flow control)。
有两种方式可以实现:
- 基于速率(rate-based)的流量控制。让发送方以指定速率发送数据。
- 基于窗口(window-based)的流量控制。这这种方法里,窗口大小不是固定的。需要有一种方法让接收方可以通知发送方使用多大的窗口。这种通知称为窗口更新(window update)。
发送方使用接收方更新过来的窗口大小来控制流量。在TCP中,窗口更新是和ACK在同一个分组中被携带,意味着发送方会在它的窗口滑动到右边的同时调整窗口的大小。
基于窗口的流量控制可以很好的保护接收方,但是对于中间网络却无效。发送方的速率可能超过中间某个路由器的处理能力,从而导致丢包。所以需要一种称为拥塞控制(congestion control)的流量控制形式来处理。这一部分内容将在另外的文章中阐述。
