TCP 传输控制协议(二)
之前的文章中讨论了在有损信道上传输数据的情况,当传输过程有误时,一种解决方案就是重传。当网络延迟很高时,直接重传的协议性能会很差,为了提高效率,发送方再收到 ACK 之前会发送多个分组,但这也导致整个问题变得更复杂。
一种解决上述问题的方案是使用滑动窗口,如下图所示:
1.图中 3 号分组已经被发送和确认,所以发送方保存的它的副本可以删除;
2.图中窗口大小为 3 即 4、5、6 三个分组,这三个分组已经发送但还没收到 ACK 确认;
3.分组 7 已经准备好发送但还没发送,因为还没进入这个窗口;
4.下一秒,如果收到了分组 4 的 ACK,窗口就会右移一个分组,这意味着分组 4 可以释放了,而分组 7 可以被发送。
通常来说,这个窗口结构在发送方和接收方都有。在发送方,它记录着哪些分组可以释放、哪些分组等待 ACK、哪些还不能发送;在接收方,它记录着哪些分组已经收到并确认,哪些分组是下一步期望收到的。目前这个结构可以方便记录发送方与接收方之间的数据,但这个窗口大小应该设置为多少呢,如果接收和发送双方速度不一致该怎么处理呢。针对这一类流量控制的问题,滑动窗口协议中的窗口大小是不固定的,让接收方可以通知发送方使用多大的窗口,如果其中一端跟不上数据传输,那它可以向发送端通告一个较小的窗口,每个 ACK 分组都会携带最新的窗口大小值,以适应两端的容量与数据处理能力。(简单了解的话这部分可以参考《Web 性能权威指南》这本书)
另外之前提到的发送端在等待 ACK 时,到底应该等待多久的问题,这里可以再进一步讨论:就是说到底要等待多久才能认为一个分组已丢失并重发。具体来说,发送方在重发一个分组之前应等待等待的时间量大致是这些时间之和:发送分组花费的时间、、接收方处理并发送 ACK 的时间、ACK 返回到发送方的时间,以及发送方处理 ACK 的时间。不过受限于实际环境,以上这些数据很难给出一个确切的结果,一种策略是让协议尝试去估计它们,选择一组样本的传输时间均值来做参考。但把重传定时器直接设置为这个值是不合理的,因为很可能不少分组传输时间要大于均值,从而导致不必要的重传,所以这个值要比均值更大一些(具体在后面继续讨论)。TCP 就是建立在这个基础上,增加了更详细的实现,之后会继续聊聊这个话题
版权声明: 本文为 InfoQ 作者【姬翔】的原创文章。
原文链接:【http://xie.infoq.cn/article/536de7758d6bfe3a0f0e1efda】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论