目录
- TCP 协议
- 基本概念
- TCP 的特点
- TCP 报文格式
- 3 次握手与 4 次挥手
- 三次握手(Three-way Handshake)
- 四次挥手(Four-way Handshake)
- 常见问题
- 性能优化
- TCP 的拥塞控制算法
- 慢启动(Slow Start)
- 拥塞避免(Congestion Avoidance)
- 快速重传(Fast Retransmit)
- 快速恢复(Fast Recovery)
- 拥塞控制参数
- 现代 TCP 拥塞控制算法
- 性能优化建议
TCP 协议
基本概念
TCP(传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。
TCP 的特点
-
面向连接
- 通信双方必须先建立连接
- 数据传输结束后需要断开连接
-
可靠传输
- 使用确认机制
- 超时重传
- 流量控制
- 拥塞控制
-
全双工通信
- 双方都可以发送和接收数据
- 支持双向数据流
-
基于字节流
- 数据以字节为单位传输
- 没有消息边界
TCP 报文格式
-
源端口和目的端口
- 各占 2 字节
- 用于标识发送和接收进程
-
序列号和确认号
- 各占 4 字节
- 用于可靠传输和流量控制
-
控制位
- SYN:建立连接
- ACK:确认
- FIN:结束连接
- RST:重置连接
- PSH:推送数据
- URG:紧急数据
-
窗口大小
- 占 2 字节
- 用于流量控制
3 次握手与 4 次挥手
三次握手(Three-way Handshake)
-
第一次握手
- 客户端发送 SYN 包
- 序列号 seq = x
- 进入 SYN_SENT 状态
-
第二次握手
- 服务器发送 SYN + ACK 包
- 序列号 seq = y
- 确认号 ack = x + 1
- 进入 SYN_RCVD 状态
-
第三次握手
- 客户端发送 ACK 包
- 确认号 ack = y + 1
- 进入 ESTABLISHED 状态
三次握手的目的:
- 确认双方的收发能力
- 同步序列号和确认号
- 交换窗口大小信息
- 防止历史连接
四次挥手(Four-way Handshake)
-
第一次挥手
- 客户端发送 FIN 包
- 序列号 seq = u
- 进入 FIN_WAIT_1 状态
-
第二次挥手
- 服务器发送 ACK 包
- 确认号 ack = u + 1
- 进入 CLOSE_WAIT 状态
-
第三次挥手
- 服务器发送 FIN 包
- 序列号 seq = w
- 进入 LAST_ACK 状态
-
第四次挥手
- 客户端发送 ACK 包
- 确认号 ack = w + 1
- 进入 TIME_WAIT 状态
四次挥手的特点:
- 服务器可能还有数据要发送
- TIME_WAIT 状态持续 2MSL
- 防止旧连接的数据包影响新连接
常见问题
-
为什么需要三次握手?
- 防止历史连接
- 同步序列号
- 避免资源浪费
-
为什么需要四次挥手?
- 服务器可能还有数据要发送
- 确保数据完整传输
- 防止数据丢失
-
TIME_WAIT 状态的作用
- 确保最后一个 ACK 能够到达
- 防止旧连接的数据包影响新连接
- 等待 2MSL 时间
-
TCP 粘包和拆包
- 原因:TCP 是字节流协议
- 解决方案:
- 消息边界标记
- 固定长度消息
- 消息头+消息体
性能优化
-
连接优化
- 使用长连接
- 启用 TCP keepalive
- 合理设置超时时间
-
传输优化
- 启用 Nagle 算法
- 使用 TCP_NODELAY
- 调整窗口大小
-
拥塞控制
- 慢启动
- 拥塞避免
- 快速重传
- 快速恢复
TCP 的拥塞控制算法
TCP 拥塞控制算法主要包括四个核心部分:慢启动、拥塞避免、快速重传和快速恢复。
慢启动(Slow Start)
-
工作原理
- 初始拥塞窗口(cwnd)设为 1 个 MSS
- 每收到一个 ACK,cwnd 增加 1 个 MSS
- 呈指数增长:1, 2, 4, 8, 16…
-
触发条件
- 新连接建立时
- 超时重传后
- 空闲一段时间后
-
结束条件
- 达到慢启动阈值(ssthresh)
- 发生超时重传
- 收到重复 ACK
拥塞避免(Congestion Avoidance)
-
工作原理
- cwnd 线性增长:每 RTT 增加 1 个 MSS
- 增长公式:cwnd += 1/cwnd
-
触发条件
- cwnd 达到 ssthresh 时
- 从慢启动阶段切换
-
结束条件
- 发生超时重传
- 收到重复 ACK
快速重传(Fast Retransmit)
-
工作原理
- 收到 3 个重复 ACK 时触发
- 立即重传丢失的包
- 不需要等待超时
-
优势
- 减少等待时间
- 提高传输效率
- 更快恢复传输
-
触发条件
- 收到 3 个重复 ACK
- 包序号大于当前发送窗口
快速恢复(Fast Recovery)
-
工作原理
- 收到 3 个重复 ACK 时触发
- cwnd 设为 ssthresh + 3
- 每收到重复 ACK,cwnd 增加 1
- 收到新的 ACK 后,cwnd 设为 ssthresh
-
状态转换
- 从拥塞避免进入快速恢复
- 收到新 ACK 后回到拥塞避免
- 超时后回到慢启动
-
优势
- 避免进入慢启动
- 保持较高的传输速率
- 更快恢复网络状态
拥塞控制参数
-
拥塞窗口(cwnd)
- 发送方控制发送速率
- 动态调整大小
- 受网络状况影响
-
接收窗口(rwnd)
- 接收方控制接收速率
- 防止接收缓冲区溢出
- 通过 ACK 包通告
-
慢启动阈值(ssthresh)
- 初始值通常较大
- 超时后设为当前 cwnd 的一半
- 快速重传后设为当前 cwnd 的一半
现代 TCP 拥塞控制算法
-
TCP Reno
- 经典算法
- 包含上述四个核心机制
- 适合一般网络环境
-
TCP New Reno
- Reno 的改进版本
- 优化了快速恢复机制
- 处理多个包丢失的情况
-
TCP BBR
- Google 开发的现代算法
- 基于带宽和 RTT 建模
- 更好的带宽利用率
- 更低的缓冲区占用
-
TCP CUBIC
- Linux 默认算法
- 使用立方函数控制窗口增长
- 更好的高速网络适应性
性能优化建议
-
网络层面
- 合理设置初始窗口大小
- 优化网络拓扑结构
- 减少网络抖动
-
应用层面
- 使用长连接
- 合理设置超时时间
- 实现断点续传
-
系统层面
- 选择合适的拥塞控制算法
- 调整系统参数
- 监控网络状态