Skip to content
本页目录

四次挥手

挥手请求既可以由客户端发起,也可以由服务端发起,以客户端发起为例。

第一次挥手

客户端发起挥手请求,向服务器发送标志位是FIN报文段,并设置序列号seq=x,客户端进入FIN_WAIT_1状态;

第二次挥手

服务器接收到FIN报文段后,向客户端返回标志位是ACK的报文段,并设置ack=x+1,服务器进入CLOSE_WAIT状态,客户端收到ACK报文后,进入FIN_WAIT_2状态;

第三次挥手

服务器向客户端发送标志位是FIN的报文段,请求关闭连接,同时服务器进入LAST_ACK状态;

第四次挥手

客户端接收到服务器的FIN报文段后,向服务器发送ACK报文段,然后进入TIME_WAIT状态,而服务端接收到ACK报文后就关闭连接。此时的客户端将在等待2MSL后依然没有收到回复的情况下,才将客户端连接关闭。

四次挥手全过程图示:

null

为什么要四次挥手?

因为TCP是全双工模式,为了保证可靠性必须四次挥手。比如当关闭连接时,客户端无数据需发送,便向服务器发送FIN报文段 ==> 服务器接收后,由于此时服务器可能还有数据需要发送,故返回ACK报文段 ==> 当服务器数据发送完毕,便向客户端发送FIN报文,表示可以关闭连接。

为什么要等待2MSL(报文段最大生存时间)?

为了保证TCP协议的全双工连接能够可靠关闭:因为第四次挥手的ACK报文段可能因为网络问题丢失,导致服务器接收不到确认应答,当服务器因超时重发FIN报文段时,有2MSL的等待,客户端再次接收FIN报文段,正确返回ACK报文段,使服务器关闭连接。
为了保证本次连接的重复数据段从网络中消失:因为建立新连接时,不能保证端口号与此前关闭的连接端口不同,又因为 IP 地址没变,此时若因一些原因某些数据滞留在网络中,TCP协议就认为滞留数据是属于新连接的,造成数据污染。为了避免数据污染,故需等待2MSL