深入理解 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。
    • 客户端状态从 CLOSED → SYN_SENT,等待服务端确认。
    • (LwIP 中对应 tcp_connect() 函数,触发 SYN 报文发送)
  2. 第二次握手(服务端→客户端):

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

    • 客户端收到 SYN+ACK 报文后,确认服务端的序列号(ACK=y+1),发送 ACK 报文(仅确认,无数据)。
    • 客户端状态从 SYN_SENT → ESTABLISHED,此时双向连接完全建立,双方可开始收发数据。
    • (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 报文(终止报文),携带当前序列号 u,FIN 标志位设为 1,表示"我没有数据要发了"。
    • 客户端状态从 ESTABLISHED → FIN_WAIT_1,等待服务端确认。
    • (LwIP 中对应 tcp_close() 函数,触发 FIN 报文发送)
  2. 第二次挥手(服务端→客户端):

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

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

    • 客户端收到 FIN 报文后,发送 ACK 报文确认(ACK=w+1),状态从 FIN_WAIT_2 → TIME_WAIT。
    • 服务端收到 ACK 后,状态从 LAST_ACK → CLOSED,完成关闭。
    • 客户端需等待 2MSL(报文最大生存时间) 后,才从 TIME_WAIT → CLOSED(防止延迟的报文干扰新连接)。
为什么需要四次挥手?
  • 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_SENT、ESTABLISHED、TIME_WAIT 等)。

总结

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

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

相关推荐
运维行者_14 分钟前
网络性能监控怎么做?从自动发现到根因分析的4个环节
运维·服务器·网络·人工智能·支持向量机
hz567892 小时前
涉密视频会议设备配置指南:终端、音视频采集与配套设施选型
服务器·网络·数据库·安全·实时音视频·信息与通信·智能硬件
优橙教育2 小时前
零基础学AI应用开发要多久?3个月能到什么水平
服务器·开发语言·网络·php
AIgorithmGEEK3 小时前
[Linux]从手写报头到内核套路:序列化、反序列化与自定义协议全链路
linux·运维·服务器·网络·序列化·反序列化
深圳恒讯7 小时前
海外服务器延迟高怎么解决?从线路到TCP协议的6层排查清单
运维·服务器·tcp/ip
物联网软硬件开发-轨物科技7 小时前
【轨物洞见】什么是产品碳足迹(PCF)?ISO 14067 计算方法与应用场景深度解读
大数据·网络·人工智能
姜鱼问生9 小时前
docker exec 排查容器问题:从日志到进程
运维·网络·数据库·docker·容器
盛世宏博北京9 小时前
工业环境稳定采集:配电室 IP 温湿度变送器 TCP/UDP 通信部署指南
单片机·tcp/ip·udp
qq_5434478210 小时前
DNS解析怎么排查?故障处理与运维实用手册
运维·服务器·网络·php