发布于 

Wireshark: 分析 TCP 四次挥手

简介

首先要明白 TCP 协议是一种面向连接的、可靠的、基于字节流的传输层通信协议。

其次,TCP 是全双工模式,需要两边的连接全部关闭,此 TCP 会话才算完全关闭,四次挥手使得 TCP 的全双工连接能够可靠的终止。

TCP 的连接的拆除需要发送四个包,因此称为四次挥手(Four-way handshake),也叫做改进的三次握手。客户端或服务器均可主动发起挥手动作,在 socket 编程中,任何一方执行 close() 操作即可产生挥手操作。

下面根据客户端(IP: 10.4.17.176)请求服务端(IP: 116.211.186.208) 来分析四次挥手(four-way handshake)的过程。

这里需要注意一个问题,任何一方执行 close() 操作即可产生挥手操作,所以断开连接端可以是 Client 端,也可以是 Server 端。

在阅读下面内容之前,我假设你已经阅读过 Wireshark: 简单分析 TCP 三次挥手 这篇文章。

分析

使用 iOS 设备的浏览器客户端 Safari 访问 116.211.186.208 这个网站,关于如何开启 iOS 设备的虚拟网卡可以参考 初识 Wireshark 这篇文章。

针对 HTTP 的请求,可以进行 Follow,选择 TCP Stream 即可,如下图所示:

此时,可以看到四次挥手的抓包情况,如下图所示:

另外,从上图中可以看出,首先发起 Close 的是服务端。

第一次挥手,发送 FINACK 报文,如图:

第二次挥手,客户端发送 ACK 报文给服务端,如图:

第三次挥手,客户端发送 FINACK 报文给服务端,如图:

第四次挥手,服务端发送 ACK 报文给客户端,如图:

从图中抓包来看,seqack 的值变化如下表:

次数 seq 值 ack 值
1 140 447
2 447 141
3 447 141
4 141 448

小结

结合上面抓包的示例,小结一下四次挥手的过程。

在前面说过,断开连接端可以是 Client 端,也可以是 Server 端,我上面的例子首先发起 close 的一方是 Server 端。

第一次挥手:
服务端发送一个 [FIN+ACK] 报文,表示自己没有数据要发送了,想断开连接,并进入 fin_wait_1 状态(不能再发送数据到客户端,但能够发送控制信息 ACK 到客户端)。

第二次挥手:
客户端收到 [FIN] 报文后,客户端知道不会再有数据从服务端传来,发送 ACK 进行确认,客户端进入 close_wait 状态。此时服务端收到了客户端对 FINACK 后,进入 fin_wait2 状态。

第三次挥手:
客户端发送 [FIN ACK] 报文给对方,表示自己没有数据要发送了,客户端进入 last_ack 状态。服务端收到了客户端的 FIN 信令后,进入 time_wait 状态,并发送 ACK 确认消息。

第四次挥手:
服务端在 time_wait 状态下,等待 2MSL(MSL是数据分节在网络中存活的最长时间) 一段时间,没有数据到来的,就认为对面已经收到了自己发送的 ACK 并正确关闭了进入 close 状态,自己也断开了到客户端的 TCP 连接,释放所有资源。当客户端收到服务端的ACK 回应后,会进入 close 状态,并关闭本端的会话接口,释放相应资源。

根据 wireshark 抓包和上面流程的分析,可以画出如下示意流程图:


扫码关注,你我就各多一个朋友~


本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。

veryitman