目录
客户端与服务端四次挥手
关于TIME_WAIT状态
为什么TIME_WAIT状态等待的时间是2MSL?
客户端与服务端四次挥手
基于TCP协议通信的客户端与服务端断开连接就要进行四次挥手,如下图:
四次挥手过程中客户端与服务端状态转化:
客户端
ESTABLISHED->FIN_WAIT1:客户端主动调用close时,向服务器发送结束报文段,同时进入FIN_WAIT1状态。
FIN_WAIT1->FIN_WAIT2:客户端收到服务器对结束报文段的确认,进入FIN_WAIT2状态,开始等待服务器的结束报文段。
FIN_WAIT2->TIME_WAIT:客户端收到服务端发来的结束报文段,并确认应答。
TIME_WAIT->CLOSED:客户端需要等待一个2MSL(Max Segment Life,报文最大存活时间)才会进入CLOSED状态。
服务端
ESTABLISHED->CLOSE_WAIT:客户端主动调用close关闭连接,服务端收到结束报文段并确认应答。
CLOSE_WAIT->LAST_ACK:服务端调用close,向客户端发送结束报文段,等待确认应答。
LAST_ACK->CLOSED:服务器收到最后一个确认应答后连接被关闭。
注意:对于四次挥手,客户端和服务端有先断开连接与后端开断开连接之分。
关于TIME_WAIT状态
做一个测试:
先启动server后启动client,再ctrl+c服务端(ctrl+c就等价于close(fd)先让服务端从状态ESTABLISHED->FIN_WAIT1),然后再ctrl+c客户端,此时在服务端使用指令netstat -ntp会看到server的状态是TIME_WAIT,然后迅速启动server会出现如下情况:
出现绑定套接字失败的错误,TCP协议规定:主动关闭连接的一方,在四次挥手完成后,要处于TIME_ WAIT状态(即连接没有关闭),等待2MSL的时间后才能转化为CLOSED状态连接才能断开,由于server是主动断开连接的一方,四次挥手后进入TIME_WAIT状态仍然不能再次监听同样的server端口因此会出现上图中的报错。