Skip to content

TCP 字段速查表

TCP 首部(Header)由 20 字节的固定部分和可选的扩展选项(Options)组成。首部的总长度由 Data Offset(数据偏移)字段指示,而应用数据紧随在首部之后。在 TCP 通信中,一个方向上的 Seq(序列号)标识该方向正在发送的字节流位置,而 Ack(确认号)则标识期望从反方向连续接收到的下一个字节位置。

固定首部布局

text
  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                      |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |DOff |Res|A|C|E|U|A|P|R|S|F|             Window               |
 |     |   |E|W|C|R|C|S|S|Y|I|                                  |
 |     |   | |R|E|G|K|H|T|N|N|                                  |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |           Checksum            |         Urgent Pointer        |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                    Options and Padding                        |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                         Application Data                      |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

AE 标志位属于 AccECN 扩展协议。在抓包分析传统 TCP 报文时,该位置可能显示为保留位(Reserved)或旧称,具体取决于抓包工具(如 Wireshark)的版本,以及连接双方是否成功协商了 AccECN。

固定字段

字段位数解析方式主要用途应用层的控制方式
Source Port16按网络字节序读取标识发送端端口通过 bind 选择本地端口;客户端也可交给操作系统自动分配临时端口
Destination Port16按网络字节序读取标识接收端端口通过 connect 系统调用传入的目标地址指定
Sequence Number32Wireshark 默认显示相对值标识当前报文段首个数据字节在整个字节流中的位置。当带有 SYN 标志时,该字段携带本方向的初始序列号(ISN),真实数据的首字节序号从 ISN+1 开始完全由底层 TCP 协议栈管理
Acknowledgment Number32ACK 标志置位时生效表示期望从对端接收的下一个字节序号,用于向发送方确认之前的数据已成功到达完全由底层 TCP 协议栈根据实际接收进度自动产生
Data Offset4数值乘以 4 字节指示 TCP 首部的总长度(包含 Options)应用程序通过开启特定的 TCP 选项(如 Timestamp)间接影响首部长度
Reserved通常3结合当前规范和扩展解释为未来的协议扩展保留普通应用层无直接控制接口
Flags9单独检查每一位包含 9 个标志位,用于表示握手、确认、断开连接、重置、推送(Push)和拥塞控制反馈等状态部分行为可由 connectshutdown、连接关闭方式及 Socket 选项间接触发
Window16结合 Window Scale(缩放因子)计算用于通告接收方的当前可用窗口大小(即流控机制中的接收能力)受应用层读取速率、系统接收缓冲区大小以及内核 TCP 算法共同影响
Checksum16结合 IP 伪首部计算用于检测 TCP 首部和数据在传输过程中的完整性,防范误码完全由底层协议栈计算。注意:如果网卡开启了校验和卸载(Checksum Offload),在本机抓取发出的包时可能会看到报错,这属于正常现象
Urgent Pointer16URG 标志置位时生效作为相对于当前 Sequence Number 的偏移量,指出紧急数据结束的位置仅少数平台提供带外数据(Out-of-band Data)接口,现代应用中已极少使用

Data Offset (数据偏移) 快速计算

Data Offset 字段的单位是 32 位字(即 4 字节)。

Data OffsetTCP 首部长度Options 与 Padding 长度
520字节0字节
624字节4字节
832字节12字节
1040字节20字节
1560字节40字节

举个例子:如果 IP 层信息显示该 TCP 报文段的总长(Total Length)为 132 字节,而 TCP 头的 Data Offset 为 8,那么实际的 TCP 负载(Payload)数据长度就是:

1328×4=100 字节

在 IPv4 网络抓包时,TCP 数据的长度也可以直接通过 IPv4 报文总长计算得出:

LTCP data=LIPv4 totalLIPv4 headerLTCP header

如果是 IPv6 环境,其基础首部使用的是 Payload Length(有效载荷长度)字段,计算时还需要将路径上附加的各类 IPv6 扩展首部(Extension Headers)开销一并扣除。

标志位

标志名称常见阶段含义与抓包分析提示
SYNSynchronize建立连接用于同步双方的初始序列号。注意:SYN 标志本身会在序列空间中消耗一个位置(即长度算作 1)
ACKAcknowledgment握手第二步及之后的所有报文表明 Acknowledgment Number 字段是有效的
FINFinish有序关闭连接表示发送方的数据已经发送完毕。注意:FIN 标志同样会消耗一个序列号位置
RSTReset异常中止或拒绝连接用于立即重置或终止连接状态。在排查问题时,通常需要结合序列号以及具体的上下文场景来判断 RST 的触发来源
PSHPush数据传输提示接收端的 TCP 协议栈应尽快将这批数据向上层应用交付,而不是继续在缓冲区积攒。注意:TCP 是流式协议,PSH 并不定义应用层的“消息边界”
URGUrgent早期或专用协议表明 Urgent Pointer 字段是有效的
ECEECN EchoECN 协商和拥塞反馈在 Classic ECN 中,用于参与能力协商并向发送方反馈网络拥塞;在 AccECN 中,它与 CWR 和 AE 组合编码,提供更细粒度的拥塞反馈
CWRCongestion Window ReducedECN 响应在 Classic ECN 中,发送方用它来告知接收方自己已经减小了拥塞窗口;在 AccECN 中,与 ECE 和 AE 共同参与反馈编码
AEAccurate ECNAccECN 协商与计数反馈属于 AccECN 扩展,与 ECE、CWR 组成 3 位联合编码,具体含义需参考 RFC 9768 规范

Seq 与 Ack 速算规则

假设有这样一个 TCP 报文段(Segment):

  • 相对序列号 Seq = 1000
  • TCP 负载数据长度为 300 字节
  • 未设置 SYN 或 FIN 标志

当接收端成功收到该报文后,它返回的 ACK 确认号将向后推进至:

1000+300=1300

以下是几个计算 Seq 推进量的常用规则:

报文内容本方向下一 Seq 的推进量
纯 ACK,无负载数据0
携带 120 字节负载数据120
SYN 报文,无负载数据1
FIN 报文,无负载数据1
携带 80 字节负载数据并附加 FIN 标志81

注意:TCP 序列号是一个 32 位的无符号整数,采用回绕(Wrap-around)的模运算机制。当序列号逼近最大值 2321 时,下一个序号会回绕到空间低端(从 0 继续增长)。因此,协议栈在比较数据包先后顺序时,使用的是专门的序列号环形比较算法,而不是简单的数值大小对比。

常用选项 (TCP Options)

选项常见 Kind出现位置主要用途抓包分析要点
End of Option List0选项末尾标记有效选项列表的结束该标志之后,直到 Data Offset 所指示的首部末尾,均视为无意义的填充数据(Padding)
No-Operation1任意选项区单字节占位符,主要用于 4 字节边界对齐该选项只占 1 字节,没有 Length 字段
MSS2SYN、SYN+ACK通告本端所能接收的最大 TCP 数据载荷(Payload)大小通信双方会在握手阶段各自独立通告。其实际取值受路径 MTU、IP 地址族(IPv4/IPv6)以及底层首部开销的综合影响
Window Scale3SYN、SYN+ACK由于基础 Window 字段只有 16 位,此选项用于按比例放大窗口的最大表达范围仅在三次握手期间进行双向独立协商。确定的缩放因子将作用于该方向上的后续所有报文
SACK Permitted4SYN、SYN+ACK用于协商连接双方是否支持选择性确认(SACK)功能仅仅是在握手阶段声明能力,并不实际在此报告丢包缺口
SACK5发生乱序或丢包时的 ACK 报文精确报告已经收到的不连续数据块范围,以避免不必要的重传每个 SACK 块(Block)由左边界(起点)和右边界(终点)组成,右边界指向已收连续数据段后的第一个未收字节位置
Timestamp8协商成功后的大量报文用于精确计算往返时延(RTT)并防范序列号回绕(PAWS 机制)包含 TSval(发送端时间戳)和 TSecr(回显的对端时间戳)两个值,通过分析它们可以追踪报文的交互时序

在估算 MSS 与底层网络 MTU 的关系时,常用的公式为:

MSSMTULIP headerLTCP header

例如,在标准以太网中,MTU 通常为 1500 字节。扣除 20 字节的 IPv4 基础首部和 20 字节的 TCP 基础首部后:

MSS=15002020=1460 字节

对于 IPv6,由于其基础首部增至 40 字节,相同条件下的 MSS 会缩减为 1440 字节。此外,如果是经过 VPN/隧道封装、启用了 IP 扩展首部,或者受限于整条链路中的最小路径 MTU(PMTU),最终实际协商的 MSS 取值往往会变得更小。

Wireshark 常见显示提示

Wireshark 显示项来源机制抓包分析排障提示
[TCP Segment Len: N]Wireshark 根据捕获到的 IP 报文总长减去各级首部长度计算得出注意:如果抓包的机器(发送端)开启了 TSO/GSO 等分段卸载功能,网卡发包前还没有进行实际分片,你可能会看到远超 MTU 的巨大 Length(如几万字节),这是正常现象
[Next sequence number: X]由 Wireshark 自动计算推导综合考虑了负载数据长度,以及 SYN/FIN 标志对序列号空间的占用(各占用 1 字节长度)
[Calculated window size: N]由捕获到的 Window 字段原始值乘以协商好的缩放因子得出注意:如果在抓包时错过了前期的三次握手阶段,Wireshark 将无法得知 Window Scale 因子,此时计算出的窗口大小可能严重偏小,并不代表真实的流控状态
[SEQ/ACK analysis]由 Wireshark 的 TCP 会话追踪引擎通过上下文状态推断生成极度依赖抓包数据的完整性。如果出现抓包层面漏抓丢包、数据包乱序到达分析器,或者你是从连接中途开始抓包的,这里的专家提示(如 TCP Retransmission, Dup ACK 等)往往会频繁误报失效
Checksum: ... [unverified]受 Wireshark 的首选项配置或网卡 Checksum Offload(硬件卸载)的影响建议在排查校验问题时,尽量在接收端进行抓包,因为网卡收到包时线缆传输的真实 Checksum 尚未被修改或卸载,更具诊断价值

应用程序层面的控制能力

作为底层的传输协议,TCP 对上层应用屏蔽了大量的细节。对于普通的流式 Socket 应用程序,开发者通常只能进行以下几方面的直接控制:

  • 四元组建立:通过 bind() 选择绑定的本地 IP 与端口;通过 connect() 指定远端的目的地址与端口。
  • 数据发送行为:决定何时调用 send()/write() 写入数据,以及每次写入的具体字节内容。
  • 数据接收行为:通过 recv()/read() 的读取频率和每次读取的大小,间接影响本地接收缓冲区的消耗速率(进而动态影响 TCP 向对端通告的接收窗口)。
  • Socket 选项调优:例如设置 TCP_NODELAY(禁用 Nagle 算法以降低小包延迟)、开启 TCP Keepalive 保活探测机制,或调整系统层面的收发缓冲区配额大小(SO_SNDBUF, SO_RCVBUF)。
  • 连接拆除方式:调用 shutdown() 发起优雅的单向半关闭,调用 close() 进行双向的正常挥手关闭,或者利用 SO_LINGER 等选项触发发送 RST 报文以进行异常中止。

与此同时,诸如数据分段(Segmentation)、序列号与确认号的管理、重传超时的计算、滑动窗口的通告与调节,以及校验和(Checksum)的生成与验证等核心机制,均由操作系统内核中的 TCP 协议栈全权接管处理。我们在应用代码中无法直接干预,只能通过网络抓包工具来旁路观察这些底层行为。

抓包分析:报文快速检查 Checklist

在实际排查网络问题阅读 TCP 数据包时,建议按以下顺序进行逐层解析:

  1. 确定流向与身份:检查源/目的 IP 及端口(即四元组),明确当前报文是由客户端发往服务端,还是相反方向。
  2. 分离首部与数据:查看 Data Offset(首部长度),剥离头部后,确认实际传输的 TCP 负载数据长度(Payload Length)。
  3. 识别报文性质:查看 Flags 标志位,判断这是握手建连、正常数据传输、主动挥手断开,还是异常重置(RST)。
  4. 定位发送进度:检查当前报文的 Seq(序列号),结合 Payload 长度,明确本段数据在整个发送字节流中的具体位置区间。
  5. 确认接收进度:如果 ACK 标志置位,查看 Ack(确认号),明确对端已经成功收到了哪个位置之前的连续字节。
  6. 评估流控压力:观察 Window(接收窗口大小)并务必结合 Window Scale(缩放因子),判断接收端此时是否有足够的缓冲区余量。
  7. 检查附加功能:解析 Options(可选字段),重点关注 MSS、SACK 和 Timestamp 等会显著影响传输性能与机制的协商参数。
  8. 排查校验异常:最后查看 Checksum。如显示报错,需结合抓包位置(发送端还是接收端)判断是否是由于网卡 Checksum Offload(硬件卸载)引发的“假报警”。

返回附录目录 · 下一页:TCP 状态速查表

Licensed under CC BY-NC-SA 4.0.