TCP 协议(TCP Protocol)

TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的传输层协议。


什么是 TCP

TCP 是传输层协议,提供可靠的、面向连接的数据传输服务。

TCP 的特点

  • 面向连接:通信前需要建立连接
  • 可靠传输:保证数据正确到达
  • 全双工通信:可以同时双向传输
  • 流量控制:防止发送方发送过快
  • 拥塞控制:防止网络拥塞

TCP 连接管理

三次握手(Three-Way Handshake)

目的:建立 TCP 连接

过程

客户端                          服务器
   |                              |
   |--- SYN (seq=x) ------------>|
   |                              |
   |<-- SYN-ACK (seq=y, ack=x+1) -|
   |                              |
   |--- ACK (ack=y+1) ---------->|
   |                              |
   |<===== 连接建立 =============>|

详细说明

  1. 客户端发送 SYN:请求建立连接,序列号为 x
  2. 服务器发送 SYN-ACK:确认收到 SYN,同时发送自己的 SYN,序列号为 y,确认号为 x+1
  3. 客户端发送 ACK:确认收到服务器的 SYN,确认号为 y+1

为什么是三次握手?

  • 确保双方都能发送和接收数据
  • 防止旧的重复连接请求造成混乱

四次挥手(Four-Way Handshake)

目的:关闭 TCP 连接

过程

客户端                          服务器
   |                              |
   |--- FIN (seq=x) ------------>|
   |                              |
   |<-- ACK (ack=x+1) -----------|
   |                              |
   |<-- FIN (seq=y) --------------|
   |                              |
   |--- ACK (ack=y+1) ---------->|
   |                              |
   |<===== 连接关闭 =============>|

详细说明

  1. 客户端发送 FIN:请求关闭连接
  2. 服务器发送 ACK:确认收到 FIN
  3. 服务器发送 FIN:服务器也准备关闭连接
  4. 客户端发送 ACK:确认收到服务器的 FIN

为什么是四次挥手?

  • TCP 是全双工的,需要双方都关闭
  • 服务器可能还有数据要发送,所以先确认,再发送 FIN

TCP 可靠性保证

1. 序列号和确认号

序列号(Sequence Number):标识每个字节的位置

确认号(Acknowledgment Number):期望收到的下一个字节的序列号

示例

发送方发送:seq=100, len=50  (字节 100-149)
接收方确认:ack=150          (期望收到字节 150)

2. 确认机制(ACK)

工作原理

  • 接收方收到数据后,发送 ACK 确认
  • 如果发送方未收到 ACK,会重传数据

3. 重传机制(Retransmission)

超时重传

  • 发送数据后启动定时器
  • 如果超时未收到 ACK,重传数据

快速重传

  • 收到 3 个重复的 ACK,立即重传
  • 比超时重传更快

TCP 流量控制

滑动窗口(Sliding Window)

目的:控制发送方的发送速度,防止接收方缓冲区溢出

工作原理

  • 接收方在 ACK 中告知可用窗口大小
  • 发送方根据窗口大小调整发送速度

窗口大小

可用窗口 = 接收窗口 - 已发送但未确认的数据

示例

接收窗口:1000 字节
已发送未确认:300 字节
可用窗口:700 字节

TCP 拥塞控制

拥塞控制算法

TCP 使用多种算法控制拥塞:

1. 慢启动(Slow Start)

特点

  • 连接建立后,拥塞窗口(cwnd)从 1 开始
  • 每收到一个 ACK,cwnd 翻倍
  • 指数增长

过程

cwnd = 1
收到 ACK → cwnd = 2
收到 ACK → cwnd = 4
收到 ACK → cwnd = 8
...

2. 拥塞避免(Congestion Avoidance)

特点

  • 达到慢启动阈值(ssthresh)后,进入拥塞避免
  • 每收到一个 ACK,cwnd 增加 1
  • 线性增长

3. 快速重传和快速恢复

快速重传

  • 收到 3 个重复 ACK,立即重传
  • 不等待超时

快速恢复

  • 收到 3 个重复 ACK,进入快速恢复
  • cwnd = ssthresh + 3
  • 每收到重复 ACK,cwnd + 1

TCP 状态转换

TCP 状态

状态说明
CLOSED关闭状态
LISTEN监听状态(服务器)
SYN_SENT已发送 SYN(客户端)
SYN_RECEIVED已收到 SYN(服务器)
ESTABLISHED连接已建立
FIN_WAIT_1已发送 FIN,等待 ACK
FIN_WAIT_2已收到 ACK,等待 FIN
CLOSE_WAIT已收到 FIN,等待关闭
LAST_ACK已发送 FIN,等待 ACK
TIME_WAIT等待 2MSL 后关闭

状态转换图

CLOSED
  ↓ (主动打开)
SYN_SENT → ESTABLISHED
  ↓ (被动打开)
LISTEN → SYN_RECEIVED → ESTABLISHED
  ↓ (主动关闭)
ESTABLISHED → FIN_WAIT_1 → FIN_WAIT_2 → TIME_WAIT → CLOSED
  ↓ (被动关闭)
ESTABLISHED → CLOSE_WAIT → LAST_ACK → CLOSED

TCP 头部结构

TCP 头部格式

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          Source Port          |       Destination Port        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        Sequence Number                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Acknowledgment Number                      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  Data |           |U|A|P|R|S|F|                               |
| Offset| Reserved |R|C|S|S|Y|I|            Window             |
|       |           |G|K|H|T|N|N|                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           Checksum            |         Urgent Pointer        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Options                    |    Padding    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

字段说明

  • Source Port:源端口(16 位)
  • Destination Port:目标端口(16 位)
  • Sequence Number:序列号(32 位)
  • Acknowledgment Number:确认号(32 位)
  • Data Offset:数据偏移(4 位)
  • Flags:控制标志(URG、ACK、PSH、RST、SYN、FIN)
  • Window:窗口大小(16 位)
  • Checksum:校验和(16 位)

TCP vs UDP

特性TCPUDP
连接面向连接无连接
可靠性可靠不可靠
速度较慢较快
头部大小20 字节8 字节
流量控制
拥塞控制
应用场景Web、邮件、文件传输DNS、视频、游戏

实际应用

查看 TCP 连接

# Linux/Mac
netstat -an | grep ESTABLISHED
# 或
ss -t
 
# 查看 TCP 状态
netstat -an | grep tcp

抓包分析

# 使用 tcpdump
sudo tcpdump -i eth0 tcp
 
# 使用 Wireshark(图形界面)
# 过滤 TCP 包:tcp
# 查看三次握手:tcp.flags.syn == 1

常见问题

1. 为什么 TCP 是可靠的?

  • 序列号和确认号
  • 超时重传
  • 流量控制
  • 拥塞控制

2. TIME_WAIT 状态的作用?

  • 确保最后一个 ACK 能够到达
  • 防止旧的重复连接请求造成混乱
  • 等待时间:2MSL(Maximum Segment Lifetime)

3. TCP 如何保证数据顺序?

通过序列号,接收方可以按序列号重组数据。


总结

TCP 协议要点:

  • 面向连接:三次握手建立连接,四次挥手关闭连接
  • 可靠性:序列号、确认号、重传机制
  • 流量控制:滑动窗口机制
  • 拥塞控制:慢启动、拥塞避免、快速重传
  • 状态管理:TCP 连接有多种状态

理解 TCP 协议是网络编程和网络问题排查的基础。


相关链接


TCP 传输层协议 网络协议