2026/5/19 1:26:53
网站建设
项目流程
广州大石附近做网站的公司哪家好,专业制作彩铃网站,注册logo商标设计要求,百度免费推广有哪些方式在《初始篇》中#xff0c;我们将网络比作一个复杂的物流系统。其中#xff0c;TCP#xff08;传输控制协议#xff09; 扮演了“可靠特快专递”的角色。对于后端开发者而言#xff0c;TCP 不仅仅是面试题中的那几张流程图。它是所有应用层协议#xff08;HTTP, RPC, MyS…在《初始篇》中我们将网络比作一个复杂的物流系统。其中TCP传输控制协议扮演了“可靠特快专递”的角色。对于后端开发者而言TCP 不仅仅是面试题中的那几张流程图。它是所有应用层协议HTTP, RPC, MySQL 连接的基石。在生产环境中无论是服务端的CLOSE_WAIT堆积报警还是高并发下的连接池耗尽根源往往都能追溯到 TCP 的状态流转上。面试官之所以热衷于问“三次握手”和“四次挥手”并非为了考察你的背诵能力而是看你是否理解在一个不可靠的通信信道IP 层之上如何通过严谨的状态机设计构建出一个可靠的通信连接今天我们深入 TCP 的心脏拆解这套支撑起整个互联网的连接管理机制。一、 三次握手不仅是“你好”很多同学对三次握手的理解停留在这个层面“A 问 B 在吗B 说在。A 说知道了。”这只是表象。TCP 三次握手的核心目的其实是为了同步双方的初始序列号。TCP 是基于字节流的为了保证数据不丢、不重、按序到达每一个字节都需要有一个编号。握手过程就是双方互相告知“我要开始发数据了我的起始编号是 X请你确认。”1. 握手全流程推演第一次握手 (SYN)客户端发送一个 SYN 报文SYN1并随机生成一个初始序列号 client_isn。此时客户端处于 SYN_SENT 状态。潜台词我要建立连接我的数据将从这个编号开始。第二次握手 (SYN ACK)服务端收到 SYN 后回复一个 SYN ACK 报文。它包含两层意思一是 ACK确认收到了客户端的序号ack client_isn 1二是 SYN服务端也生成自己的初始序列号 server_isn。此时服务端处于 SYN_RCVD 状态。潜台词收到了你的起始编号我记住了。我也要建立连接这是我的起始编号请你也确认一下。第三次握手 (ACK)客户端收到后回复一个 ACK 报文ack server_isn 1。此时客户端连接建立进入 ESTABLISHED 状态。服务端收到这个 ACK 后也进入 ESTABLISHED 状态。潜台词收到了你的起始编号我也记住了。连接建立成功。硬核面试题 1为什么是 3 次2 次不可以吗这是面试中最高频的问题。很多人会回答“为了防止失效的连接请求突然到达服务端”这没错但不够深刻。核心原因有两点防止历史连接的初始化假设网络拥堵客户端发送了 旧的 SYN (Seq90)然后又发送了 新的 SYN (Seq100)。如果只有 2 次握手服务端收到旧的 SYN (90) 后立刻回个 ACK 并建立连接。客户端发现“不对啊我想要的是 100你怎么回我 90” 于是客户端发送 RST 中止连接。但此时服务端已经建立了连接浪费了资源。如果是 3 次握手服务端收到旧的 SYN (90) 回复 SYNACK。客户端收到后发现 Seq 不对直接回一个 RST复位报文告诉服务端“这个是旧的别理它”。只有三次握手才能让客户端有“验证”的机会从而阻止历史连接。同步双方序列号TCP 是全双工的双向通信。2 次握手只能保证“客户端 - 服务端”的序列号被确认无法保证“服务端 - 客户端”的序列号被客户端确认。只有一来一回再一去双方的初始序列号才能都被可靠同步。硬核面试题 2什么是 SYN Flood 攻击原理攻击者伪造海量 IP发送大量的SYN包给服务端但就是不回第三次ACK。后果服务端的半连接队列 (Syn Queue)被瞬间填满导致无法处理正常的连接请求CPU 也会因为不断重发 SYNACK 而飙升。防御调大半连接队列、开启tcp_syncookies不将半连接放入队列而是通过 Cookie 验证。二、 四次挥手优雅的离场建立连接需要热情断开连接则需要耐心。因为 TCP 是全双工的这意味着通信的双方都有独立的发送和接收能力。断开连接的本质是双方都要单独关闭自己的“发送通道”。1. 挥手全流程推演第一次挥手 (FIN)客户端打算关闭连接发送 FIN 报文。此时客户端进入 FIN_WAIT_1 状态。潜台词我没有数据要发给你了我打算关闭我的发送通道。第二次挥手 (ACK)服务端收到 FIN回一个 ACK。此时服务端进入 CLOSE_WAIT 状态。潜台词知道了。但请你等一下我可能还有数据没发完你先别彻底挂断继续听我说。注意此时连接处于半关闭状态。客户端不能发数据了但还可以收数据。第三次挥手 (FIN)服务端把剩下的数据发完了也想断开了。于是发送 FIN 报文。此时服务端进入 LAST_ACK 状态。潜台词我的数据也发完了现在我也要关闭我的发送通道了再见。第四次挥手 (ACK)客户端收到 FIN回一个 ACK。此时客户端进入 TIME_WAIT 状态等待 2MSL 时间后才真正关闭 (CLOSED)。服务端收到 ACK 后立刻进入 CLOSED。潜台词好的收到了一路顺风。硬核面试题 3为什么握手是 3 次挥手却是 4 次握手时服务端收到 SYN 后因为没有历史负担它可以把“确认收到” (ACK) 和“我也要连接” (SYN) 合并在一个包里发送即 SYNACK所以 3 次就够了。挥手时服务端收到客户端的 FIN 时它可能还有数据在缓存区里没发完。它必须先回一个 ACK 说“我知道你想断了”然后继续把数据发完。等事情都处理好了再发自己的 FIN。ACK 和 FIN 很难合并发送所以需要分两步总共就是 4 次。三、 生产环境的噩梦CLOSE_WAIT 与 TIME_WAIT在后端面试和线上故障排查中TCP 的状态流转是重灾区。你必须死磕这两个状态。1. CLOSE_WAIT被动关闭方出现位置被动关闭连接的一方通常是服务端。现象如果你用netstat命令发现服务端有成千上万个CLOSE_WAIT状态说明系统这就快挂了。原因回顾四次挥手CLOSE_WAIT 出现在“收到对方 FIN回复 ACK”之后等待“发送己方 FIN”之前。如果你一直卡在这里说明服务端程序没有调用 close() 关闭连接。排查思路这通常是代码 Bug。比如在数据库连接池、HTTP Client 中处理完请求后忘记释放连接或者异常处理逻辑中漏掉了关闭连接的代码。2. TIME_WAIT主动关闭方出现位置主动发起关闭的一方客户端或者服务端主动断开连接时。现象高并发场景下如果服务器充当 Client 去调第三方接口可能会积累大量的TIME_WAIT导致端口耗尽。面试必问为什么客户端在发完最后一个 ACK 后还要等待 2MSL报文最大生存时间的 2 倍才关闭防丢包如果第四次挥手的 ACK 丢了服务端会重发 FIN。如果客户端早早关机了服务端就收不到响应了。TIME_WAIT就是为了“兜底”确保有足够的时间处理可能重传的 FIN。防混淆网络中可能存在“迷路”的旧数据包。等待 2MSL 可以让这些残存在网络中的旧报文自然消亡防止它们“尸变”跑到了下一个复用该端口的新连接中造成数据错乱。 总结TCP 的连接管理本质上是在不可靠的物理网络之上通过协商握手、确认ACK和状态机State Machine强行构建出的一种逻辑上的可靠性。三次握手是为了同步序列号防止历史连接困扰。四次挥手是因为全双工通信发送和接收要分别关闭。状态监控CLOSE_WAIT意味着代码泄露TIME_WAIT意味着主动关闭和端口占用。理解了这些当你再看到线上的网络报错时脑海中浮现的就不再是枯燥的定义而是数据包在网线两端交互的生动画面。如果这篇博文帮你看清了 TCP 的真面目欢迎点赞收藏