TCP协议中,建立一个连接需要三次握手,而终止一个连接要经过四次挥手。
一:原因
终止链接比建立链接多一次是因为第二次“握手”会发送SYN和ACK。SYN是请求连接标志,表示服务器端同意建立连接;ACK是确认报文,表示告诉客户端,服务器端收到了它的请求报文。
而终止链接是第二次“挥手”和第三次“挥手”分别发送ACK确认报文和FIN终止链接标志。
二:过程
1.三次握手
第一次握手:客户端给服务端发一个 SYN 报文,并指明客户端的初始化序列号 ISN。此时客户端处于 SYN_SENT 状态。
第二次握手:服务器收到客户端的 SYN 报文之后,会以自己的 SYN 报文作为应答,并且也是指定了自己的初始化序列号 ISN。同时会把客户端的 ISN + 1 作为ACK 的值,表示自己已经收到了客户端的 SYN,此时服务器处于 SYN_RCVD 的状态。
第三次握手:客户端收到 SYNACK 报文之后,会发送一个 ACK 报文,当然,也是一样把服务器的 ISN + 1 作为 ACK 的值,表示已经收到了服务端的 SYN 报文,此时客户端处于 ESTABLISHED 状态。服务器收到 ACK 报文之后,也处于 ESTABLISHED 状态,此时,双方已建立起了连接。
2.四次挥手
第一次挥手:客户端发送一个 FIN 报文,报文中会指定一个序列号。此时客户端处于 FIN_WAIT1 状态。
FIN=1,序号seq=u
第二次挥手:服务端收到 FIN 之后,会发送 ACK 报文,且把客户端的序列号值 +1 作为 ACK 报文的序列号值,表明已经收到客户端的报文了,此时服务端处于 CLOSE_WAIT 状态。此时的TCP处于半关闭状态,客户端到服务端的连接释放。客户端收到服务端的确认后,进入FIN_WAIT2(终止等待2)状态,等待服务端发出的连接释放报文段。此时服务端开始准备释放服务端到客户端方向上的连接。
ACK=1,确认号ack=u+1,序号seq=v
第三次挥手:和客户端的第一次挥手一样发送 FIN 报文,且指定一个序列号。此时服务端处于 LAST_ACK 的状态。等待客户端的确认。此时服务端停止在服务端到客户端的方向上发送数据,但是服务器端仍然能够接收从客户端传输过来的数据。
FIN=1,ACK=1,序号seq=w,确认号ack=u+1
第四次挥手:客户端收到 FIN 之后,一样发送一个 ACK 报文作为应答,且把服务端的序列号值 +1 作为自己 ACK 报文的序列号值,此时客户端处于 TIME_WAIT 状态。需要过一阵子以确保服务端收到自己的 ACK 报文之后才会进入 CLOSED 状态,服务端收到 ACK 报文之后,就处于关闭连接了,处于 CLOSED 状态。
客户端进入TIME_WAIT(时间等待)状态。此时TCP未释放掉,需要经过时间等待计时器设置的时间2MSL后,客户端才进入CLOSED状态。
ACK=1,seq=u+1,ack=w+1
简单来说,就是通过三次握手来确定是否可以发送和接收,以及如何接收。
依赖四种可靠机制——确认、排序、流控、重传。
三:2MSL等待状态
1.TIME_WAIT状态也称为2MSL等待状态。
MSL是Maximum Segment Lifetime的英文缩写,可译为“最长报文段寿命”,它是任何报文在网络上存在的最长的最长时间,这是一个工程值(经验值),不同的系统中可能不同。
当TCP执行一个主动关闭,并发回最后一个ACK,该连接必须在TIME_WAIT状态停留的时间为2倍的MSL,这就是2MSL等待状态。
2.四次挥手释放连接时,等待2MSL的原因:
保证客户端发送的最后一个ACK报文段能够到达服务端。
防止“已失效的连接请求报文段”出现在本连接中
3.在2MSL阶段可能发生两种情况:
如果客户端在2MSL内,再次收到了来自服务器端的FIN报文,说明服务器端由于各种原因没有接收到客户端发出的ACK确认报文。客户端再次向服务器端发出ACK确认报文,计时器重置,重新开始2MSL的计时;
如果客户端在2MSL内没有再次收到来自服务器端的FIN报文,说明服务器端正常接收了ACK确认报文,客户端可以进入CLOSED阶段,完成“四次挥手”。