This commit is contained in:
2026-05-24 11:42:38 +08:00
commit 30d312ac35
521 changed files with 146481 additions and 0 deletions
@@ -0,0 +1,155 @@
---
tags: [计算机网络, TCP, 状态机, 三次握手, 四次挥手]
create time: 2026-05-18 01:30
---
# TCP 段结构与状态机
## 概述
TCP(Transmission Control Protocol)是互联网最核心的可靠传输协议。理解其段结构和完整状态机,是排查线上网络问题的基本功。
## TCP 首部格式(32-bit fields)
```
┌─────────────┬─────────────┬───────────────────┐
│ Source Port │ Destination Port│ Sequence No │
│ 2 bytes │ 2 bytes │ 4 bytes │
├─────────────┼───────────────┤ │
│ Ack No │ Data Offset | Reserved│ECN│ CWR│ ACK │ PSH │ RST │ SYN │ FIN │
│ 4 bytes │ 4bits │ 3 bits │ │ │ │ │ │
├─────────────┴─────────────┴───────────────────┤
│ Window Size │
│ 2 bytes │
├───────────────────┬───────────────────────────┤
│ Checksum │ Urgent Pointer │
│ 2 bytes │ 2 bytes │
├───────────────────┴───────────────────────────┤
│ Options (variable) │
│ Max: 40 bytes │
└───────────────────────────────────────────────┘
Minimum header: 20 bytes
Maximum header: 60 bytes (with options)
```
### 关键字段详解
| 字段 | 大小 | 说明 |
|------|------|------|
| **Source/Dest Port** | 各 2B | 源端口和目的端口 |
| **Sequence Number** | 4B | 本报文第一个字节的序号(32 bit,约 4GB) |
| **Acknowledgment Number** | 4B | 期望收到的下一个字节序号(ACK=1 时有效) |
| **Data Offset** | 4 bit | 首部长度,单位 4 bytes(最小 5 = 20B,最大 F = 60B) |
| **Reserved** | 3 bit | 保留字段,必须为 0 |
| **ECN** | 2 bit | ECN-Echo + CWR:显式拥塞通知 |
| **URG** | 1 bit | 紧急指针有效 |
| **ACK** | 1 bit | 确认号有效(除首次 SYN 外几乎所有包都设 ACK=1) |
| **PSH** | 1 bit | 推送标志,告诉接收端立即提交应用层 |
| **RST** | 1 bit | 复位连接(异常关闭) |
| **SYN** | 1 bit | 同步序列号(建立连接) |
| **FIN** | 1 bit | 结束标志(优雅关闭) |
| **Window Size** | 2B | 接收窗口大小,流量控制基础 |
| **Checksum** | 2B | 覆盖首部 + 数据的 CRC |
| **Urgent Pointer** | 2B | URG=1 时偏移量,指示紧急数据位置 |
### 常用 TCP Options
| Option | 大小 | 说明 |
|--------|------|------|
| NOP | 1B | No Operation,用于填充对齐 |
| MSS | 4B | Maximum Segment Size,通常 1460(1500-MT-20IP) |
| Window Scale | 4B | 扩大窗口因子(2^x倍,最大 14 = 16384 倍) |
| SACK Perm / SACK | 可变 | Selective Acknowledgment,选择性确认 |
| Timestamps | 10B | TSval + TSecr,RTT 测量和防回绕 |
## TCP 状态机——完整图
```mermaid
stateDiagram-v2
[*] --> CLOSED
note right of CLOSED
TCP 不活跃状态
只有监听套接字在此
end note
CLOSED --> LISTEN: socket() + listen()
LISTEN --> SYN_RCVD: 收到 SYN (server only)
LISTEN --> ESTABLISHED: connect() + remote SYN-ACK (client side rare)
note right of SYN_SENT
client sent SYN
waiting for SYN-ACK
end note
SYN_RCVD --> ESTABLISHED: 3-Way Handshake Complete
SYN_SENT --> ESTABLISHED: Got SYN-ACK
ESTABLISHED --> CLOSE_WAIT: Application calls close()
ESTABLISHED --> FIN_WAIT_1: Remote sends FIN
FIN_WAIT_1 --> FIN_WAIT_2: Local ACK received
FIN_WAIT_1 --> CLOSING: Simultaneous close
FIN_WAIT_2 --> TIME_WAIT: Remote FIN received
CLOSING --> TIME_WAIT: Remote ACK received
CLOSE_WAIT --> LAST_ACK: Local application close
LAST_ACK --> CLOSED: Final ACK received
TIME_WAIT --> CLOSED: 2 * MSL timeout
note right of TIME_WAIT
Must wait 2*MSL
Ensures final ACK arrives
Prevents old duplicate packets
end note
note right of CLOSE_WAIT
Server side closing
Application must call close()
end note
```
### 所有 11 种状态一览
| # | 状态 | 触发条件 | 谁处于? |
|---|------|---------|---------|
| 1 | CLOSED | 初始/终止 | 双方初始状态 |
| 2 | LISTEN | `listen()` 系统调用 | 服务端 |
| 3 | SYN_SENT | `connect()` 发出 SYN | 客户端 |
| 4 | SYN_RCVD | 收到 SYN | 服务端 |
| 5 | ESTABLISHED | 三次握手完成 | 双方 |
| 6 | FIN_WAIT_1 | 本地调用 close() | 主动关闭方 |
| 7 | FIN_WAIT_2 | FIN_WAIT_1 的 ACK 到达 | 主动关闭方 |
| 8 | CLOSE_WAIT | 收到远程 FIN | **被动关闭方**(服务器!)|
| 9 | CLOSING | 同时关闭 | 极少见 |
| 10 | LAST_ACK | 本地发送最后一个 FIN | 被动关闭方 |
| 11 | TIME_WAIT | 发送完最后一个 ACK | 主动关闭方 |
> [!tip] 哪些状态是你最常看到的?
> - **ESTABLISHED**: 正常工作
> - **TIME_WAIT**: 高频短连接的服务端(如 nginx、API 网关)
> - **CLOSE_WAIT**: ⚠️ **应用 Bug!** 说明服务器收到了客户端的关闭请求但没调用 close()
### CLOSE_WAIT 堆积排查
```bash
# 查看 CLOSE_WAIT 数量
$ ss -tan state close-wait | wc -l
4521
# 是谁引起的?查进程
$ ss -tan state close-wait src :80
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
CLOSE-WAIT 0 0 10.0.0.1:80 203.0.113.5:45678 app=nginx(1234)
# 解决方案: 修复代码中未正确关闭的文件描述符/HTTP连接
```
## 关联笔记
- [[hhs/NETWORK/TCP三次握手与四次挥手]] — 详细解析握手/挥手过程
- [[hhs/NETWORK/TCP可靠传输机制]] — 序列号/确认号的深入讲解
- [[hhs/NETWORK/TCP拥塞控制]] — TCP 窗口的动态管理