HTTP请求过程(三)—— TCP四次挥手断开连接以及异常处理

HTTP请求过程(三)—— TCP四次挥手断开连接以及异常处理

上一篇文章介绍了,三次握手建立连接后,双方就可以进行数据的发送和接收了。假如之后客户端发起了断开连接的请求,那么正常情况下的过程如下图所示:

HTTP请求过程(三)—— TCP四次挥手断开连接以及异常处理

1.客户端向服务器发送FIN数据包,告知服务端需要断开连接,之后就会FIN_WAIT_1状态。

2.服务端收到FIN数据包后,会向客户端发送Ack包,并继续处理未处理完的数据,然后进入CLOSE_WAIT状态。

3.客户端收到Ack包后进入FIN_WAIT_2状态。

4.服务端数据处理完毕后向客户端发送FIN包,告知自己可以准备断开连接了,然后进入LAST_ACK状态。

5.客户端收到来自服务端的FIN包后,发出ACK确认包,然后进入TIME_WAIT状态。

6.服务端收到客户端的ACK确认包后,关闭socket套接字,进入CLOSED状态。

到这里,正常的流程就走完了,但是也许你要问,客户端还没有CLOSED掉,这是为什么呢?

关于2MSL和TIME_WAIT

MSL:即报文最大生存时间,超过这个时间的报文都会被丢弃掉。

TIME_WAIT:客户端发送完ACK包后可能因为网络存在问题导致无法及时到达服务端,那么一定时间后服务端会启动重发机制再次发送FIN包,如果客户端早早就关闭了连接,那么服务端将不再有可能收到Ack确认包。TIME_WAIT的时长就是2倍MSL,想一下为什么是2MSL?

异常断连

有句话叫“理想很丰满,现实很骨感”,这句话同样适合于计算机的世界,异常总是无处不在。例如突发的网线故障,一方机器奔溃、断电,SYN攻击等情况,倘若连接得不到及时释放,就会造成资源的浪费,甚至影响正常的功能。

解决办法:

1.很多防火墙等对于空闲socket自动关闭;

2.打开TCP协议自带Keep-alive功能,相关参数如下图:

HTTP请求过程(三)—— TCP四次挥手断开连接以及异常处理

为什么是四次挥手?

客户端发送FIN并不意味着TCP连接立即关闭,因为服务端数据可能还没有发送完毕,为了保证可以继续发送数据,服务端的FIN包并不会立即发给客户端,所以就多出一次报文发送。


分享到:


相關文章: