深入理解 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 是客户端关闭后的"等待期",目的是避免延迟报文干扰新连接。

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

相关推荐
咖啡の猫2 小时前
微信小程序网络数据请求
网络·微信小程序·小程序
boring_1112 小时前
AI时代本质的思考
网络·人工智能·智能路由器
Lam㊣2 小时前
Ubuntu(Ubuntu 22.04.4 LTS)更改IP地址及网关
tcp/ip·ubuntu·php
BEOL贝尔科技2 小时前
通过采集器监测环境的温湿度如果这个采集器连上网络接入云平台会发生什么呢?
网络·人工智能·数据分析
这儿有一堆花2 小时前
实战:FastAPI与WebSocket的高并发足球数据API开发指南
websocket·网络协议·fastapi
wearegogog1232 小时前
基于MATLAB的D2D仿真场景实现
开发语言·网络·matlab
Godspeed Zhao2 小时前
现代智能汽车中的无线技术00——智能汽车的无线依赖
网络·汽车
独自破碎E2 小时前
【字符串分割】验证IP地址
服务器·网络·tcp/ip
数通工程师3 小时前
实操教程:华为防火墙HRP主备模式完整配置步骤
运维·服务器·网络·网络协议·tcp/ip·华为