四次挥手

#面试

img

挥手开始前客户端与服务器都处于ESTABLISHED状态,假设客户端先发起关闭请求:

  • 第一次挥手:客户端发送一个 FIN 报文,报文中指定一个序列号,此时客户端处于 FIN_WAIT1状态,即发出连接释放报文段,并停止发送数据,等待服务器确认。
  • 第二次挥手:服务器收到 FIN 报文后,会发送 ACK 报文,并且将客户端的序列号 + 1作为 ACK 报文的序列号值,此时服务器处于 CLOSE_WAIT 状态,此时的 TCP 连接处于半关闭的状态,客户端到服务器的连接被释放。客户端收到服务器的确认后,进入 FIN_WAIT2 状态,等待服务器发送的 FIN 报文。
  • 第三次挥手:服务器也发送一个 FIN 报文给客户端,并且指定一个序列号。此时服务器处于LAST_ACK状态,等待客户端确认。
  • 第四次挥手:客户端收到 FIN 报文后,一样发送一个 ACK 报文作为应答,并且将服务器的序列号 + 1 作为 ACK 报文的序列号值。客户端进入TIME_WAIT 状态,服务器收到应答后,直接进入 CLOSED 状态。客户端在发送应答请求后,会等待一段时间,然后由 TIME_WAIT 状态进入CLOSED 状态。

为什么不像三次握手那样,需要四次?

当服务器收到客户端的关闭报文后,并不会立即关闭socket,只会发送一个应答报文,表示收到了服务器的消息。当服务器的所有报文全部发送完毕后,服务器才能发起FIN报文,申请关闭。

在第三次挥手和第四次挥手间,进行等待的目的?

为了保证第四次挥手成功地被服务端接收到。如果第四次挥手报文丢失,则服务器会重发第三次挥手的内容。这样还在等待中的客户端就可以接收到重发的保文,再次进行关闭尝试。