第21章 TCP的超时与重传

所属:TCP/IP详解 卷1:协议 来源:TCP/IP详解 卷1:协议

本章介绍TCP的超时与重传,包括RTT测量、RTO计算、Karn算法和指数退避等。


21.1 引言

超时与重传

超时与重传(Timeout and Retransmission):

  • TCP可靠性的核心
  • 发了数据等确认
  • 超时没收到就重传
  • 保证数据可靠交付

超时重传是TCP可靠性的基础。


为什么需要超时重传

为什么需要超时重传:

  • IP是不可靠的
  • 数据报可能丢
  • 可能出错
  • TCP要保证可靠
  • 所以要超时重传

基本思想:

  • 发了数据,启动定时器
  • 定时器到了还没收到ACK
  • 就重传

超时没确认就重传。


本章讨论的内容

本章讨论的内容:

  • RTT测量
  • RTO计算
  • Karn算法
  • 指数退避
  • 快速重传
  • 重传的例子

本章介绍超时与重传。


21.2 RTT测量

什么是RTT

RTT(Round-Trip Time):

  • 往返时间
  • 发数据到收到确认的时间
  • 网络延迟的度量

RTT是往返时间。


为什么要测量RTT

为什么要测量RTT:

  • 超时时间(RTO)要根据RTT来设
  • RTO太大:浪费时间,重传慢
  • RTO太小:太早重传,增加网络负担
  • 要合适的RTO,就要准确测量RTT

RTO要根据RTT来定。


怎么测量RTT

怎么测量RTT:

  • 发一个段,记录时间
  • 收到ACK,记录时间
  • 差就是RTT

问题:

  • 重传的段怎么算?
  • 这个ACK是原来的还是重传的?
  • 不知道
  • 测量不准

重传的段RTT不好测。


RTT的变化

RTT的特点:

  • 不是固定的
  • 随时变化
  • 网络状况变化
  • 路由变化
  • 拥塞变化
  • 有波动

所以:

  • 不能只测一次
  • 要持续测量
  • 要平滑
  • 要考虑波动

RTT是变化的。


21.3 RTO计算

什么是RTO

RTO(Retransmission TimeOut):

  • 重传超时时间
  • 发了数据,等多久没ACK就重传

RTO是重传超时时间。


经典的RTO计算

经典的RTO计算(Jacobson算法):

  1. 平滑RTT(SRTT)

    • 平滑的RTT
    • 加权平均
    • SRTT = α × SRTT + (1-α) × RTT
    • α通常是0.9
  2. RTT偏差(RTTVAR)

    • RTT的波动程度
    • RTTVAR = β × RTTVAR + (1-β) × |RTT - SRTT|
    • β通常是0.75
  3. RTO

    • RTO = SRTT + 4 × RTTVAR
    • 平均加4倍偏差
    • 比较保守

RTO = SRTT + 4 × RTTVAR。


为什么这样算

为什么这样算:

  • 平均RTT是基础
  • 加上偏差作为缓冲
  • 偏差大,RTO就大
  • 偏差小,RTO就小
  • 适应不同的网络状况

4倍偏差:

  • 比较保守
  • 防止误重传
  • 大多数情况都够

平均加4倍偏差。


RTO的上下限

RTO的上下限:

  • 下限:通常1秒
  • 上限:通常60秒

为什么有下限:

  • 防止RTO太小
  • 网络稍微波动就重传
  • 增加负担

为什么有上限:

  • 防止RTO太大
  • 丢了半天不重传
  • 影响性能

RTO有上下限。


21.4 Karn算法

什么是Karn算法

Karn算法:

  • 解决重传时RTT测量的问题
  • 重传的段不测量RTT
  • 只用没重传的段来测量

重传的段不参与RTT计算。


为什么需要Karn算法

问题:

  • 发了一个段,超时重传了
  • 然后收到ACK
  • 这个ACK是对原来的还是重传的?
  • 不知道
  • 如果算成重传的,RTT就偏大
  • 如果算成原来的,RTT就偏小
  • 都不准

Karn的解决:

  • 重传的段,收到ACK不更新RTT
  • 直接忽略
  • 只用没重传的来更新

重传的段不测RTT。


指数退避

指数退避(Exponential Backoff):

  • 重传的时候
  • RTO翻倍
  • 每次重传,RTO乘以2
  • 指数增长

为什么:

  • 重传说明网络可能拥塞
  • 要放慢点
  • 指数退避
  • 避免加剧拥塞

例子:

  • 第一次超时:RTO
  • 第二次:2×RTO
  • 第三次:4×RTO
  • 第四次:8×RTO
  • …

每次重传RTO翻倍。


Karn算法和指数退避

Karn算法和指数退避的关系:

  • 重传的段不更新RTT
  • 但是RTO要指数退避
  • 每次重传RTO翻倍
  • 直到收到新的ACK
  • 再用新的RTT更新

重传时RTO指数退避。


21.5 快速重传

什么是快速重传

快速重传(Fast Retransmit):

  • 不用等超时
  • 收到三个重复的ACK
  • 就知道丢包了
  • 马上重传

快速重传不用等超时。


为什么需要快速重传

为什么需要快速重传:

  • 超时重传要等RTO
  • RTO可能很长(几百毫秒到几秒)
  • 太慢了
  • 如果能早点知道丢包
  • 就能早点重传
  • 提高吞吐量

快速重传更快。


怎么工作的

快速重传的工作过程:

  1. 发送方发了1,2,3,4,5
  2. 2丢了
  3. 接收方收到1,发ACK 2
  4. 接收方收到3,发ACK 2(重复ACK)
  5. 接收方收到4,发ACK 2(重复ACK)
  6. 接收方收到5,发ACK 2(重复ACK)
  7. 发送方收到三个重复ACK
  8. 知道2丢了
  9. 马上重传2
  10. 不用等超时

三个重复ACK就重传。


为什么是三个

为什么是三个重复ACK:

  • 一个重复:可能是乱序
  • 两个重复:可能还是乱序
  • 三个重复:很可能丢了
  • 三个比较可靠
  • 误判率低

乱序也会产生重复ACK:

  • 但通常不会有三个
  • 所以三个比较保险

三个重复ACK比较可靠。


21.6 重传的例子

超时重传的例子

超时重传的例子:

  1. 发送方发段1
  2. 启动定时器,RTO=1秒
  3. 段丢了
  4. 1秒到了,超时
  5. 重传段1
  6. RTO翻倍,变成2秒
  7. 启动新的定时器
  8. 收到ACK
  9. 取消定时器

超时了就重传。


快速重传的例子

快速重传的例子:

  1. 发送方发了1,2,3,4,5
  2. 2丢了,其他都到了
  3. 接收方收到1 → ACK 2
  4. 接收方收到3 → ACK 2(重复)
  5. 接收方收到4 → ACK 2(重复)
  6. 接收方收到5 → ACK 2(重复)
  7. 发送方收到三个重复ACK
  8. 马上重传2
  9. 不用等超时

三个重复ACK就重传。


21.7 小结

超时与重传概述

  1. 作用

    • TCP可靠性的核心
    • 超时没确认就重传
  2. 为什么需要

    • IP不可靠
    • 会丢包
    • TCP要保证可靠

RTT测量

  1. 什么是RTT

    • 往返时间
    • 发数据到收ACK的时间
  2. 为什么测量

    • 用来算RTO
    • RTO要合适
  3. 特点

    • 变化的
    • 有波动
    • 要平滑

RTO计算

  1. 什么是RTO

    • 重传超时时间
    • 等多久重传
  2. Jacobson算法

    • SRTT:平滑RTT
    • RTTVAR:RTT偏差
    • RTO = SRTT + 4×RTTVAR
  3. 上下限

    • 下限:通常1秒
    • 上限:通常60秒

Karn算法

  1. 什么是Karn算法

    • 重传的段不测量RTT
    • 只用没重传的
  2. 为什么需要

    • 重传的段不知道ACK是哪个的
    • 测不准
  3. 指数退避

    • 每次重传RTO翻倍
    • 拥塞了放慢点

快速重传

  1. 什么是快速重传

    • 三个重复ACK就重传
    • 不用等超时
  2. 为什么需要

    • 超时太慢
    • 快速重传更快
  3. 为什么三个

    • 三个比较可靠
    • 误判率低

关键概念

  1. RTT

    • 往返时间
    • 测量
  2. RTO

    • 重传超时
    • Jacobson算法
  3. Karn算法

    • 重传的段不测RTT
    • 指数退避
  4. 快速重传

    • 三个重复ACK
    • 不用等超时

TCP超时重传