TCP 报文首部有哪些关键字段?标志位分别是什么?
简化版
TCP 首部里最关键的几样:源/目的端口(定位进程)、序列号 seq(给字节编号、保证有序)、确认号 ack(告诉对方期待的下一个字节)、窗口大小(流量控制)、校验和(检错),以及 6 个标志位——SYN(建连)、ACK(确认)、FIN(关闭)、RST(重置)、PSH(催促交付)、URG(紧急)。三次握手/四次挥手就是靠 SYN/ACK/FIN 这几个标志位配合完成的。
详细版
TCP 首部主要字段:
| 字段 | 作用 |
|---|---|
| 源端口 / 目的端口 | 各 16 位,定位收发两端的进程 |
| 序列号(Seq) | 本报文段数据第一个字节的编号,保证有序、去重 |
| 确认号(Ack) | 期望收到的下一个字节序号(累计确认) |
| 数据偏移 | 首部长度(首部有可选字段,长度可变) |
| 标志位 | 6 个控制位(见下) |
| 窗口大小 | 接收窗口 rwnd,用于流量控制 |
| 校验和 | 首部 + 数据的差错校验 |
| 紧急指针 | 配合 URG 标志指出紧急数据位置 |
6 个标志位:
- SYN(Synchronize):请求建立连接、同步序列号。三次握手的前两次都带 SYN。
- ACK(Acknowledgment):确认号有效。建连后几乎所有报文都带 ACK。
- FIN(Finish):请求关闭连接。四次挥手用它。
- RST(Reset):重置连接,强制中断(出错、拒绝连接时发)。
- PSH(Push):催促接收方尽快把数据交给应用,别在缓冲区里等。
- URG(Urgent):紧急指针有效,标记有需要优先处理的数据(实际很少用)。
完整版教学
一、首部字段怎么支撑 TCP 的可靠传输
TCP 的可靠性(详见「TCP 如何保证可靠传输」那道题)全靠首部里这几个字段协同:
- 序列号 + 确认号:序列号给每个字节编号 → 接收方能排序、去重、发现缺口;确认号是「我下一个期待的字节」→ 发送方据此知道哪些已安全送达。这一对是可靠传输的核心。
- 窗口大小:接收方通告 rwnd → 发送方据此控制发送量,实现流量控制(详见「TCP 流量控制」那道题)。
- 校验和:检测数据在传输中有没有损坏,坏了就丢弃等重传。
所以首部不是一堆无关字段,而是「编号—确认—流控—检错」这套机制的载体。
二、SYN 和 ACK:三次握手的主角
三次握手就是 SYN 和 ACK 标志位的配合:
客户端 → SYN(我要建连,seq=x)
服务端 → SYN + ACK(我也同步,seq=y,ack=x+1)
客户端 → ACK(确认,ack=y+1)
- 第一次只有 SYN;
- 第二次 SYN + ACK 合在一个报文里(这也是握手「三次」而非四次的原因);
- 第三次只有 ACK。
建连后,后续数据报文几乎都带 ACK(因为要不断确认收到的数据)。
三、FIN 与 RST:两种「关闭」的区别
- FIN 是「优雅关闭」:四次挥手用 FIN,双方各自发 FIN + ACK,把两个方向依次正常关闭,确保数据都传完(详见「四次挥手」那道题)。
- RST 是「粗暴重置」:直接中断连接,不管数据传没传完。什么时候发 RST?
- 连接到不存在的端口(对方没监听);
- 一方异常崩溃后收到旧连接的数据;
- 应用设置
SO_LINGER为 0 强制关闭; - 收到不该收到的报文。
收到 RST 的一方会立即报「connection reset by peer」。FIN 是商量着关,RST 是直接拔线。
四、PSH 和 URG:两个不常考但会问的
- PSH:正常情况下 TCP 可能把数据攒在缓冲区里等凑够再交给应用。PSH 标志催它「别等了,马上把数据交上去」。交互式应用(如 SSH 敲一个字符就要立即响应)会用到。
- URG + 紧急指针:标记数据里有一段「紧急数据」需要优先处理,紧急指针指出它的位置。实际中几乎不用,了解即可。
五、常见误区
- ❌ 以为 seq 是报文编号——它是字节编号(TCP 是字节流),指本段数据第一个字节的序号。
- ❌ 把 FIN 和 RST 当一回事——FIN 是四次挥手的优雅关闭,RST 是强制重置、丢弃未传完数据。
- ❌ 以为 ACK 只在握手时用——建连后几乎每个报文都带 ACK 做确认。
- ❌ 以为访问未监听端口会超时——通常对方直接回 RST,快速拒绝。
六、常见误区与追问
| 考点 | 正确口径 |
|---|---|
| SYN | 建立连接、同步初始序列号 |
| ACK | 确认号有效,表示已收到某序号之前的数据 |
| FIN | 正常关闭一个方向 |
| RST | 异常复位连接 |
SYN=1, ACK=0 first handshake
SYN=1, ACK=1 second handshake
FIN=1 close one direction
RST=1 abort connection
TCP 标志位要结合连接状态看,同一个 ACK 在握手、传输、挥手中语义侧重点不同。
- 误区:ACK 只在三次握手里使用。 连接建立后几乎所有数据段都会带 ACK,用于确认收到的数据。
- 误区:FIN 和 RST 都是正常关闭。 FIN 是有序关闭,RST 是异常复位,可能丢弃未处理数据。
- 误区:PSH 表示强制立即发送到网络。 PSH 更多提示接收端尽快交付应用,实际行为还受实现影响。
- 追问:序列号和确认号是什么关系? 序列号标识本段数据位置,确认号表示期望收到的下一个字节序号。
- 追问:SYN 为什么消耗一个序号? SYN 参与可靠确认,逻辑上占用一个序号空间。
- 追问:窗口字段有什么用? 接收端通过窗口字段通告可接收空间,支撑 TCP 流量控制。
七、加强记忆
TCP 首部关键字段:源/目的端口(定位进程)、序列号(字节编号、保序)、确认号(期待的下一字节、累计确认)、窗口(流控)、校验和(检错)。6 个标志位:SYN(建连)、ACK(确认)、FIN(优雅关闭)、RST(强制重置)、PSH(催交付)、URG(紧急)。三次握手靠 SYN/ACK、四次挥手靠 FIN/ACK,FIN 是商量着关、RST 是直接拔线。