TCP的四次挥手(假设由客户端发起)
首先客户端原先处于ESTABLISHED状态,然后客户端发送完信息后发送FIN给服务器,此后自己进入FIN_WAIT1状态。
服务器原先处于ESTABLISHED状态,然后服务器接收到FIN之后回复ACK,接着进入CLOSE_WAIT状态。客户端接收到ACK后进入FIN_WAIT2状态。
服务器处理完接收的数据之后发送FIN表示不再接收数据,请求关闭。接着进入LAST_ACK状态。
客户端接收到FIN后回应ACK表示接收到,随后自己进入TIME_WAIT状态,等待2MSL后自动进入CLOSED状态。服务器接收到ACK后直接进入CLOSED状态。
为什么要有CLOSE_WAIT状态?
当发送方没有数据要发送时,可能接收方任然有数据需要接收,或者有数据需要读或写,那么此时是不能立刻关闭客户端,此时就需要一个等待的时间。
为什么要有TIME_WAIT状态?
两个作用:
1.防止旧的数据包干扰下次连接
TIME_WAIT状态需要等待2MSL,MSL是网络报文在网络上生存的最大时间,所以经过MSL之后,发送的所有数据包要么被接收了,要么就丢失了,不可能会有活的数据包发送到下次连接的。
2.确保连接正常关闭
剩下的一个MSL就是确保接收方发送FIN的有足够的时间到达服务器,假设最后发送方回应的ACK经过MSL后丢失了,那么接收方就会重新发送FIN,在ACK丢失且新的FIN到达时的时间为MSL——2MSL。
建立连接后客户端出现问题会发生什么?
此时连接任然继续,但是客户端无法发送包,所以此时处于相看两无言的一个状态。这种状态其实就是浪费时间,但是万一一定时间内客户端恢复了会怎么样,那么能直接断开吗?显然是不理性的,所有TCP就有一个保活机制。就是双方无数据交互时,在一定时间内双方会任然处于连接状态,当超过指定时间后,接收方就会给发送方发送一个探测报文,看看对方挂没挂,多次探测报文没有回应后就认为对方挂了,接收方提前进入CLOSED状态。