超时与重传
复习
- 序号与确认:接收方用确认告知收到的进度
- TCP 为什么需要连接:可靠传输需要双方维护状态
- 三次握手:连接建立之后才开始传输数据
TL;DR
- 发了却没收到确认,发送方就需要重传
- 重传要等多久,由超时时间决定
- 超时太短会误重传,太长又反应迟钝
- 根据实际往返时间动态估计超时,是常见做法
正文
有了确认,发送方知道“对方收到了没有”。可如果确认迟迟不来,该怎么办?它不能一直等下去,总得有个“等多久算丢”的期限。
一个定时器
发送方每发出一段数据,就启动一个重传定时器。两种结局:
- 在定时器到点之前收到确认:撤销定时器,继续发后面的
- 定时器到点仍未收到确认:认定该段可能丢了,重传
这机制本身不难,难的是——该等多久?
等多久的两难
超时时间设得不好,会有两种麻烦:
- 太短:数据其实没丢,只是确认在路上慢了点,发送方就急着重传,白白浪费带宽,还让接收方收到重复段
- 太长:真丢了也要干等很久才重传,整体速度被拖慢,网络空着也不干活
所以,没有哪个固定的秒数万全。网络时延是变化的,合适的超时也应该跟着变。
让超时自己适应
一个自然的思路是:先测量实际的往返时间(RTT),再据此估算超时。
做法大致是:为每一段数据记录“发出时刻”和“收到确认时刻”,两者相减得到这次往返花了多久;把这些测量值平滑一下,再留出一点余量(防止偶然波动),就得到当前的超时时间。
网络快,测得快,超时就短;网络慢,超时自动变长。与其拍一个死板的数字,不如让机制自己观察、自己调整。
不必干等
还有一种情况:接收方发现中间丢了一段,后面却收到了。它会在每次收到“缺口之后”的数据时,反复回同一个确认,等于在喊:“我还在等那一段!”
发送方连续收到几个这样的重复确认,就能猜到“应该是丢了,赶紧重传吧”,不必等到定时器到点。这叫快速重传,是超时机制的有效补充。
连续发、放心发,靠的是另一个工具——滑动窗口。
思考题 1
超时时间设得太短或太长,各自会有什么问题?
思考题 2
为什么超时时间应该根据实际往返时间估计,而不是固定一个数?
小结
知识点
- 发送方用重传定时器判断是否重传
- 超时设置存在“太短误传、太长迟滞”的两难
- 依据测量的往返时间动态估计超时
- 快速重传可在超时前提前重发
参考资料
- Wikipedia(zh):传输控制协议:超时与重传机制
- Wikipedia(zh):往返时间:数据往返一次所需的时间
思考题答案(仅供参考)
思考题 1
太短时,明明没丢的数据会被误判为丢失而重传,浪费带宽并造成重复;太长时,真丢了也要等很久才重传,传输效率被拖慢。两种都会损害性能,所以需要动态、合适的取值。
思考题 2
因为网络时延本来就随时间波动,固定一个数无法同时适应快网和慢网。测量实际往返时间并加以平滑和留余量,能让超时随网络状况自动调整,减少误重传又不至于反应迟缓。
协议
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
封面图
设计师 | 南国微雪