TC的连接释放—四次挥手
四次挥手释放TCP连接的过程
FIN-终止位;ACK-确认位;seq-序号;ack-确认号;
ESTABLISHED-连接建立状态;
FIN-WAIT-1-终止等待1状态;FIN-WAIT-2-终止等待2状态;CLOSE-WAIT-关闭等待状态;LAST-ACK-最后确认状态;TIME-WAIT-时间等待状态;
FIN(终止控制)报文段-终止控制位FIN=1的报文段,可以携带数据,无论是否携带数据,都会消耗一个序号。
MSL-最长报文段生存时间;
数据传输结束后,服务端和客户端均可释放连接,此时均处于ESTABLISHED状态,假设客户端主动关闭连接,服务端被动关闭连接。
第一次挥手:客户端向服务端发送连接释放报文段,并停止发送数据,首部中的终止位FIN=1,序号seq=u(前面客户端发给服务端的数据的最后一个字节的序号+1),此时,客户端进入FIN-WAIT-1状态;
第二次挥手:服务端收到客户端发送的连接释放报文段以后 ,发出确认报文段,首部中的确认位ACK=1,序号seq=v(前面服务端发给客户端的数据的最后一个字节的序号+1),确认号ack=u+1(上次客户端发送给服务端的序号+1),服务端进入CLOSE-WAIT状态;此时,客户端到服务端这个方向的连接已经释放,TCP处于半关闭状态(客户端已经没有数据要发送,若服务端发送数据,客户端仍需接收);客户端收到服务端的确认报文段后,进入FIN-WAIT-2状态,等待服务端发送连接释放报文段;
第三次挥手:当服务端没有数据要发给客户端时,服务端发出连接释放报文段,首部中的终止位FIN=1,确认位ACK=1,序号seq=w(前面服务端发给客户端的数据的最后一个字节的序号+1),确认号ack=u+1(上次客户端发送给服务端的序号+1),此时,服务端进入LAST-ACK状态;
第四次挥手:客户端收到服务端的连接释放报文段后,必须发出确认报文段,首部中的确认位ACK=1,序号seq=u+1(上次客户端发送给服务端的序号+1),确认号ack=w+1(上次服务端发给客户端的序号+1),此时,客户端进入TIME-WAIT状态,经过时间等待计时器设置的时间2MSL后,客户端进入CLOSED状态;服务端收到客户端发来的确认报文段后,也进入CLOSED状态。
问题1:为什么不是三次挥手?
由于TCP连接是全双工的,每个方向都必须单独进行关闭。当客户端完成数据发送时,向服务端发送一个FIN报文段来终止这一方向的连接,服务端收到FIN报文段以后只是说明客户端不会再向服务端发送数据了,但是服务端仍有可能向客户端发送数据,直到服务端也向客户端发送了FIN报文段。
问题2:为什么在TIME-WAIT状态必须等待2MSL的时间?
1.保证客户端发送的确认报文能够到达服务端(可靠的终止TCP连接)。客户端发给服务端的确认报文可能会丢失,若服务端没有收到确认报文,服务端会超时重传FIN+ACK报文段,客户端就可以在2MSL时间段内收到服务端重传来的FIN+ACK报文段;接着,客户端重传一次确认报文段,且重新启动2MSL计时器,直到客户端和服务端都进入CLOSED状态,否则,服务端无法正常进入CLOSED状态。
2.防止已经失效的连接请求报文出现在新连接中。客户端发送完确认报文段以后,经过2MSL时间段后,就可以使本连接持续的时间内所产生的所有的报文段从网络中消失;就可以使下一个新的连接中不会出现本连接失效的连接请求报文段。