3. TCP三次握手原理:SYN、SYN-ACK、ACK标志位详解与状态转换图
TCP三次握手是面向连接通信的基石,它确保通信双方在数据传输前完成序列号同步、窗口协商与资源预留。本节将深入解析SYN、SYN-ACK、ACK三个控制标志位的作用,并通过状态转换图展示连接建立的完整过程。
3.1 三次握手流程与标志位详解
三次握手由客户端主动发起,服务端被动响应,共交换三个报文段。每个报文段携带特定的TCP控制标志位,这些标志位位于TCP首部的Flags字段中。
| 步骤 | 方向 | 报文类型 | 标志位 | 核心作用 |
|---|---|---|---|---|
| 第1次 | Client → Server | SYN报文 | SYN=1, ACK=0 | 客户端请求建立连接,携带初始序列号ISN(c) |
| 第2次 | Server → Client | SYN-ACK报文 | SYN=1, ACK=1 | 服务端确认收到SYN,同时请求建立连接,携带ISN(s)和确认号 |
| 第3次 | Client → Server | ACK报文 | SYN=0, ACK=1 | 客户端确认收到SYN-ACK,连接建立完成,可携带数据 |
关键概念:SYN标志位用于同步序列号,ACK标志位用于确认收到数据。三次握手中,前两次报文必须设置SYN,第三次报文必须设置ACK。只有第三次握手完成后,双方才能开始传输应用数据。
3.2 序列号与确认号机制
三次握手的核心是交换初始序列号(ISN)并建立确认机制。序列号用于标识字节流中的位置,确认号表示期望收到的下一个字节序号。
- 第一次握手:客户端发送SYN报文,序列号
seq = x(ISN(c)),不携带数据,消耗一个序列号。 - 第二次握手:服务端发送SYN-ACK报文,序列号
seq = y(ISN(s)),确认号ack = x+1,表示已收到客户端的SYN。 - 第三次握手:客户端发送ACK报文,序列号
seq = x+1,确认号ack = y+1,表示已收到服务端的SYN-ACK。
验证要点:在抓包测试中,检查第三次握手的确认号是否为第二次握手的序列号加1,这是判断握手是否正确的关键指标。
3.3 状态转换图
TCP连接建立过程中,客户端和服务端各自经历一系列状态变化。下图展示了三次握手对应的完整状态转换路径。
3.4 半连接队列与全连接队列
服务端在三次握手过程中维护两个关键队列,用于管理未完成和已完成连接的请求。
| 队列名称 | 创建时机 | 状态 | 存储内容 | 溢出后果 |
|---|---|---|---|---|
| 半连接队列(SYN Queue) | 服务端收到SYN后 | SYN_RCVD | 未完成三次握手的连接请求 | SYN Flood攻击、连接超时 |
| 全连接队列(Accept Queue) | 服务端收到ACK后 | ESTABLISHED | 已完成三次握手的连接 | 应用层accept()无法及时处理 |
测试验证注意:在压力测试中,如果服务端出现大量SYN_RCVD状态连接,说明半连接队列可能已满,需要检查是否遭受SYN Flood攻击或调整
tcp_max_syn_backlog内核参数。如果出现大量ESTABLISHED状态但应用层连接数不增长,则需排查全连接队列溢出问题。
3.5 三次握手的抓包验证方法
使用Wireshark或tcpdump抓取三次握手报文时,应关注以下关键字段:
# 使用tcpdump抓取三次握手报文
sudo tcpdump -i eth0 -nn 'tcp port 80 and (tcp[tcpflags] & (tcp-syn|tcp-ack) != 0)'
# 典型输出示例(三次握手)
# 1. 客户端发送SYN
# 10:00:00.001 IP 192.168.1.100.54321 > 192.168.1.1.80: Flags [S], seq 1000, ...
# 2. 服务端回复SYN-ACK
# 10:00:00.002 IP 192.168.1.1.80 > 192.168.1.100.54321: Flags [S.], seq 2000, ack 1001, ...
# 3. 客户端发送ACK
# 10:00:00.003 IP 192.168.1.100.54321 > 192.168.1.1.80: Flags [.], ack 2001, ...
验证检查清单:
- 第一次握手:SYN标志位为1,ACK标志位为0,序列号为客户端ISN。
- 第二次握手:SYN和ACK标志位均为1,确认号为客户端ISN+1,序列号为服务端ISN。
- 第三次握手:ACK标志位为1,SYN标志位为0,确认号为服务端ISN+1。
- 三次握手完成后,双方序列号应保持同步,后续数据报文从ISN+1开始编号。
3.6 常见异常场景分析
| 异常场景 | 现象 | 可能原因 | 排查方向 |
|---|---|---|---|
| 第一次握手无响应 | 客户端反复重传SYN,最终超时 | 服务端未启动、防火墙拦截、路由不可达 | 检查服务端端口监听状态、防火墙规则 |
| 第二次握手丢失 | 客户端收到SYN-ACK后无响应 | 客户端防火墙拦截、客户端资源耗尽 | 检查客户端SYN_SENT状态连接数 |
| 第三次握手丢失 | 服务端处于SYN_RCVD状态,重传SYN-ACK | 网络丢包、客户端未收到SYN-ACK | 检查服务端半连接队列、网络延迟 |
| SYN Flood攻击 | 大量SYN_RCVD状态连接,半连接队列满 | 攻击者伪造源IP发送大量SYN | 启用SYN Cookie、限制SYN速率 |
实战建议:在测试环境中,使用
ss -tna命令观察连接状态变化。执行三次握手测试时,应能观察到客户端状态从SYN_SENT快速变为ESTABLISHED,服务端状态从LISTEN经过SYN_RCVD最终变为ESTABLISHED。如果某个状态停留时间过长,说明对应步骤存在问题。