Files
cs-note/hhs/NETWORK/04-传输层/01-TCP段结构与状态机.md
T
2026-05-24 11:42:38 +08:00

6.2 KiB
Raw Blame History

tags, create time
tags create time
计算机网络
TCP
状态机
三次握手
四次挥手
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 状态机——完整图

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 堆积排查

# 查看 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连接

关联笔记