三次握手四次挥手(对话场景)

一、先搞懂背景:TCP 是个什么东西?

TCP 是一个可靠的、面向连接的协议。

  • 就像打电话:你和对方都要先 "喂?听得见吗?" 确认线路没问题,再开始说话,说完还要互相确认 "我挂了",避免对方还在等。
  • 三次握手就是建立连接的过程 ,四次挥手就是断开连接的过程

二、三次握手:建立连接(为什么是三次,不是两次?)

核心目标

让客户端和服务器,互相确认三件事:

  1. 我的发送能力没问题
  2. 我的接收能力没问题
  3. 对方的发送和接收能力也没问题

角色分工

  • 客户端:主动发起连接的一方(比如你的浏览器)
  • 服务器:被动等待连接的一方(比如网站的服务器)

三次握手的完整流程(带对话场景)

假设客户端叫 A,服务器叫 B。

第一次握手:A → B(SYN)

A 给 B 打电话:

"喂,B 吗?我是 A,我想跟你连个线,我的初始序号是 x,你能听到我说话吗?"

  • 对应报文:SYN=1seq=x
  • 服务器收到后:知道了 "A 的发送能力没问题,B 的接收能力也没问题",但 B 还不知道 A 能不能听到自己说话。
第二次握手:B → A(SYN+ACK)

B 给 A 回电话:

"我听到你了 A!你的序号 x 我收到了,我确认收到你的请求(ACK=x+1)。我也想跟你连线,我的初始序号是 y,你能听到我说话吗?"

  • 对应报文:SYN=1ACK=1ack=x+1seq=y
  • 客户端收到后:知道了 "B 的发送和接收能力都没问题,A 的接收能力也没问题"。
第三次握手:A → B(ACK)

A 再回 B 一句:

"收到你的回应啦!我也听到你说话了,确认你的序号 y(ACK=y+1),我们可以开始传数据了!"

  • 对应报文:ACK=1ack=y+1
  • 服务器收到后:终于确认 "A 的接收能力没问题",双方正式建立连接。

为什么不能两次握手?

如果只有两次,B 发完第二次握手的包后,就以为连接建立成功了,开始给 A 发数据。但如果 A 没收到这个包,A 根本不知道 B 要连,就会忽略 B 的数据,B 这边就会一直等 A 回应,白白浪费资源。三次握手就是为了双向确认双方都收到了对方的信号,避免这种 "单向确认" 的问题。


三、四次挥手:断开连接(为什么是四次?)

TCP 是全双工的,意思是:A 和 B 可以同时互相发数据,像双向车道。断开连接时,两边都要确认自己这边的 "车道" 关了,所以需要四次挥手。

核心目标

双方都确认:

  1. 对方不会再给我发数据了
  2. 我这边也发完了,可以安全断开了

四次挥手的完整流程(带对话场景)

还是 A(客户端)和 B(服务器)。

第一次挥手:A → B(FIN)

A 说:

"B,我这边的数据发完了,我不想再给你发数据了,我准备关我的发送通道了(FIN),你收到了吗?"

  • 对应报文:FIN=1seq=u
  • B 收到后:知道 A 不会再发数据了,但 B 可能还有数据没发给 A,所以 B 先回个确认,不马上关自己的通道。
第二次挥手:B → A(ACK)

B 回 A:

"收到了,我知道你不发数据了,我先确认一下(ACK=u+1),我这边还有点数据要发给你,等我发完再跟你说。"

  • 对应报文:ACK=1ack=u+1
  • 此时,A 到 B 的方向(A 的发送通道)关闭了,但 B 到 A 的方向还能继续传数据。
第三次挥手:B → A(FIN)

B 把剩下的数据发完了,跟 A 说:

"A,我这边的数据也发完了,我也不想再给你发数据了,我准备关我的发送通道了(FIN),你收到了吗?"

  • 对应报文:FIN=1ACK=1seq=vack=u+1
  • A 收到后,知道 B 也发完了,准备回个确认。
第四次挥手:A → B(ACK)

A 回 B:

"收到了,我知道你不发数据了,确认一下(ACK=v+1),你可以关了。"

  • 对应报文:ACK=1ack=v+1
  • 服务器收到后,立刻关闭连接。客户端这边会等一段时间(TIME_WAIT),确保 B 收到了这个确认,避免 B 没收到,一直等不到回应。

为什么挥手是四次,握手却是三次?

因为握手的时候,B 可以把 "确认 A 的请求" 和 "向 A 发起连接请求" 合并成一个包(SYN+ACK),所以两次合并成了一次,总共三次。但挥手的时候,B 收到 A 的 FIN 后,可能还有数据没发完,不能马上回 FIN,必须先回 ACK 确认,等数据发完了再发 FIN,所以 ACK 和 FIN 必须分成两次发,总共四次。


四、关键补充:几个容易搞混的点

  1. SYN、ACK、FIN 是什么?
    • SYN:同步位,用来发起连接请求
    • ACK:确认位,用来告诉对方 "我收到你的包了"
    • FIN:结束位,用来发起断开请求
  2. 序号 seq 和确认号 ack 的作用
    • seq:我这次发的包的序号
    • ack:我收到了你序号为 x 的包,下次请从 x+1 开始发
    • 这两个序号是 TCP 保证数据不丢、不乱序的核心。
  3. **TIME_WAIT 为什么要等?**因为第四次挥手的 ACK 如果丢了,B 收不到,就会一直重发 FIN 请求。A 等一会儿,是为了确保 B 能收到 ACK,避免 B 一直卡在断开状态。
相关推荐
念恒123061 小时前
网络基础
linux·网络·c++
白山云北诗1 小时前
漏洞扫描+渗透测试:从资产摸底到风险验证,完成二次安全收口
网络·安全·web安全·渗透测试·漏洞扫描·ddos防护·cc防护
爱研究的小梁1 小时前
乾元通聚合路由及管理平台支持全面适配信创
网络·人工智能·信息与通信
KaMeidebaby2 小时前
卡梅德生物技术快报|bli亲和力检测gst:告别批量跑胶:BLI实时酶切监测技术加速GST融合蛋白下游流程优化
前端·网络·数据库·人工智能·算法
千维百策6662 小时前
运用 SRE 原则降低生产事故影响:CRE 实战经验与可靠性优化方法
网络·数据库·人工智能
三川6982 小时前
深入浅出SSD 08:PCIe的介绍
网络
2601_963282772 小时前
极寒专网技术拆解:黑龙江零下 40℃场景数字对讲组网全方案|黑龙江移远科技寒地通信底层技术解析
运维·网络·人工智能·科技
LedgerNinja3 小时前
WEEX API 稳定性实战:限频、重试与风控的工程化清单
运维·区块链
ZJH__GO3 小时前
网络编程v2--多客户端互通
java·运维·服务器·开发语言·计算机网络