TCP三次握手与四次挥手深度解析 - SRE视角

2025/12/01 network sre 共 6550 字,约 19 分钟

TCP三次握手与四次挥手深度解析 - SRE视角

SCQA结构

  • 情境(Situation):作为SRE工程师,网络故障排查是日常工作的重要组成部分,而TCP协议是互联网的基础协议之一
  • 冲突(Conflict):TCP协议的三次握手和四次挥手过程复杂,字段含义丰富,实际网络抓包中可能出现与理论不符的情况
  • 问题(Question):如何从SRE视角深入理解TCP三次握手和四次挥手的全流程?如何解释实际抓包中的异常情况?
  • 答案(Answer):本文将结合实际tcpdump抓包结果,详细解析TCP三次握手和四次挥手的每一个字段含义,并分析常见异常情况

一、TCP协议基础

TCP(Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层协议。它通过三次握手建立连接,四次挥手关闭连接,使用序号和确认机制保证数据的可靠传输。

二、实际抓包分析

我们先来看一段实际的tcpdump抓包结果:

19:49:11 root@rocky9.6-12,10.0.0.52:~ # tcpdump -Si ens160 -nn tcp and ip host 10.0.0.31 and 10.0.0.12 
dropped privs to tcpdump 
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode 
listening on ens160, link-type EN10MB (Ethernet), snapshot length 262144 bytes 
19:49:25.404687 IP 10.0.0.31.42124 > 10.0.0.12.80: Flags [S], seq 2595890315, win 64240, options [mss 1460,sackOK,TS val 2913276518 ecr 0,nop,wscale 7], length 0 
19:49:25.404715 IP 10.0.0.12.80 > 10.0.0.31.42124: Flags [S.], seq 1389065622, ack 2595890316, win 65160, options [mss 1460,sackOK,TS val 65980928 ecr 2913276518,nop,wscale 7], length 0 
19:49:25.404933 IP 10.0.0.31.42124 > 10.0.0.12.80: Flags [.], ack 1389065623, win 502, options [nop,nop,TS val 2913276518 ecr 65980928], length 0 
19:49:25.404934 IP 10.0.0.31.42124 > 10.0.0.12.80: Flags [P.], seq 2595890316:2595890388, ack 1389065623, win 502, options [nop,nop,TS val 2913276518 ecr 65980928], length 72: HTTP: GET / HTTP/1.1 
19:49:25.404952 IP 10.0.0.12.80 > 10.0.0.31.42124: Flags [.], ack 2595890388, win 509, options [nop,nop,TS val 65980928 ecr 2913276518], length 0 
19:49:25.405284 IP 10.0.0.12.80 > 10.0.0.31.42124: Flags [P.], seq 1389065623:1389066076, ack 2595890388, win 509, options [nop,nop,TS val 65980928 ecr 2913276518], length 453: HTTP: HTTP/1.1 200 OK 
19:49:25.405658 IP 10.0.0.31.42124 > 10.0.0.12.80: Flags [.], ack 1389066076, win 501, options [nop,nop,TS val 2913276519 ecr 65980928], length 0 
19:49:25.405658 IP 10.0.0.31.42124 > 10.0.0.12.80: Flags [F.], seq 2595890388, ack 1389066076, win 501, options [nop,nop,TS val 2913276519 ecr 65980928], length 0 
19:49:25.405726 IP 10.0.0.12.80 > 10.0.0.31.42124: Flags [F.], seq 1389066076, ack 2595890389, win 509, options [nop,nop,TS val 65980929 ecr 2913276519], length 0 
19:49:25.405943 IP 10.0.0.31.42124 > 10.0.0.12.80: Flags [.], ack 1389066077, win 501, options [nop,nop,TS val 2913276519 ecr 65980929], length 0 

三、TCP三次握手详细解析

TCP三次握手是建立连接的过程,用于确保双方都准备好进行数据传输,并就初始序列号达成一致。

1. 第一次握手(客户端→服务器)

19:49:25.404687 IP 10.0.0.31.42124 > 10.0.0.12.80: Flags [S], seq 2595890315, win 64240, options [mss 1460,sackOK,TS val 2913276518 ecr 0,nop,wscale 7], length 0 

字段解析

  • 时间戳:19:49:25.404687 - 数据包捕获时间
  • 源IP和端口:10.0.0.31.42124 - 客户端IP和随机端口
  • 目的IP和端口:10.0.0.12.80 - 服务器IP和HTTP服务端口
  • Flags [S]:SYN标志位,表示发起连接请求
  • seq 2595890315:客户端初始序列号(ISN),用于标识后续发送的数据字节流
  • win 64240:客户端接收窗口大小,表示客户端缓冲区可用空间
  • options
    • mss 1460:最大报文段大小,TCP报文数据部分的最大长度
    • sackOK:支持选择性确认
    • TS val 2913276518 ecr 0:时间戳选项,val是客户端时间戳,ecr是回显的服务器时间戳(此处为0表示首次握手)
    • nop:无操作,用于对齐
    • wscale 7:窗口缩放因子,实际窗口大小 = win × 2^wscale
  • length 0:数据部分长度为0,因为这只是连接请求

2. 第二次握手(服务器→客户端)

19:49:25.404715 IP 10.0.0.12.80 > 10.0.0.31.42124: Flags [S.], seq 1389065622, ack 2595890316, win 65160, options [mss 1460,sackOK,TS val 65980928 ecr 2913276518,nop,wscale 7], length 0 

字段解析

  • Flags [S.]:SYN+ACK标志位,S表示同意建立连接,.表示ACK确认
  • seq 1389065622:服务器初始序列号(ISN)
  • ack 2595890316:确认号,等于客户端ISN+1,表示已收到客户端的SYN请求
  • win 65160:服务器接收窗口大小
  • options
    • TS val 65980928 ecr 2913276518:服务器时间戳,ecr回显客户端第一次握手的时间戳

3. 第三次握手(客户端→服务器)

19:49:25.404933 IP 10.0.0.31.42124 > 10.0.0.12.80: Flags [.], seq 2595890316, ack 1389065623, win 502, options [nop,nop,TS val 2913276518 ecr 65980928], length 0 

字段解析

  • Flags [.]:ACK标志位,仅表示确认
  • seq 2595890316:客户端序列号,等于第一次握手的ISN+1
  • ack 1389065623:确认号,等于服务器ISN+1,表示已收到服务器的SYN+ACK响应

三次握手完成:此时TCP连接已建立,双方可以开始传输数据。

四、数据传输过程

在三次握手之后,客户端和服务器开始进行数据传输:

1. 客户端发送HTTP请求

19:49:25.404934 IP 10.0.0.31.42124 > 10.0.0.12.80: Flags [P.], seq 2595890316:2595890388, ack 1389065623, win 502, options [nop,nop,TS val 2913276518 ecr 65980928], length 72: HTTP: GET / HTTP/1.1 

字段解析

  • Flags [P.]:PSH+ACK标志位,PSH表示推送数据,.表示ACK确认
  • seq 2595890316:2595890388:数据序列号范围,表示发送的数据字节范围
  • length 72:数据部分长度为72字节,包含HTTP GET请求

2. 服务器确认收到请求

19:49:25.404952 IP 10.0.0.12.80 > 10.0.0.31.42124: Flags [.], ack 2595890388, win 509, options [nop,nop,TS val 65980928 ecr 2913276518], length 0 

字段解析

  • ack 2595890388:确认号等于客户端发送的最后一个字节序列号+1,表示已收到所有请求数据

3. 服务器发送HTTP响应

19:49:25.405284 IP 10.0.0.12.80 > 10.0.0.31.42124: Flags [P.], seq 1389065623:1389066076, ack 2595890388, win 509, options [nop,nop,TS val 65980928 ecr 2913276518], length 453: HTTP: HTTP/1.1 200 OK 

字段解析

  • seq 1389065623:1389066076:服务器发送的数据序列号范围
  • length 453:数据部分长度为453字节,包含HTTP 200响应

4. 客户端确认收到响应

19:49:25.405658 IP 10.0.0.31.42124 > 10.0.0.12.80: Flags [.], ack 1389066076, win 501, options [nop,nop,TS val 2913276519 ecr 65980928], length 0 

字段解析

  • ack 1389066076:确认号等于服务器发送的最后一个字节序列号+1,表示已收到所有响应数据

五、TCP四次挥手详细解析

TCP四次挥手是关闭连接的过程,用于确保双方都已完成数据传输,并释放资源。

1. 第一次挥手(客户端→服务器)

19:49:25.405658 IP 10.0.0.31.42124 > 10.0.0.12.80: Flags [F.], seq 2595890388, ack 1389066076, win 501, options [nop,nop,TS val 2913276519 ecr 65980928], length 0 

字段解析

  • Flags [F.]:FIN+ACK标志位,FIN表示客户端不再发送数据,.表示ACK确认
  • seq 2595890388:客户端最后发送的数据序列号
  • ack 1389066076:确认服务器已发送的数据

2. 第二次挥手(服务器→客户端)

19:49:25.405726 IP 10.0.0.12.80 > 10.0.0.31.42124: Flags [F.], seq 1389066076, ack 2595890389, win 509, options [nop,nop,TS val 65980929 ecr 2913276519], length 0 

字段解析

  • Flags [F.]:FIN+ACK标志位,服务器同时发送FIN和ACK
  • seq 1389066076:服务器最后发送的数据序列号
  • ack 2595890389:确认客户端的FIN请求

3. 第三次挥手(客户端→服务器)

19:49:25.405943 IP 10.0.0.31.42124 > 10.0.0.12.80: Flags [.], seq 2595890389, ack 1389066077, win 501, options [nop,nop,TS val 2913276519 ecr 65980929], length 0 

字段解析

  • Flags [.]:ACK标志位,客户端确认服务器的FIN请求
  • seq 2595890389:客户端序列号,等于第一次挥手的FIN序列号+1
  • ack 1389066077:确认号,等于服务器FIN序列号+1

六、常见四次挥手流程与异常分析

1. 常见四次挥手流程

标准四次挥手流程

  1. 客户端发送FIN,请求关闭连接 → FIN_WAIT_1状态
  2. 服务器发送ACK,确认收到FIN → 客户端进入FIN_WAIT_2状态,服务器进入CLOSE_WAIT状态
  3. 服务器发送FIN,请求关闭连接 → 服务器进入LAST_ACK状态
  4. 客户端发送ACK,确认收到FIN → 客户端进入TIME_WAIT状态,服务器进入CLOSED状态
  5. 客户端等待2MSL(最大报文段寿命)后进入CLOSED状态

2. 抓包中的异常分析

用户疑问:观测到四次挥手并没有像正常的客户端发起FIN标志,而是服务器段发起的ACK标志,这是为何?

实际情况分析

  • 从抓包结果看,客户端确实先发起了FIN标志(第一次挥手):Flags [F.]
  • 服务器的响应是同时发送了FIN和ACK标志(第二次挥手):Flags [F.]
  • 这是一种优化的四次挥手,服务器在收到客户端的FIN后,立即发送FIN+ACK,将第二次和第三次挥手合并为一次

为什么会出现这种情况?

  • 当服务器在收到客户端FIN时,已经没有更多数据要发送给客户端
  • 服务器可以直接发送FIN+ACK,减少一次网络往返,提高效率
  • 这种情况在HTTP/1.0短连接中很常见,服务器处理完请求后立即关闭连接

3. 四次挥手各阶段状态变化

阶段客户端状态服务器状态操作
1FIN_WAIT_1ESTABLISHED客户端发送FIN
2FIN_WAIT_2CLOSE_WAIT服务器发送ACK
3FIN_WAIT_2LAST_ACK服务器发送FIN
4TIME_WAITCLOSED客户端发送ACK
5CLOSED-客户端等待2MSL后关闭

七、SRE视角的TCP故障排查要点

1. 三次握手故障

  • SYN丢失:客户端持续重传SYN,但无响应,可能是网络问题或服务器过载
  • SYN_RCVD堆积:服务器大量连接处于SYN_RCVD状态,可能遭遇SYN洪水攻击
  • 半连接状态:客户端或服务器长时间处于SYN_SENT或SYN_RCVD状态,可能是防火墙配置问题

2. 四次挥手故障

  • TIME_WAIT过多:客户端大量连接处于TIME_WAIT状态,可能是短连接过多导致,可调整tcp_tw_reuse、tcp_tw_recycle等参数
  • CLOSE_WAIT过多:服务器大量连接处于CLOSE_WAIT状态,可能是应用程序未正确关闭连接
  • FIN_WAIT_2过多:客户端大量连接处于FIN_WAIT_2状态,可能是服务器未发送FIN,需检查服务器应用

3. 常用排查命令

# 查看TCP连接状态
ss -tuln
ss -tan state TIME_WAIT

# 查看TCP相关内核参数
sysctl -a | grep tcp

# 抓包并分析
tcpdump -i eth0 -nn tcp port 80
wireshark # 图形化分析工具

八、结论

TCP三次握手和四次挥手是确保可靠连接的核心机制,作为SRE工程师,深入理解其原理和字段含义对于网络故障排查至关重要。实际网络中,TCP协议会根据具体情况进行优化,如合并挥手包,这是正常现象。

通过分析tcpdump抓包结果,我们可以:

  • 确认连接建立和关闭的完整性
  • 定位网络延迟和丢包问题
  • 识别异常连接状态
  • 优化TCP参数配置

掌握TCP协议的底层原理,将帮助我们更好地设计和维护可靠的网络服务。

文档信息

Search

    Table of Contents