简述四次断开(挥手)的过程
当客户端与服务器端进行数据传输完毕后,客户端主动请求关闭,服务器端被动关闭
第一次挥手:客户端向服务器端发送FIN包(seq=1,FIN=1),并进入FIN-WAIT1状态
第二次挥手:服务器端收到客户端发送的的包,会回复ACK确认包,表示收到,并进入CLOSE_WAIT 状态,客户端收到服务器的ACK包会进入FIN_WAIT2状态
第三次挥手: 服务器端向客户端发送FIN+ACK包给客户端,表示数据已经传输完毕,可以关闭了,并进入LAST_ACK,最后确认状态。
第四次挥手:客户端收到服务器端发送的包,回复ACK确认包,表示收到,然后进入TIME_WAIT状态,等待2MSL后进入CLOSE状态,服务器收到ACK确认包进入CLOSE状态。
四次挥手完毕
为什么是四次挥手?而不是三次?
三次握手是因为服务器端在收到客户端的syn请求包后,将ACK确认包和自己的SYN请求包合在一起发送给客户端了,而在结束时,客户端向服务器端发送FIN包,仅仅表示自己没有要传输的数据了,但这并不表示服务器端没有数据要传输给客户端了,所以服务器端在收到客户端发送的数据包后,会先发送一个ACK确认包给客户端,表示自己收到了,然后把自己的数据传输完毕,才会再次向服务器端发送FIN+ACK确认包,所以这就导致多出了一次。
为什么要等待2MSL?
另一种问法:TIME_WAIT状态是什么意思?有什么作用?
MSL(Maximum Segment Lifetime 最长的报文段寿命 或最长生命周期),TCP允许不同的实现可以设置不同的MSL值。
ACK 包到达服务器需要 MSL 时间,服务器重传 FIN 包也需要 MSL 时间,2MSL 是数据包往返的最大时间,如果 2MSL 后还未收到服务器重传的 FIN 包,就说明服务器已经收到了 ACK 包。
第一,保证客户端发送的最后一个ACK报文能够到达服务器,因为这个ACK报文可能丢失,站在服务器的角度看来,
我已经发送了FIN+ACK报文请求断开了,客户端还没有给我回应,应该是我发送的请求断开报文它没有收到,
于是服务器又会重新发送一次,而客户端就能在这个2MSL时间段内收到这个重传的报文,接着给出回应报文,并且会重启2MSL计时器。
第二,防止类似与“三次握手”中提到了的“已经失效的连接请求报文段”出现在本连接中。客户端发送完最后一个确认报文后,
在这个2MSL时间中,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样新的连接中不会出现旧连接的请求报文。