跳到主要内容

超时估计与流量控制

TCP 如何估计往返时间?​

  • 采样: 通过发送样本报文段测量 SampleRTT;
  • 变化: 网络环境变化会使往返时间随之波动, 因此需要平滑;
  • 指数加权移动平均:

EstimatedRTT=0.875×EstimatedRTT+0.125×SampleRTTEstimatedRTT = 0.875 \times EstimatedRTT + 0.125 \times SampleRTT

  • 偏差估计:

DevRTT=0.75×SampleRTT+0.25×∣SampleRTT−EstimatedRTT∣DevRTT = 0.75 \times SampleRTT + 0.25 \times |SampleRTT - EstimatedRTT|

超时间隔如何设置与管理?​

  • 初始值: TimeoutInterval 推荐初始值为 1 s;
  • 超时后: 每发生一次超时就把当前值乘 2;
  • 命中新样本后: 按估计值重算:

TimeoutInterval=EstimatedRTT+4×DevRTTTimeoutInterval = EstimatedRTT + 4 \times DevRTT

TCP 为什么要做流量控制?​

  • 问题: 发送方发送太快会导致接收方的接收缓存溢出;
  • 目标: 让发送方的发送速率与接收方应用读取数据的速度相匹配;
  • 实现: 发送方维护接收窗口 rwnd, 全双工的两端各维护一个;

接收窗口 rwnd 如何计算?​

  • 可用空间: 缓存大小减去已到达但尚未被应用读取的字节数:

rwnd=RcvBuffer−(LastByteRcvd−LastByteRead)rwnd = RcvBuffer - (LastByteRcvd - LastByteRead)

  • 发送约束: 在途未确认的字节数不得超过 rwnd:

LastByteSend−LastByteAcked≤rwndLastByteSend - LastByteAcked \le rwnd

变量含义
RcvBuffer接收方缓存区大小
LastByteRead应用已读取的字节流最后一个字节号
LastByteRcvd已收到的字节流最后一个字节号
LastByteSend已发送的字节流最后一个字节号
LastByteAcked已被确认的字节流最后一个字节号