真实面经题目 · 原创解析
TCP 为什么需要四次挥手?
TCP 需要四次挥手,是因为 TCP 是全双工协议,两个方向的数据流要分别关闭。主动关闭方发送 FIN 只表示自己不再发送数据,对方收到后先 ACK 确认,但对方可能还有未发送完的数据,等它也发送完后再发 FIN,主动关闭方再 ACK,因此通常是四个报文段。
真实面经题目 · 原创解析
TCP 需要四次挥手,是因为 TCP 是全双工协议,两个方向的数据流要分别关闭。主动关闭方发送 FIN 只表示自己不再发送数据,对方收到后先 ACK 确认,但对方可能还有未发送完的数据,等它也发送完后再发 FIN,主动关闭方再 ACK,因此通常是四个报文段。
可以从全双工和半关闭解释。TCP 连接包含两个独立方向:A 到 B 和 B 到 A。A 主动关闭时发送 FIN,表示 A 到 B 方向没有数据了;B 收到后必须 ACK,但此时 B 到 A 方向可能还要继续发送剩余数据,所以不能立刻关闭整个连接。等 B 的应用层也决定关闭,B 再发送 FIN,表示 B 到 A 方向也结束;A 收到后回复 ACK,并进入 TIME_WAIT 等待一段时间,确保最后 ACK 能被重传并让旧报文在网络中消失。若 B 的 ACK 和 FIN 恰好合并,报文数量可能看起来少于四个,但逻辑上仍是两个方向分别关闭。
TCP 连接建立后,双方都可以同时发送和接收数据。关闭连接不是拔掉一根单向线,而是要分别关闭两个方向的数据流。一个方向不再发送,并不意味着另一个方向也已经没有数据。四次挥手反映的正是全双工连接在关闭阶段的独立性。
主动关闭方发送 FIN,含义是我这边已经没有数据要发了。发送 FIN 后,主动关闭方进入 FIN_WAIT_1,仍然可以接收对方数据。FIN 会消耗一个序号,接收方必须确认。这个阶段只关闭主动方到被动方的发送方向,不关闭反向数据流。
被动关闭方收到 FIN 后,内核会回复 ACK,告诉对方 FIN 已收到。此时被动方通常进入 CLOSE_WAIT,等待本地应用调用 close。CLOSE_WAIT 存在的原因是应用可能还有数据要写回,或者还没完成业务收尾。只要应用不关闭,内核不能擅自替它发送 FIN。
当被动方应用也完成发送并关闭连接时,内核发送 FIN,表示反向数据流也结束。主动关闭方收到后回复 ACK,随后进入 TIME_WAIT。被动方收到这个 ACK 后可以进入 CLOSED。到这里,两个方向都确认没有新数据,连接资源才能完整释放。
主动关闭方最后进入 TIME_WAIT 不是多余等待。它有两个作用:一是如果最后 ACK 丢失,被动方会重发 FIN,主动方还能再次 ACK;二是让网络中属于旧连接的延迟报文自然过期,避免同一四元组快速复用后被旧报文干扰。等待时长通常与最大报文生存时间相关。
建立时双方的 SYN 和 ACK 可以自然合并,服务端确认客户端 SYN 的同时发送自己的 SYN。关闭时被动方收到 FIN 后可能还有数据要发,ACK 和自己的 FIN 往往不能立即合并。
不一定。如果被动方没有剩余数据且内核时机合适,ACK 和 FIN 可能合并发送。但逻辑上仍然是两个方向分别确认关闭。
说明对端已经关闭发送方向,本机也确认了,但本机应用迟迟没有关闭 socket。常见原因是代码没有正确 close、线程阻塞或连接生命周期管理有缺陷。
先判断是否是正常短连接高峰,再考虑连接复用、长连接、调整应用主动关闭方、扩大端口范围和合理内核参数。不能为了减少数量盲目破坏协议安全性。