滑动窗口

滑窗出现的原因

之前所有的通信方式都是这样,发送数据->等待ACK->发送数据->等待ACK,这种单线工作方式叫做停止等待(stop-and-wait),停止等待虽然实现了TCP传输的可靠性,但是同时牺牲了网络通信的效率,在等待ACK的时间段内,我们的网络都处于闲置状态。

我们希望有一种方式,可以同时发送出多个片段。然而如果同时发出多个片段,那么由于IP包传送是无次序的,有可能会生成乱序片段,也就是后发出的片段先到达,在"停止等待"的工作方式下,乱序片段完全被拒绝,这也很不效率。毕竟,乱序片段只是提前到达的片段。我们可以在缓存中先存放它,等到它之前的片段补充完毕,再将它缀在后面。然而,如果一个乱序片段实在是太过提前,那这个流传输就太乱了。该片段将长时间占用缓存。

我们需要一种折中的方法来解决该问题:利用缓存保留一些"不那么乱"的片段,期望能在段时间内补充上之前的片段。所以计算机暂不处理,但发送相应的ACK。对于乱得比较厉害的片段,无情的拒绝它们:不处理,也不发送对应的ACK,此时滑窗就应运而生了。

滑窗是如何工作的

滑窗sliding window)同时应用于接收方和发送方,双方各有一个滑窗。每个滑窗中可以有多个片段,当片段位于滑窗中时,表示TCP正在处理该片段。也就是可以同时处理多个片段。滑窗越大同时处理的片段数目越多。当然,滑窗越大,计算机也必须分配出更多的缓存供滑窗使用。天下毕竟没有免费的午餐。

简单画了个图希望能够方便理解

发送方

片段从左向右排列,可以清楚的看到有三个部分

  1. 红色片段:已发送并且收到ACK确认的片段
  2. 白色片段:已发送暂未收到ACK确认的片段
  3. 绿色片段:未发送的片段

滑窗中的片段4、5、6,已经发送出去,并等待相应的ACK。如果收到片段4ACK,滑窗将向右移动。这样,滑窗中将有新的片段7。片段7被发送出去,等待ACK。然后,在接收到片段5的ACK之前,滑窗不会移动,即使已经收到了片段6ACK也不会移动,这样,就保证了片段的的片段序列。

接收方

其实大体也很类似 片段确认ACK从左向右排列

  1. 红色为已经成功接收并且发送ACK确认的片段
  2. 白色为等待接收的片段

片段1、2、3已经接收并确认了,此时等待接收片段4、5、6,如果此时接受到片段4,滑窗则会向右一格,等待接收片段5、6、7,如果片段5、6片段4之前到的话,滑窗因为有空缺,不会移动,直至片段4成功接收并确认,滑窗才会向右移动,如果出现滑窗外的片段,则会丢弃不会接收和确认

总结

TCP协议和UDP协议走了两个极端。TCP协议复杂但可靠,UDP协议轻便但不可靠。在处理异常的时候,TCP极端负责,而UDP一副无所谓的样子。在TCP中,分段和编号实现了次序。ACK和重新发送实现了可靠性。滑窗则让上面的机制更加有效率的运行。不放弃,这就是TCP协议的态度。

results matching ""

    No results matching ""