深入理解 TCP 协议中三次握手建立连接和四次挥手关闭连接的核心逻辑

你想深入理解 TCP 协议中三次握手建立连接四次挥手关闭连接的核心逻辑,这是 TCP 面向连接、可靠通信的基础。我会用「流程拆解+状态变化+通俗解释+LwIP 实现关联」的方式,帮你把这两个核心机制讲透。

一、三次握手(TCP 建立连接)

核心目标

客户端和服务端通过三次交互,同步序列号和确认号协商初始窗口大小,最终建立双向可靠的通信链路,确保双方都做好了收发数据的准备。

完整流程(附状态变化)

服务端 客户端 服务端 客户端 初始状态:LISTEN 初始状态:CLOSED 状态:SYN_SENT 状态:SYN_RCVD 状态:ESTABLISHED 状态:ESTABLISHED 连接建立完成,可收发数据 1. SYN报文 (SEQ=x,SYN=1) 2. SYN+ACK报文 (SEQ=y,ACK=x+1,SYN=1,ACK=1) 3. ACK报文 (SEQ=x+1,ACK=y+1,ACK=1)

步骤详解(通俗版)
  1. 第一次握手(客户端→服务端)

    • 客户端主动发起连接,发送 SYN 报文(同步报文),携带自己的初始序列号 x,并将 SYN 标志位设为 1。
    • 客户端状态从 CLOSEDSYN_SENT,等待服务端确认。
    • (LwIP 中对应 tcp_connect() 函数,触发 SYN 报文发送)
  2. 第二次握手(服务端→客户端)

    • 服务端收到 SYN 报文后,确认客户端的序列号(ACK=x+1),同时发送自己的 SYN 报文(初始序列号 y),将 SYNACK 标志位都设为 1。
    • 服务端状态从 LISTENSYN_RCVD,并进入 ESTABLISHED(已建立)状态,准备接收数据。
    • (LwIP 中 tcp_in.c 处理 SYN 报文,触发 SYN+ACK 响应)
  3. 第三次握手(客户端→服务端)

    • 客户端收到 SYN+ACK 报文后,确认服务端的序列号(ACK=y+1),发送 ACK 报文(仅确认,无数据)。
    • 客户端状态从 SYN_SENTESTABLISHED,此时双向连接完全建立,双方可开始收发数据。
    • (LwIP 中客户端收到 SYN+ACK 后,发送最终 ACK,完成连接建立)
为什么需要三次握手?
  • 核心是防止"失效的连接请求报文"被服务端接收(比如客户端超时重发的旧 SYN 报文延迟到达)。
  • 三次握手能确保双方都确认"对方能收/发报文",避免服务端为无效连接分配资源(比如创建 socket、分配缓冲区)。

二、四次挥手(TCP 关闭连接)

核心目标

TCP 是全双工通信(双方可同时收发数据),关闭连接时需要分别关闭"客户端→服务端"和"服务端→客户端"两个方向的链路,因此需要四次交互。

完整流程(附状态变化)

服务端 客户端 服务端 客户端 初始状态:ESTABLISHED 状态:FIN_WAIT_1 状态:CLOSE_WAIT 状态:FIN_WAIT_2 状态:LAST_ACK 状态:TIME_WAIT 状态:CLOSED 等待2MSL后→CLOSED 1. FIN报文 (SEQ=u,FIN=1) 2. ACK报文 (SEQ=v,ACK=u+1,ACK=1) 3. FIN报文 (SEQ=w,ACK=u+1,FIN=1) 4. ACK报文 (SEQ=u+1,ACK=w+1,ACK=1)

步骤详解(通俗版)
  1. 第一次挥手(客户端→服务端)

    • 客户端主动关闭连接,发送 FIN 报文(终止报文),携带当前序列号 uFIN 标志位设为 1,表示"我没有数据要发了"。
    • 客户端状态从 ESTABLISHEDFIN_WAIT_1,等待服务端确认。
    • (LwIP 中对应 tcp_close() 函数,触发 FIN 报文发送)
  2. 第二次挥手(服务端→客户端)

    • 服务端收到 FIN 报文后,先发送 ACK 报文确认(ACK=u+1),表示"我收到你关闭的请求了"。
    • 服务端状态从 ESTABLISHEDCLOSE_WAIT(关闭等待),此时服务端仍可向客户端发送剩余数据。
    • 客户端收到 ACK 后,状态从 FIN_WAIT_1FIN_WAIT_2,等待服务端发送自己的 FIN 报文。
  3. 第三次挥手(服务端→客户端)

    • 服务端发送完所有数据后,主动发送 FIN 报文(序列号 w),表示"我也没有数据要发了,你可以关闭了"。
    • 服务端状态从 CLOSE_WAITLAST_ACK,等待客户端最终确认。
  4. 第四次挥手(客户端→服务端)

    • 客户端收到 FIN 报文后,发送 ACK 报文确认(ACK=w+1),状态从 FIN_WAIT_2TIME_WAIT
    • 服务端收到 ACK 后,状态从 LAST_ACKCLOSED,完成关闭。
    • 客户端需等待 2MSL(报文最大生存时间) 后,才从 TIME_WAITCLOSED(防止延迟的报文干扰新连接)。
为什么需要四次挥手?
  • TCP 是全双工通信,关闭连接时需要"双向确认":客户端先关闭自己的发送方向,服务端确认后,再关闭自己的发送方向,客户端最后确认。
  • 服务端收到 FIN 后可能还有未发送完的数据,因此需要先回 ACK 确认关闭请求,待数据发完后再发 FIN 关闭自己的方向。

三、LwIP 中与握手/挥手相关的核心模块

  • 三次握手:tcp.c 中的 tcp_connect()tcp_listen()tcp_in.c 中的 tcp_process_syn()(处理 SYN 报文)。
  • 四次挥手:tcp.c 中的 tcp_close()tcp_abort()tcp_in.c 中的 tcp_process_fin()(处理 FIN 报文)。
  • 状态管理:LwIP 用 struct tcp_pcb(TCP 协议控制块)中的 state 字段维护连接状态(如 SYN_SENTESTABLISHEDTIME_WAIT 等)。

总结

核心关键点
  1. 三次握手 :核心是同步序列号+双向确认,确保连接建立的可靠性,避免无效连接;
  2. 四次挥手 :核心是全双工链路的双向关闭,服务端需先确认关闭请求,待数据发完后再主动关闭;
  3. 状态变化是关键:握手/挥手的本质是 TCP 连接状态的有序切换,LwIP 通过 tcp_pcb 管理这些状态;
  4. 特殊状态:TIME_WAIT 是客户端关闭后的"等待期",目的是避免延迟报文干扰新连接。

简单记:握手是"你好→收到你好,我也好→收到你也好",挥手是"我走了→收到你走→我也走了→收到你也走"。

相关推荐
北京耐用通信7 分钟前
不换设备、不重写程序:耐达讯自动化网关如何实现CC-Link IE转Modbus TCP的高效互通?
人工智能·科技·物联网·网络协议·自动化·信息与通信
志栋智能17 分钟前
超自动化巡检:实现运维“事前预防”的关键拼图
大数据·运维·网络·人工智能·机器学习·自动化
七夜zippoe23 分钟前
OpenClaw 技能开发实战:从零到一
运维·服务器·网络·openclaw·技能开发
liweiweili12625 分钟前
http数据传输过程数据编码解码问答
网络协议·http·状态模式
oi..26 分钟前
《Web 安全入门|XSS 漏洞原理、CSP 策略与 HttpOnly 防护实践》
前端·网络·测试工具·安全·web安全·xss
加勒比之杰克1 小时前
从阻塞 IO 到 epoll:把 Linux 网络 IO 一次讲透
linux·网络·windows·select·多路转接·epoll·poll
Dynadot_tech1 小时前
完成注册的域名可以做什么?
网络·域名·dynadot·网站域名
有代理ip1 小时前
动态IP的安全性优化:策略升级与隐私保护实战指南
网络·网络协议·tcp/ip
CDN3601 小时前
高防 IP 回源 502/504 异常?源站放行与健康检查修复
网络·网络协议·tcp/ip
说实话起个名字真难啊1 小时前
Docker 入门之网络基础
网络·docker·php