网络基础约 12 分钟阅读更新于 2026-07-30

TCP 三次握手、四次挥手和 Keep-Alive:连接怎么建立又怎么保持

围绕TCP 连接管理与 Keep-Alive 章节,讲清三次握手、四次挥手、HTTP Keep-Alive 和 TCP KeepAlive 的作用与区别。

相关工具

文章目录(10 个章节)

连接管理不是背流程,是确认状态

很多人第一次学 TCP,会把三次握手和四次挥手背成口令:SYN、SYN+ACK、ACK;FIN、ACK、FIN、ACK。背下来当然有用,但如果只停在这一步,遇到真实问题时还是会发懵。比如为什么要三次?为什么关闭时经常说四次?HTTP Keep-Alive 和 TCP KeepAlive 名字这么像,解决的是同一件事吗?

文中讲 TCP 的连接管理时,核心其实很朴素:TCP 是面向连接的协议。数据真正传输之前,双方要先确认彼此能收、能发,并同步后续传输要用的初始序列号;数据传完之后,也要把两个方向的发送状态分别收尾。连接的建立和释放,处理的都是“双方现在处在什么状态”这个问题。

理解了这一层,三次握手就不再是仪式,四次挥手也不是多此一举。它们是在给可靠传输铺路:先把通信双方拉到同一个起点,再在结束时把两个方向的通道都关干净。

三次握手:建立连接前先对齐收发能力

三次握手从客户端发起。第一步,客户端向服务器发送一个 SYN 报文,表示自己想建立连接,并带上客户端的初始序列号。这个序列号不是随便摆设,后续 TCP 会靠序列号追踪数据位置、确认哪些数据已经收到。

第二步,服务器收到 SYN 后,如果愿意建立连接,就回复 SYN+ACK。这里有两层意思:ACK 表示“我收到了你的连接请求和序列号”,SYN 表示“我这边也准备好了,这是我的初始序列号”。也就是说,服务器不是只点头,它还把自己的发送起点告诉客户端。

第三步,客户端再回一个 ACK,确认收到了服务器的 SYN。到这里,双方都知道对方能收,也知道对方能发;双方的初始序列号也同步好了,连接才进入可以传输数据的状态。

TCP 三次握手和四次挥手时序图,展示 SYN、SYN ACK、ACK 以及 FIN、ACK、FIN、ACK 的连接状态变化
三次握手与四次挥手

三次握手同步双方初始序列号并确认收发能力;四次挥手分别关闭两个传输方向。

为什么不是两次就够

如果只做两次,客户端发 SYN,服务器回 SYN+ACK,服务器这边已经知道客户端能发、自己能收;客户端收到后,也知道服务器能发、自己能收。看起来好像差不多了,但服务器还不知道客户端是否收到了自己的 SYN。

第三次 ACK 的意义就在这里:客户端告诉服务器,“你发来的同步信息我收到了”。服务器收到这个 ACK 后,才能确认自己的发送能力在客户端那边也被验证过。三次握手不是为了凑数字,而是为了让双方都完成一次“发送是否可达”和“接收是否可用”的确认。

这也是 文中说三次握手能确保双方可以正确传输数据的原因。连接建立以后,应用层看到的是一条可用的通道;但在 TCP 下面,这条通道已经经过了状态确认和序列号同步。

四次挥手:FIN 只关闭一个方向

关闭连接比建立连接更容易被误解。很多人会问:建立要三次,关闭为什么常说四次?关键在于 TCP 是全双工的。全双工的意思是,客户端到服务器、服务器到客户端,是两个方向的传输。一个方向不想再发数据了,不代表另一个方向也马上没数据可发。

资料 对四次挥手的描述很直接:客户端先发送 FIN,表示自己没有数据要发了;服务器收到后回复 ACK,表示知道了。此时客户端到服务器这个方向开始收尾,但服务器仍然可能还有数据要发给客户端,所以它不能立刻把整个连接粗暴关掉。

等服务器也确认自己没有数据要发送时,再向客户端发送 FIN。客户端收到后回复 ACK,表示也确认了服务器这一侧的结束请求。到这一步,两个方向都完成了停止发送的通知,连接才算真正释放。

HTTP Keep-Alive:让一个 TCP 连接服务多次请求

讲完连接的建立和释放,就能理解 HTTP Keep-Alive 为什么有价值了。早期 HTTP 如果每次请求都新建 TCP 连接,请求结束后立刻关闭,那么一个页面加载多张图片、多个脚本、多个接口时,就会反复握手、传输、挥手。真正的数据可能不大,连接管理的成本却被重复付了很多次。

HTTP Keep-Alive 解决的是复用问题:一次请求响应完成后,客户端和服务器不马上关闭 TCP 连接,而是把这条连接暂时保留下来,后续 HTTP 请求继续走同一条 TCP 连接。文中提到,HTTP/1.0 需要通过 `Connection: Keep-Alive` 开启;HTTP/1.1 默认采用长连接。

这类长连接的直接收益很清楚:减少 TCP 建立和关闭的开销,让同一连接承载多个请求响应,也降低一些重复传输带来的浪费。对网页、接口调用、小资源加载来说,这会让整体请求过程更顺。

Keep-Alive 不是一直不关

HTTP Keep-Alive 容易让人产生一个错觉:既然复用连接能省开销,那连接是不是越久越好?实际不是。连接长时间占着,服务器就要维护对应的 socket、缓冲区和状态。访问量一上来,闲置连接太多,会把服务端资源拖住。

所以长连接一般都会配合超时策略。连接空闲超过一段时间,服务器会主动关闭;有些服务器还会限制单条连接最多处理多少个请求。这样做不是和 Keep-Alive 矛盾,而是在复用效率和资源占用之间取平衡。

排查接口问题时,这一点很常见。你可能看到某些请求复用了连接,另一些请求又重新建连;原因不一定是客户端坏了,可能只是连接空闲超时、服务端达到了最大请求数,或者中间代理按自己的策略关闭了连接。

TCP KeepAlive:内核层面的空闲探测

TCP KeepAlive 和 HTTP Keep-Alive 名字相似,但层次完全不同。HTTP Keep-Alive 在应用层,目标是复用同一条 TCP 连接处理多个 HTTP 请求;TCP KeepAlive 在传输层,更靠近操作系统协议栈,目标是判断一条空闲 TCP 连接到底还活不活着。

文中提到,TCP KeepAlive 会在连接空闲时发送探测报文。如果对端仍然存在并能正常响应,就会回 ACK,连接继续保持;如果连续一段时间收不到 ACK,发送方就会认为连接可能已经断开,于是关闭连接并释放资源。

这在长时间空闲的连接里很有用。比如客户端异常断电、网络中断、NAT 设备悄悄丢掉映射,应用层不一定马上知道。没有探测机制时,服务端可能以为连接还在,资源也一直挂着。TCP KeepAlive 就是帮系统定期问一句:对面还在吗?

HTTP Keep-Alive 与 TCP KeepAlive 对比图,展示应用层连接复用和传输层空闲探测的区别
HTTP Keep-Alive 与 TCP KeepAlive 的区别

HTTP Keep-Alive 关注复用连接提升请求效率;TCP KeepAlive 关注探测空闲连接是否仍然存活。

两个 Keep-Alive 不要混着调

实际开发里,最容易踩坑的是把两个 Keep-Alive 当成一个开关。比如接口请求很慢,你去打开 TCP KeepAlive,通常不会解决问题。因为 TCP KeepAlive 不负责复用 HTTP 请求,它只是探测空闲连接是否还在。请求效率主要看 HTTP 连接复用、服务端配置、代理策略、TLS 复用、并发限制等因素。

反过来,HTTP Keep-Alive 也不能替代 TCP KeepAlive。HTTP 长连接能让多次请求走同一个 TCP 连接,但如果连接长时间没有应用层数据,底层网络是否还保留这条连接,并不是 HTTP 头本身能完全保证的。中间设备可能有自己的空闲超时,服务端也可能按策略关闭。

更稳妥的理解是:HTTP Keep-Alive 管“同一条连接能不能继续拿来发请求”;TCP KeepAlive 管“这条空闲连接是不是还真的活着”。一个偏性能,一个偏存活检测。名字像,职责不一样。

排查连接问题时怎么看

如果你发现接口每次都在重新建立连接,优先看 HTTP 层:请求或响应里有没有 `Connection: close`,客户端连接池是否开启,服务端是否支持长连接,中间代理有没有强制关闭。HTTP/1.1 默认长连接,但默认不代表永远复用,任何一方都可能因为超时、限制或策略结束连接。

如果问题是长时间空闲后第一次请求失败,更应该看超时链路:客户端连接池空闲时间、服务器 keep-alive timeout、负载均衡空闲超时、NAT 或防火墙超时。很多时候,不是 TCP 不可靠,而是某一层设备已经把空闲连接清掉了,应用还拿旧连接继续用。

如果是 WebSocket、数据库连接、消息队列这类长期连接,通常还会有应用层心跳。应用层心跳和 TCP KeepAlive 也不是一回事:应用心跳能确认业务协议还在正常处理,TCP KeepAlive 只能说明 TCP 对端还可能活着。排查时把层次分清,能少走很多弯路。

面试里怎么讲

如果被问三次握手,可以这样说:客户端发送 SYN 并带上初始序列号,服务器回复 SYN+ACK 并带上自己的初始序列号,客户端再回 ACK。三次握手的目的,是让双方确认彼此具备发送和接收能力,并同步后续传输需要的序列号。

如果被问四次挥手,就抓住全双工:FIN 只表示一方没有数据要发,不代表另一方也立刻结束。客户端 FIN 后,服务器先 ACK;等服务器也没有数据要发时,再 FIN;客户端最后 ACK。两个方向分别关闭,所以常见过程是四次。

如果被问 Keep-Alive,别急着只说“保持连接”。要补上层次:HTTP Keep-Alive 是应用层长连接,用来复用 TCP 连接处理多个 HTTP 请求响应;TCP KeepAlive 是传输层空闲探测,用来判断连接是否仍然存活。前者偏效率,后者偏状态检测。

常见问题

三次握手的核心目的是什么?

确认双方都具备发送和接收能力,并同步各自的初始序列号,为后续可靠传输做准备。

四次挥手为什么不能简单合成两次?

TCP 是全双工连接,一个方向结束发送不代表另一个方向也没有数据要发。FIN 只关闭一个发送方向,所以两个方向通常要分别通知和确认。

HTTP Keep-Alive 和 TCP KeepAlive 最大区别是什么?

HTTP Keep-Alive 是应用层连接复用机制,目标是减少重复建连成本;TCP KeepAlive 是传输层空闲探测机制,目标是发现连接是否还存活。

计算机网络

继续阅读

返回专题