用Wireshark抓包查看TCP三次握手
TCP(传输控制协议)作为互联网的核心协议之一,其连接管理机制 —— 三次握手和四次挥手 —— 是确保数据可靠传输的关键。本文将结合理论与 Wireshark 抓包实践,让我们看看TCP的三次握手到底是什么。
TCP 三次握手
1. 握手过程详解
第一次握手(SYN)
客户端向服务器发送一个带有SYN=1
标志的报文段,表示请求建立连接。此时客户端进入SYN_SENT
状态。报文中包含一个随机生成的初始序列号(ISN),例如Seq=1926459878
。该序列号用于后续数据传输的顺序标识。
第二次握手(SYN+ACK)
服务器收到请求后,回复一个SYN=1
且ACK=1
的报文段。其中,ACK=1
表示确认客户端的 SYN 请求,确认号Ack=1926459879
(即客户端 ISN+1),同时服务器也会生成自己的初始序列号Seq=980795485
。此时服务器进入SYN_RECEIVED
状态。第三次握手(ACK)
客户端验证确认号无误后,发送ACK=1
的确认报文,确认号Ack=980795486
(服务器 ISN+1),序列号为客户端 ISN+1(Seq=1926459879
)。至此,双方进入ESTABLISHED
状态,连接建立完成。
2. 核心设计逻辑
防止重复连接:通过随机生成的 ISN 避免历史残留报文干扰新连接。
双向确认:三次握手确保双方都能确认对方的发送和接收能力。若采用两次握手,服务器无法确认客户端是否收到 SYN+ACK,可能导致资源浪费。
TCP 四次挥手:连接终止的优雅告别
1. 挥手过程详解
第一次挥手(FIN)
客户端发送FIN=1
的报文段,表示不再发送数据,进入FIN_WAIT_1
状态。报文中的序列号Seq=1392
(假设为当前数据的最后一个字节序号)。第二次挥手(ACK)
服务器回复ACK=1
确认收到 FIN,确认号Ack=1393
(客户端 Seq+1),此时服务器进入CLOSE_WAIT
状态。客户端收到 ACK 后进入FIN_WAIT_2
状态。第三次挥手(FIN)
服务器处理完剩余数据后,发送FIN=1
的报文段,序列号Seq=607
(假设为服务器当前数据的最后一个字节序号),确认号仍为Ack=1393
。服务器进入LAST_ACK
状态。第四次挥手(ACK)
客户端收到 FIN 后,回复ACK=1
确认,确认号Ack=608
(服务器 Seq+1),序列号为Seq=1393
。客户端进入TIME_WAIT
状态,等待 2 倍报文最大生存时间(2MSL)后彻底关闭连接。
2. 为何需要四次挥手?
TCP 是全双工协议,每个方向需单独关闭。服务器在收到 FIN 后可能仍有数据待发送,因此需先回复 ACK 确认,再单独发送 FIN 关闭己方连接。若合并为三次挥手,可能导致数据丢失。
WireShark抓包
本文使用Navicat
去连接mysql
数据库,使用Wireshark
来查看抓包对应的报文。
首先打开 Wireshark
,由于我的计算机使用以太网连接,因此在界面中双击 “以太网” 接口,即可开始捕获该接口上的所有数据包。
进入以后,在过滤器这里我们过滤
mysql
服务器的ip,ip.addr == 192.168.18.10
防止抓包太多,影响抓包分析。
然后我们可以用navicat
打开对应的mysql连接即可。然后我们就可以看到WireShark
中抓到了与mysql
服务器192.168.18.10
通信的数据包。
从 Wireshark
的抓包记录中,开头的三个报文清晰呈现了 TCP 三次握手的交互过程:首先,客户端(192.168.18.136)
向服务器(192.168.18.10)
发送了一个带有 [SYN]
标志的连接请求报文;服务器收到后,随即返回带有 [SYN,ACK]
标志的应答报文,既确认了客户端的请求,也同步发起了自身的连接序列;最后,客户端再以 [ACK]
报文回应,完成对服务器请求的确认。至此,抓包记录中完整展现了三次握手的闭环,TCP 连接正式建立。
Wireshark在此也清晰地为我们呈现了基于OSI七层网络模型的分层数据包结构,这里从数据链路层到传输层的每一层封装细节都被完整拆解,传输层数据(绿色)包含端口号等核心字段,这些数据会先传递给网络层;网络层(蓝色)会在其头部封装网络层信息,比如源 IP 地址、目的 IP 地址等;随后,封装后的数据包被交由数据链路层,数据链路层会进一步添加自身的头部信息(红色),例如源 MAC 地址、目的 MAC 地址;最终,完成层层封装的数据包被传递到物理层,由物理层转换为电信号或光信号进行传输。
展开TCP层的报文详情,我们可以清晰看到客户端发起第一次握手(SYN报文)时携带的信息:源端口号为56665、目的端口号为3306,序列号(Seq Number)为0、确认号(ACK Number)为0,SYN标志位被置为1,同时还包含了滑动窗口(Window)的大小信息。