网络工程 · 21 12 月, 2025 0

用Wireshark抓包观察TCP握手

前言

TCP三次握手(TCP 3-Way Handshake)稍微学过一点网络知识的人都会念。但如此一个抽象的概念具象化后是什么样?本文就以Wireshark抓包结果,展示开始、结束TCP会话的实际过程。

从实际案例观察

下图为一次完整的TCP会话。会话的发起、结束均由客户端完成。

  • 客户端:192.168.31.10
  • 服务器:192.168.100.1

一、发起会话

从上图No.97~102可以看到发起TCP会话时的三次握手过程:

第N次握手发起阶段(Flags)SEQACK
1ClientSYNx=0
2ServerSYN, ACKy=0x+1=1
3ClientACKx+1=1y+1=1
🤔为什么Wireshark中看到的SYN包显示Seq=0

每个TCP连接必须使用一个“初始序列号(ISN)”,并且这个ISN应该随时间变化。——RFC793

真实的Seq序列号是随机的。为了让你更容易看懂握手过程,Wireshark有一个“相对序列号(Relative Sequence Numbers)”功能。它会把:

  • 第一个SYN的Seq显示为0
  • 第二个SYN/ACK的Seq显示为0

二、结束会话

图中No.111~121展示了客户端结束TCP会话的过程(四次握手):

第N次握手发起阶段(Flags)SEQACK
1ClientFIN, ACK18642407
2+3ServerFIN, ACK24071864
4ClientACK18652408
非必须ServerACK24081865

注意:该例中第二、三次握手,服务端将ACK(确认客户端FIN)与FIN(主动关闭)合并在同一个包中发送(piggyback)。一般的流程应该是:

  • Client — [FIN, ACK] –> Server
  • Client <– [ACK] — Server
  • Client <– [FIN, ACK] — Server
  • Client — [ACK] –> Server

此外,结束会话亦可由服务端主动发起(如超时、服务端特别设置等)。过程就是把上表中Client和Server反过来。

附录:各个参数的变化规律

序列号SEQ

  • SEQ从初始值开始,默默记录自己发送的累积字节数。
发送内容增加量
SYN/FIN+1(等价1字节)
ACK/RST+0
其他数据+数据字节数

ACK

  • ACK = 接收包的SEQ + 接收包的字节数(SYN/FIN按1算)
  • 用人话说就是:

我期望收到你下一个字节的序号。

请注意:ACK的期望对SEQ并没有什么卵用。SEQ的序号不会受收到的ACK影响

从上面描述可以看出,利用TCP会话中最后的SEQ、ACK数值,我们可以估算出某一方向向对方发送的总字节数,即对方最后的ACK - 自己初始的SEQ。但若存在SACK、乱序或重传,该方法会失效,需要结合Seq/Ack时间线分析。