
在 Wireshark 里抓一条 TCP 连接,建立过程其实只有三行:SYN,SYN+ACK,ACK。每一行都带着 Seq 和 Ack,数字明明白白摆在那里。
这几个数字读起来可能不是特别好理解。Seq 到底从哪个位置开始计算?确认号为什么总要在原来的基础上再加 1?四次挥手有时为什么只抓到三个包?TIME_WAIT 和 CLOSE_WAIT 又分别卡在哪个环节?这些疑问,都要回到报文的具体内容里去对照,才能对得上号。
这次我把 TCP 从建立连接到正常关闭的整个过程整理成了 9 张图,下面一张张过。
三次握手:三行报文与 Seq/Ack 的加 1
先看三次握手。客户端先发一个 SYN,把自己这一侧的初始序号报给服务端;服务端回 SYN+ACK,既确认收到,也同时报出自己的初始序号;客户端再回一个 ACK,连接就算建立。

Seq 和 Ack 那个“别扭”的加 1 就落在这里。SYN 占掉一个序号位置,对方回过来的确认号自然要加 1;纯 ACK 只承担确认,不占序号位置,所以不用加;FIN 同样占一个序号,道理一样。

抓包里看到的 x 和 x+1,正是这条规则留下的痕迹。
四次挥手:两个方向各自关闭
再看四次挥手。TCP 是全双工的,两个方向要各自关闭。主动关闭方先发 FIN,对面回 ACK,等自己手上的数据发完,再发一个 FIN,最后主动关闭方回 ACK。

关连接比建连接要难缠一些:两个方向的关闭时机不同步,中间还得把剩下的数据全部送完。

真实抓包里不一定刚好四行。ACK 和 FIN 经常挤进同一个包,抓出来就只剩三个;要是赶上重传或者 RST 复位,形态会更乱。抓包位置选错,或者抓得晚了一点,前面的报文一样会漏掉。

判断一条连接,别光数包
数包的个数本身说明不了什么。判断时更值得关注的是:标志位的情况、报文传输的方向、Seq 与 Ack 之间的对应关系,以及时间先后顺序。这四个方面对得上,哪怕包少了几个,整个过程照样能还原出来;反过来,如果对不上,包抓得再全也是白看。

看完之后,可以自己打开 Wireshark,随便找一条 TCP 连接,把标志位、序号和方向对着走一遍。三次和四次是结论,报文里的方向、序号和标志位才是过程。能从一个抓包里把过程还原出来,TCP 这一块就算过了。


|