说一说四次挥手
PS:这个问的太多了,大家要先理解 =》背诵,防止突然忘了也能说个大概。这道题在问的时候,可深可浅,看面试官自己的掌握力度。
参考回答
四次挥手是TCP连接断开的过程,用于保证双方都能可靠地断开连接。具体过程如下:
- 第一次挥手:客户端发送一个FIN报文,表示它想关闭连接,并不再发送数据。
- 第二次挥手:服务器收到FIN后,发送ACK报文表示确认,同时进入“半关闭”状态,客户端到服务器的连接断开,但服务器还可以继续发送数据。
- 第三次挥手:服务器发送FIN报文,表示它的数据也发送完毕,准备关闭连接。
- 第四次挥手:客户端收到FIN后,发送ACK报文,确认连接关闭。
至此,TCP连接正式断开。
详细讲解与拓展
1. 为什么需要四次挥手?
四次挥手的设计基于TCP的全双工通信模式,发送和接收的数据流是独立的。关闭连接时,双方需要分别关闭发送和接收通道,因此需要额外的确认步骤来确保双方都正确断开。
2. 四次挥手的具体过程
- 第一次挥手(客户端 → 服务器,发送FIN):
客户端发送FIN报文,表示它完成了数据发送,准备关闭连接。此时,客户端进入FIN_WAIT_1
状态。作用:通知服务器“我这边的数据发完了,后续不会再发了。”
-
第二次挥手(服务器 → 客户端,发送ACK):
服务器收到FIN后,发送ACK报文,确认已经收到客户端的关闭请求,但此时服务器可能还有数据需要发送,因此不会立即关闭连接。此时服务器进入CLOSE_WAIT
状态,客户端进入FIN_WAIT_2
状态。作用:服务器告诉客户端“我知道你不再发送数据了,但我还有数据需要处理。”
-
第三次挥手(服务器 → 客户端,发送FIN):
服务器发送完所有数据后,发送FIN报文给客户端,表示它也完成了数据发送,准备关闭连接。此时服务器进入LAST_ACK
状态。作用:通知客户端“我也发完了,可以关闭连接了。”
-
第四次挥手(客户端 → 服务器,发送ACK):
客户端收到服务器的FIN后,发送ACK报文,确认收到服务器的关闭请求。此时客户端进入TIME_WAIT
状态,等待一段时间后(一般为2倍的报文最大生存时间2MSL
),再彻底关闭连接。作用:客户端告诉服务器“我收到了,可以放心关闭了。”
3. 为什么客户端需要等待TIME_WAIT
?
客户端在发送最后的ACK后进入TIME_WAIT
状态,主要是为了确保最后的ACK能够被服务器收到。如果服务器没有收到ACK,会重新发送FIN报文,客户端需要在此期间重发ACK。
等待时间通常为2MSL
(Maximum Segment Lifetime,报文最大生存时间),以确保网络中遗留的报文全部消失。
4. 握手和挥手的对比
过程 | 三次握手 | 四次挥手 |
---|---|---|
目的 | 建立连接 | 关闭连接 |
交互次数 | 三次 | 四次 |
状态切换 | 快速完成 | 涉及TIME_WAIT ,需要额外等待 |
是否对称 | 对称 | 不对称(客户端和服务器状态切换不同步) |
5. 举例帮助理解
假设你在打电话:
- 第一次挥手(你说“我不讲了”): 你告诉朋友“我这边说完了,准备挂电话了。”
- 第二次挥手(朋友回应“好的”): 朋友确认说“我知道你不讲了,但我还有话要说。”
- 第三次挥手(朋友说“我也说完了”): 朋友告诉你“我这边也说完了,准备挂电话了。”
- 第四次挥手(你回应“好的,我们挂了吧”): 你确认收到后,挂断电话,结束通话。
这个过程确保双方都能完整地说完各自的话,并确认对方已经准备好挂断。
6. 扩展:四次挥手中的异常情况
- 为什么需要“半关闭”状态?
四次挥手中,服务器在第二次挥手后进入CLOSE_WAIT
状态,仍然可以发送数据,这种状态叫“半关闭”。
这是为了确保服务器能够处理客户端最后的请求,例如发送日志或告别消息。 -
服务器断开时的
TIME_WAIT
状态?
一般是客户端进入TIME_WAIT
状态,但在某些实现(如某些负载均衡场景)中,服务器也可能进入TIME_WAIT
状态,用于避免连接泄漏。 -
如何减少
TIME_WAIT
的开销?
在高并发场景中,过多的TIME_WAIT
连接会消耗系统资源,常用的优化方法包括:- 启用TCP端口复用(SO_REUSEADDR/SO_REUSEPORT)
- 调小
TIME_WAIT
的时间(通过调整内核参数,如tcp_fin_timeout
)。
7. 四次挥手和连接断开中的安全问题
- 资源耗尽攻击:
如果攻击者频繁发送FIN报文,可能导致服务器进入大量的CLOSE_WAIT
状态,消耗系统资源。 -
半关闭利用:
攻击者可能利用“半关闭”状态,在服务器没有彻底关闭连接时发送恶意数据。因此,服务器需要合理管理连接的生命周期。
总结
四次挥手是TCP可靠断开的保障机制,强调了通信的对称性和完整性。通过理解挥手过程和状态切换,能更好地掌握TCP协议的设计思想。在面试中,可以简要描述过程,并结合TIME_WAIT
的意义和优化场景进行拓展。