第20章 TCP的成块数据流
所属:TCP/IP详解 卷1:协议 来源:TCP/IP详解 卷1:协议
本章介绍TCP的成块数据流,包括滑动窗口、吞吐量、慢启动和拥塞避免等。
20.1 引言
成块数据流
成块数据流(Bulk Data Flow):
- 大量数据的传输
- 比如文件传输
- 数据量大
- 追求吞吐量
- 和交互式相反
成块数据追求吞吐量。
成块数据流的特点
成块数据流的特点:
-
数据量大
- 大量数据
- 持续传输
-
追求吞吐量
- 越快越好
- 最大化利用带宽
-
大包为主
- 尽量发最大的段
- 提高效率
-
流量控制和拥塞控制很重要
- 既要快,又不能拥塞
- 平衡很重要
成块数据追求高吞吐量。
本章讨论的内容
本章讨论的内容:
- 滑动窗口
- 吞吐量
- 慢启动
- 拥塞避免
- 拥塞窗口
本章介绍成块数据流的处理。
20.2 滑动窗口
什么是滑动窗口
滑动窗口(Sliding Window):
- TCP流量控制的机制
- 接收方通告窗口大小
- 发送方最多发窗口大小的数据
- 窗口随着确认滑动
滑动窗口是流量控制的机制。
窗口的概念
发送方的窗口:
已确认并发送 已发送未确认 可发送未发送 不可发送
<-----------><-------------><-------------><---------->
左边界 右边界
窗口内的:
- 已发送未确认:发了等确认
- 可发送未发送:可以发还没发
窗口外的:
- 已确认:已经确认了
- 不可发送:窗口还没到
发送方有发送窗口。
窗口的滑动
窗口的滑动:
- 收到新的确认
- 窗口左边界右移
- 右边也跟着右移
- 窗口滑动了
例子:
- 窗口大小是1000
- 确认了前500字节
- 窗口右移500字节
- 又可以发500字节了
收到确认,窗口滑动。
窗口大小和吞吐量
窗口大小和吞吐量的关系:
- 窗口越大,吞吐量越高
- 因为可以连续发更多数据
- 不用等确认
理论最大吞吐量:
吞吐量 = 窗口大小 / 往返时间
例子:
- 窗口大小:64KB = 65535字节
- 往返时间RTT:100ms
- 最大吞吐量 = 65535 / 0.1 = 655350字节/秒 ≈ 640KB/s
窗口大小限制吞吐量。
20.3 吞吐量
什么是吞吐量
吞吐量(Throughput):
- 单位时间传输的数据量
- 通常是字节/秒 或 比特/秒
- 衡量传输速度
吞吐量是传输速度。
影响吞吐量的因素
影响吞吐量的因素:
-
带宽
- 网络的最大速度
- 上限
-
窗口大小
- TCP的窗口限制
- 窗口太小达不到带宽
-
往返时间(RTT)
- RTT越大,吞吐量越低
- 因为要等确认
-
丢包率
- 丢包要重传
- 降低吞吐量
-
拥塞
- 网络拥塞
- 速度下降
很多因素影响吞吐量。
带宽延迟积
带宽延迟积(Bandwidth-Delay Product, BDP):
- 带宽 × 延迟
- 管道里能装多少数据
- 也就是填满管道需要多少数据
公式:
BDP = 带宽 × 延迟
例子:
- 带宽:100Mbps = 12.5MB/s
- 延迟:100ms = 0.1s
- BDP = 12.5MB/s × 0.1s = 1.25MB
意义:
- 窗口大小至少要等于BDP
- 才能填满管道
- 达到最大吞吐量
- 窗口太小的话,管道填不满
带宽延迟积是管道的容量。
长肥管道
长肥管道(Long Fat Pipe):
- 带宽高,延迟大
- BDP很大
- 比如跨洋的高速链路
问题:
- 普通TCP窗口只有64KB
- 不够大
- 填不满管道
- 吞吐量上不去
解决:
- 窗口扩大选项
- 把窗口扩大到更大
- 比如1GB
长肥管道需要大窗口。
20.4 慢启动
什么是慢启动
慢启动(Slow Start):
- 拥塞控制的一部分
- 刚开始发送的时候
- 慢慢增加速度
- 探测网络容量
- 避免一下子发太多拥塞
为什么叫慢启动:
- 相对于一开始就发满窗口来说
- 它是慢的
- 但其实增长很快
- 指数增长
慢启动慢慢增加速度。
拥塞窗口
拥塞窗口(Congestion Window, cwnd):
- 拥塞控制的窗口
- 发送方维护
- 表示在不拥塞的情况下
- 可以发多少数据
实际发送窗口:
发送窗口 = min(接收窗口, 拥塞窗口)
- 取两者的较小值
- 既要流量控制,又要拥塞控制
拥塞窗口是拥塞控制的窗口。
慢启动的过程
慢启动的过程:
-
刚开始
- cwnd = 1个MSS
- 发1个段
-
收到1个ACK
- cwnd += 1 MSS
- 现在可以发2个
-
收到2个ACK
- cwnd += 2 MSS
- 现在可以发4个
-
以此类推
- 指数增长
- 1, 2, 4, 8, 16…
慢启动是指数增长。
慢启动阈值
慢启动阈值(ssthresh):
- 慢启动的上限
- cwnd < ssthresh:慢启动
- cwnd >= ssthresh:拥塞避免
作用:
- 慢启动增长太快
- 到了一定程度要慢下来
- 用拥塞避免
ssthresh是慢启动的阈值。
20.5 拥塞避免
什么是拥塞避免
拥塞避免(Congestion Avoidance):
- 拥塞控制的另一部分
- 慢启动之后
- 线性增加拥塞窗口
- 慢慢增加
- 避免拥塞
拥塞避免线性增加。
拥塞避免的过程
拥塞避免的过程:
- cwnd >= ssthresh
- 每个RTT cwnd += 1 MSS
- 线性增长
- 1, 2, 3, 4…
- 比慢启动慢多了
为什么线性:
- 慢启动指数增长太快
- 容易一下子拥塞
- 线性增长更稳
- 慢慢探测
拥塞避免是线性增长。
拥塞检测
怎么检测拥塞:
- 丢包就是拥塞的信号
- 超时重传
- 或者收到三个重复ACK
检测到拥塞怎么办:
- ssthresh = cwnd / 2
- cwnd 降低
- 重新开始慢启动或拥塞避免
丢包表示拥塞。
拥塞控制的总结
拥塞控制的四个阶段:
-
慢启动
- 指数增长
- 到ssthresh为止
-
拥塞避免
- 线性增长
- 慢慢增加
-
拥塞检测
- 丢包了
- 检测到拥塞
-
快速重传/快速恢复
- 收到三个重复ACK
- 快速重传
- 快速恢复
拥塞控制有几个阶段。
20.6 快速重传和快速恢复
快速重传
快速重传(Fast Retransmit):
- 收到三个重复的ACK
- 就知道丢包了
- 不用等超时
- 马上重传
为什么快:
- 超时要等很久
- 三个重复ACK很快就能收到
- 重传更快
- 吞吐量更高
快速重传不用等超时。
快速恢复
快速恢复(Fast Recovery):
- 快速重传之后
- 不用从慢启动开始
- 从ssthresh开始拥塞避免
- 恢复更快
为什么:
- 收到三个重复ACK
- 说明网络还能通
- 不是特别拥塞
- 不用降太低
- 快速恢复
快速恢复不用从头开始。
快速恢复的过程
快速恢复的过程:
-
收到三个重复ACK
- ssthresh = cwnd / 2
- cwnd = ssthresh + 3 MSS
- 重传丢失的段
-
继续收到重复ACK
- cwnd += 1 MSS
- 可以发新的段
-
收到新的ACK
- cwnd = ssthresh
- 进入拥塞避免
快速恢复让cwnd不用降太低。
20.7 小结
成块数据流
-
特点
- 数据量大
- 追求吞吐量
- 大包为主
-
目标
- 最大化吞吐量
- 充分利用带宽
滑动窗口
-
什么是滑动窗口
- 流量控制机制
- 接收方通告窗口
- 窗口随确认滑动
-
窗口大小和吞吐量
- 吞吐量 = 窗口大小 / RTT
- 窗口越大吞吐量越高
吞吐量
-
影响因素
- 带宽
- 窗口大小
- RTT
- 丢包率
- 拥塞
-
带宽延迟积
- BDP = 带宽 × 延迟
- 管道的容量
- 窗口至少要这么大
-
长肥管道
- 带宽高延迟大
- BDP大
- 需要大窗口
慢启动
-
什么是慢启动
- 拥塞控制的一部分
- 刚开始慢慢增加
- 指数增长
-
拥塞窗口
- cwnd
- 拥塞控制的窗口
- 发送窗口 = min(接收窗口, cwnd)
-
过程
- 指数增长
- 1, 2, 4, 8…
-
慢启动阈值
- ssthresh
- 慢启动的上限
- 超过就拥塞避免
拥塞避免
-
什么是拥塞避免
- 线性增长
- 慢慢增加
- 避免拥塞
-
过程
- 每个RTT加1 MSS
- 线性增长
-
拥塞检测
- 丢包就是拥塞
- 超时或三个重复ACK
快速重传和快速恢复
-
快速重传
- 三个重复ACK
- 马上重传
- 不用等超时
-
快速恢复
- 不用从慢启动开始
- 从ssthresh开始
- 恢复更快
关键概念
-
滑动窗口
- 流量控制
- 窗口滑动
-
吞吐量
- 带宽延迟积
- 长肥管道
-
拥塞控制
- 慢启动(指数)
- 拥塞避免(线性)
- 快速重传
- 快速恢复
-
拥塞窗口
- cwnd
- ssthresh