1. TCP流量控制机制
1.1 滑动窗口原理
TCP采用滑动窗口机制进行端到端流量控制,核心目标是协调发送方与接收方的处理能力差异 。其工作原理包含三个关键维度:
-
发送窗口:发送方维护的未确认数据量上限,受拥塞窗口(cwnd)和接收窗口(rwnd)双重约束
-
接收窗口:接收方通过TCP头部通告的可用缓冲区大小
-
有效窗口:实际可发送的数据量,计算公式为:
bashEffectiveWindow = min(cwnd, rwnd) - (LastByteSent - LastByteAcked)当结果为负时发送暂停。
1.2 接收方通告窗口计算
接收方动态计算通告窗口(rwnd)的核心公式:
bash
rwnd = MaxRcvBuffer - (LastByteRcvd - NextByteRead)
其中:
- MaxRcvBuffer:接收缓冲区总容量
- LastByteRcvd:已接收的最高字节序号
- NextByteRead:应用待读取的下一字节位置
当缓冲区满时rwnd=0,触发零窗口状态。应用程序读取数据后缓冲区释放,rwnd随之增大。
1.3 零窗口探测机制
当发送方收到rwnd=0时:
- 启动持续计时器(初始值 typically 5秒)
- 计时器超时后发送1字节探测报文
- 采用指数退避策略:每次超时后计时器值翻倍(最大60秒)
- 收到非零窗口响应后重置计时器
此机制防止因ACK丢失导致的连接死锁,同时避免探测包拥塞网络。
1.4 窗口缩放(Window Scaling)
为解决16位窗口字段(最大65KB)在高带宽延迟网络(BDP)的不足:
- 协商机制:在SYN报文中通过Window Scale选项协商位移因子S(0-14)
- 计算公式:实际窗口 = 报文窗口值 << S
- 最大支持:理论窗口达1GB(S=14时65535×2¹⁴)
2. TCP 拥塞控制
拥塞控制(Congestion Control)是为了防止过多的数据注入网络,避免网络中的路由器和链路因过载而导致性能下降。它与流量控制不同,关注的是整个网络的承载能力。
TCP 拥塞控制主要依赖四个核心算法:慢开始、拥塞避免、快重传和快恢复。
2.1 主要变量
- 拥塞窗口(cwnd):发送方根据网络拥塞程度动态调整的窗口。
- 慢开始门限(ssthresh):用于切换慢开始与拥塞避免的阈值。
- 实际发送窗口 = min(cwnd, rwnd)。
2.2 四个阶段/算法
-
慢开始(Slow Start)
- 连接刚开始或超时重传时,cwnd 从一个较小值(如 1 MSS)开始,每收到一个 ACK 就将 cwnd 翻倍(指数增长)。
- 当 cwnd ≥ ssthresh 时,进入拥塞避免阶段。
-
拥塞避免(Congestion Avoidance)
- cwnd 改为每经过一个 RTT 增加 1 MSS(线性增长),降低增长幅度,谨慎探测网络容量。
- 若出现超时 ,判断网络发生拥塞,执行:
- ssthresh = max(cwnd/2, 2),
- cwnd = 1,重新进入慢开始。
-
快重传(Fast Retransmit)
- 接收方每收到一个失序报文段就立即发出重复确认(Duplicate ACK)。
- 发送方收到 3 个重复 ACK 时,立即重传丢失的报文段,而不必等待超时。
-
快恢复(Fast Recovery)
- 在快重传后,发送方执行:
- ssthresh = cwnd/2,
- cwnd = ssthresh + 3 MSS(因已收到 3 个重复 ACK,说明有 3 个报文已离开网络)。
- 之后进入拥塞避免阶段,线性增加 cwnd。
- 在快重传后,发送方执行:
注:现代 TCP 实现(如 Reno、NewReno)将快重传与快恢复结合,大幅减少因单个丢包导致的性能下降。
3. TCP 运输连接管理
TCP 是面向连接的协议,在数据传输前需要建立连接,传输结束后要释放连接。
3.1 连接建立:三次握手
三次握手用于确保双方都能正常发送和接收,并协商初始序列号。
- 第一次握手 :客户端向服务器发送 SYN=1,seq=x(随机初始序列号)。
- 第二次握手 :服务器收到后回复 SYN=1, ACK=1,ack=x+1,seq=y(服务器初始序列号)。
- 第三次握手 :客户端发送 ACK=1 ,ack=y+1,seq=x+1。连接建立完成,双方进入 ESTABLISHED 状态。
为什么是三次?
- 两次握手无法防止已失效的连接请求报文突然传到服务器导致错误连接,三次握手可确保双方发送和接收能力都正常,且序列号同步。
3.2 连接释放:四次挥手
连接释放需要四次交互,因为 TCP 连接是全双工的,每个方向必须单独关闭。
- 第一次挥手 :主动关闭方(如客户端)发送 FIN=1 ,seq=u,进入 FIN_WAIT_1。
- 第二次挥手 :被动关闭方(如服务器)收到 FIN 后回复 ACK=1 ,ack=u+1,进入 CLOSE_WAIT ;主动方收到后进入 FIN_WAIT_2。
- 第三次挥手 :被动关闭方完成数据发送后,发送 FIN=1 ,seq=w,ack=u+1,进入 LAST_ACK。
- 第四次挥手 :主动关闭方收到 FIN 后回复 ACK=1 ,ack=w+1,进入 TIME_WAIT ;被动方收到 ACK 后关闭连接。主动方在 TIME_WAIT 状态等待 2MSL(Maximum Segment Lifetime)后关闭,确保最后一个 ACK 可靠到达,防止旧连接报文干扰新连接。
总结对比
| 机制 | 目标 | 核心方法 |
|---|---|---|
| 流量控制 | 避免接收方缓冲区溢出 | 滑动窗口、接收窗口(rwnd)通告 |
| 拥塞控制 | 避免网络拥塞 | 慢开始、拥塞避免、快重传、快恢复 |
| 连接管理 | 可靠建立/释放端到端连接 | 三次握手、四次挥手 |