TCP四次挥手
四次挥手

-
客户端打算关闭连接,此时会发送一个 TCP 首部 FIN 标志位被置为 1 的报文,也即 FIN 报文,之后客户端进入 FIN_WAIT_1 状态。
-
服务端收到该报文后,就向客户端发送 ACK 应答报文,接着服务端进入 CLOSE_WAIT 状态。
-
客户端收到服务端的 ACK 应答报文后,之后进入 FIN_WAIT_2 状态。
-
等待服务端处理完数据后,应用程序调用close函数,也向客户端发送 FIN 报文,之后服务端进入 LAST_ACK 状态。
-
客户端收到服务端的 FIN 报文后,回一个 ACK 应答报文,之后进入 TIME_WAIT 状态
-
服务端收到了 ACK 应答报文后,就进入了 CLOSE 状态,至此服务端已经完成连接的关闭。
-
客户端在经过 2MSL 一段时间后,自动进入 CLOSE 状态,至此客户端也完成连接的关闭。
为什么需要四次挥手?
-
关闭连接时,客户端向服务端发送 FIN 时,仅仅表示客户端不再发送数据了但是还能接收数据。
-
服务端收到客户端的 FIN 报文时,先回一个 ACK 应答报文,而服务端可能还有数据需要处理和发送,等服务端不再发送数据时,才发送 FIN 报文给客户端来表示同意现在关闭连接。
-
客户端需要回复第四次挥手ACK,服务端收到后才知道对方关闭连接了,不然服务端不清楚对方是否收到了第三次挥手,是否正常关闭连接了
第一次挥手丢失了,会怎样?
客户端迟迟收不到 ACK 的话,就会触发超时重传机制,重传 FIN 报文,重发次数由 tcp_orphan_retries (默认7)参数控制。
当客户端重传 FIN 报文的次数超过 tcp_orphan_retries 后,就不再发送 FIN 报文,则会在等待一段时间(时间为上一次超时时间的 2 倍),如果还是没能收到第二次挥手,那么直接进入到 close 状态。
第二次挥手丢失了,会怎样?
客户端会以为自己的第一次挥手丢失,触发重传
第三次挥手丢失了,会怎样?
服务端收不到第四次挥手,会触发重传,重发次数由 tcp_orphan_retries 参数控制。如果一直收不到就断开连接。
客户端如果是通过close()函数关闭连接的,表示关闭发送和接收数据,如果 tcp_fin_timeout (默认60s)时间内还是没能收到服务端的第三次挥手(FIN 报文),那么客户端就会断开连接。如果是通过shutdown()函数关闭连接,表示只关闭发送,可以接收,这时候如果一直收不到第三次挥手,连接会一直存在。
第四次挥手丢失了,会怎样?
服务端会以为自己的第三次挥手丢失了,触发重传
客户端重复接收到第三次挥手时,会重置TIME_WAIT的时间

浙公网安备 33010602011771号