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
的是服务端。
第一次挥手,发送 FIN
和 ACK
报文,如图:
第二次挥手,客户端发送 ACK
报文给服务端,如图:
第三次挥手,客户端发送 FIN
和 ACK
报文给服务端,如图:
第四次挥手,服务端发送 ACK
报文给客户端,如图:
从图中抓包来看,seq 和 ack 的值变化如下表:
次数 | 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
状态。此时服务端收到了客户端对 FIN
的 ACK
后,进入 fin_wait2
状态。
第三次挥手:
客户端发送 [FIN ACK]
报文给对方,表示自己没有数据要发送了,客户端进入 last_ack
状态。服务端收到了客户端的 FIN
信令后,进入 time_wait
状态,并发送 ACK
确认消息。
第四次挥手:
服务端在 time_wait
状态下,等待 2MSL(MSL是数据分节在网络中存活的最长时间) 一段时间,没有数据到来的,就认为对面已经收到了自己发送的 ACK
并正确关闭了进入 close
状态,自己也断开了到客户端的 TCP
连接,释放所有资源。当客户端收到服务端的ACK
回应后,会进入 close
状态,并关闭本端的会话接口,释放相应资源。
根据 wireshark 抓包和上面流程的分析,可以画出如下示意流程图:
扫码关注,你我就各多一个朋友~