TCP 头部是什么
TCP 报文头部固定 20 字节,带选项时最多 60 字节。它承载了连接的全部状态信息:端口标识两端应用,序号与确认号描述字节流位置,标志位表达连接动作,窗口做流量控制,校验和做端到端校验。读得懂头部,才能把抓包里的每一行对应到具体问题——这也是分析重传、零窗口、RST 的前提。
基本信息
| 固定长度 | 20 字节(无选项时) |
|---|---|
| 最大长度 | 60 字节(选项区最多 40 字节) |
| 关键字段 | 端口、序号、确认号、标志位、窗口、校验和 |
| 规范 | RFC 9293 §3.1 |
| 抓包工具 | tcpdump、Wireshark、ss |
| 适用平台 | 所有 TCP/IP 实现,Linux/Windows/网络设备一致 |
典型使用场景
- 抓包判读:把每个字段对应到具体现象,而不是只看有没有回包
- 写 BPF 过滤表达式时定位标志位与端口,缩小抓包范围
- 排查连接建立失败:看 SYN 的选项区里 MSS 与窗口缩放是否协商成功
- 分析重传与乱序:对着序号和确认号判断丢在哪一段
- 防火墙与 NAT 规则按端口与标志位设计匹配条件
抓包查看头部字段
抓包查看头部字段
tcpdump -nn -vv 'tcp port 8080' -c 5 # -vv 显示窗口、校验和等细节
tcpdump -nn 'tcp[tcpflags] & tcp-syn != 0' -c 5 # 只看 SYN 报文
tcpdump -nn -S 'tcp port 8080' -c 6 # -S 显示绝对序号,便于对账
tcpdump -nn -i any 'tcp port 8080 and host 10.0.0.9' -w trace.pcap # 存盘用 Wireshark 深读字段逐列读法
| 字段 | 长度 | 作用 |
|---|---|---|
| 源端口/目的端口 | 16bit ×2 | 标识两端应用,取值 0-65535 |
| 序号 Sequence | 32bit | 本报文首字节在字节流中的位置 |
| 确认号 Acknowledgment | 32bit | 期望收到的下一个字节,累积确认 |
| 数据偏移 | 4bit | 头部长度,以 4 字节为单位,最小为 5 |
| 标志位 | 9bit | SYN/ACK/FIN/RST/PSH/URG/ECE/CWR/NS |
| 窗口 Window | 16bit | 接收窗口,可配合窗口缩放选项放大 |
| 校验和 | 16bit | 覆盖伪头部与数据,端到端校验 |
| 紧急指针 | 16bit | 配合 URG 使用,现代协议几乎不用 |
| 选项 Options | 0-40B | MSS、SACK、时间戳、窗口缩放 |
选项区只在握手段出现:MSS 声明单段最大长度(常见 1460),窗口缩放把 16 位窗口放大到更大范围以支撑高带宽高延迟链路,SACK 让选择性重传成为可能。三者协商失败都会带来性能问题而非直接报错。
校验和是端到端而非逐跳:中间设备(部分负载均衡、隧道、NAT)改写载荷而不重算校验和时,接收端会静默丢弃报文,表现为「连接建立成功但数据不动」。