四次挥手的过程与变迁的状态
当四次挥手的状态结束时,双方可以主动断开链接,断开链接后,断开链接后主机中的资源将会被释放
- 客户端打开关闭连接,此时发送一个TCP首部FIN标志位被置为1的报文,之后客户端进入FIN_WAI_1状态
- 服务端收到该报文后,就会向客户端发送一个ACK应答报文,接着服务器进入CLOSED_WATIT的状态
- 客户端接受服务器的ACK应答报文后,之后进入FIN_WAIT2状态
- 等待服务器处理完数据后,也向客户端发送FIN报文,之后服务端进入LAST_ACK状态
- 客户端接受了服务器的FIN报文之后,将会回应一个ACK应答报文,之后进入TIME_WAIT状态
- 服务端收到ACK应答报文后,将进入CLOSE状态,服务端就完成了连接的关闭
- 客户端在经过2MSL时间后,主动进入CLOASE状态,至此客户端也完成连接的关闭
注意:每个方向都需要一个FiN和ACK,因此通常被称为四次挥手 主动关闭连接的,才有TIME_WAIT状态
为什么需要四次挥手?
因为TCP是全双工通信,发送方和接收方都需要FIN报文和ACK报文,有一方是被动端,所以是四次挥手。 通俗些(关闭连接时,客户端向服务端发送FIN报文时,仅仅表示客户端不再发送数据了但是还能够接收数据; 服务器收到客户端的FIN报文时,先回一个ACK应答报文,而服务端可能还有数据需要处理和发送,等服务端不再发送数据时,才发送FIN报文给客户端表示同意现在关闭连接。 所以说,服务端通常需要等待完成数据的发送和处理,所以服务端的ACK和FIN一般都会分开发送,从而比三次握手多了一次。)
为什么需要TIME_WAIT状态?
首先注意:主动关闭连接的一方才有TIME_WAIT状态
- 防止旧连接的数据包
服务端在关闭连接之前发送SEQ=301报文,被网络延迟,这时有相同端口的TCP连接被复用后,被延迟的SEQ=301抵达了客户端,那么客户端有可能正常接收这个过期的报文,这就会产生数据错乱等严重的问题。所以,TCP中有2MSL这个时间,足以让两个方向上的数据包都被丢弃,使得原来连接的数据包在网络中都自然消失,再出现的数据包一定都是在新建立连接所产生的。 2. 保证连接正确关闭
如果客户端四次挥手的最后一个ACK报文在网络中被丢失,此时如果客户端TIME_WAIT过短或没有,就直接进入了CLOSE状态,那么服务端就会一直处于LAST_ACK状态。当客户端发起建立连接的SYN请求报文后,服务端会发送RST报文给客户端,连接建立的过程就会被中止。 而如果TIME_WAIT等待时间足够长的话:(1)服务端正常接收到四次挥手的最后一个ACK报文,则服务端正常关闭连接。(2)服务端没有收到四次挥手的最后一个ACK报文,重发FIN关闭连接报文等待新的ACK报文。 所以,客户端在TIME_WAIT状态等待2MSL时间后,就可以保证双方的连接都可以正常关闭。
为什么TIME_WAIT等待的时间是2MSL?
MSL是报文的最大生存时间,超过这段时间将会被丢弃。网络中可能存在来自发送方的数据包,当这些数据包被接收方处理后又会向对方发送响应,所以一来一回需要需要2倍的时间。
TIME_WAIT过多有什么危害?
- 内存资源占用
- 对端口号资源的占用,一个TCP连接至少消耗一个本地端口
如果服务端 TIME_WAIT 状态过多,占满了所有端口资源,则会导致无法创建新连接。
|