TCP的三次握手与四次挥手

TCP 三次握手与四次挥手,其实就是把"开始"和"结束"确认清楚

刚开始学 TCP 的时候,很多人都会被"三次握手"和"四次挥手"绕进去。建立连接就建立连接,断开连接就断开连接,为什么还要搞这么多步骤?真的有必要吗?

其实只要抓住一点就够了:TCP 是一种追求可靠性的协议。网络本身并不稳定,丢包、延迟、乱序这些问题都可能发生。如果双方还没确认清楚状态,就直接开始传数据,出了问题谁负责?所以 TCP 的这些设计,说到底就是为了让通信这件事更稳一点、更靠谱一点。

三次握手:先确认双方都准备好了

TCP 在正式传输数据之前,会先进行三次握手。这个过程本质上就是双方先打个招呼,把状态确认清楚,避免一上来就"自作多情"。

第一次握手,客户端发送一个 SYN 报文,可以理解成一句很简单的话:"我想和你建立连接,你在吗?"

第二次握手,服务器收到之后,会回复一个 SYN + ACK,意思就是:"我收到了,你发过来的消息没问题。我这边也准备好了,那你能收到我的回复吗?"

第三次握手,客户端再回复一个 ACK,表示:"能收到,你这边也没问题,那我们正式开始通信吧。"

到了这一步,连接才算真正建立。

那为什么一定要三次?两次不行吗?关键就在于,两次还不够让双方都彻底确认状态。如果只有两次,服务器虽然回复了客户端,但它并不知道客户端到底有没有收到这个回复。万一客户端没收到,服务器却已经以为连接建立好了,那后面的数据传输不就可能出问题了吗?

所以,三次握手并不是为了显得复杂,而是为了确认一件事:双方的发送和接收能力都是正常的。该确认的都确认完了,后面传数据才有意义,不是吗?

四次挥手:不是一下断掉,而是双方分别结束

理解了三次握手,再看四次挥手其实就没那么难了。

很多人会问,建立连接只要三次,为什么断开连接反而要四次?按理说,结束不是应该更简单吗?

问题就在于,TCP 是全双工通信。也就是说,客户端和服务器都可以独立发送数据。你这边不发了,不代表对方也立刻发完了。所以断开连接的时候,不能一句"拜拜"就直接结束,而是要两边分别把自己的发送通道关掉。

第一次挥手,客户端发送一个 FIN,意思是:"我这边已经没有数据要发了。"

第二次挥手,服务器回复 ACK,表示:"好,我知道你这边发完了。"

但这里要注意,服务器只是知道客户端不发了,并不代表服务器自己也已经发完了。也许它还有一些数据没传完,所以连接这时候还不能直接断。

第三次挥手,等服务器自己的数据也发完了,它再发送一个 FIN,意思是:"我这边也结束了。"

第四次挥手,客户端最后回复一个 ACK,表示:"好,那这次真的可以断开了。"

你看,四次挥手本质上不是"多此一举",而是因为 TCP 的连接是双向的,关闭时自然也要分开处理。说白了,就是你关你的,我关我的,谁都别糊里糊涂。

为什么最后还要有 TIME_WAIT?

讲到这里,通常还会遇到一个问题:客户端在最后回复完 ACK 之后,为什么还不能立刻关闭,而是要进入 TIME_WAIT 状态?

这个设计看起来有点麻烦,但实际上很有必要。

你想一下,如果客户端发出的最后一个 ACK 丢了,服务器就会以为自己的 FIN 没有被确认,于是它会重新发送一次 FIN。这时候如果客户端已经直接把连接彻底关掉了,那这个重发的 FIN 就没人处理了,连接状态就可能变得混乱。

所以 TCP 选择让客户端先等一会儿,留出一个缓冲时间。这样做主要有两个目的:第一,防止最后的确认丢失后没人补救;第二,避免旧连接里残留的数据影响后面新的连接。

说到底,TIME_WAIT 不是浪费,而是 TCP 在替不可靠的网络"兜底"。网络都不一定靠谱,协议多留一步保险,不也很正常吗?

我的理解:TCP 麻烦一点,是因为它不想出错

如果只背概念,三次握手和四次挥手很容易变成一堆死流程。但从本质上看,它们其实都在做同一件事:把状态确认清楚。

三次握手,解决的是"连接怎么可靠地建立";

四次挥手,解决的是"连接怎么可靠地关闭"。

TCP 之所以看起来步骤多,不是因为它喜欢复杂,而是因为它不相信网络环境会一直老老实实。少一次确认,平时可能没什么感觉,但真遇到丢包、超时或者异常情况的时候,问题就出来了。那既然这样,开始之前多确认一次,结束之前再确认一次,不是更稳妥吗?

总结

三次握手和四次挥手,其实没有表面看上去那么难。前者是在正式通信前确认双方都准备好了,后者是在断开连接时确认双方都处理完了。看似步骤很多,实际上都围绕着"可靠"两个字展开。

所以,TCP 真正想解决的,从来不是"怎么更快地连上"或者"怎么更快地断开",而是"怎么在不稳定的网络里,把连接这件事处理得足够清楚、足够安全"。这也正是它能长期成为主流传输协议的重要原因。

相关推荐
m0_738120724 小时前
网络安全编程——Python编写基于UDP的主机发现工具(解码IP header)
python·网络协议·tcp/ip·安全·web安全·udp
洒家肉山大魔王4 小时前
PKI/CA X.509证书的基础应用与解读
服务器·https·密码学·数字证书
北京耐用通信4 小时前
不换设备、不重写程序:耐达讯自动化网关如何实现CC-Link IE转Modbus TCP的高效互通?
人工智能·科技·物联网·网络协议·自动化·信息与通信
xingyuzhisuan4 小时前
Blender渲染加速:4090服务器OptiX后端性能提升50%
运维·服务器·性能优化·gpu算力
Trouvaille ~4 小时前
【MySQL篇】数据库操作:从创建到管理
linux·数据库·mysql·oracle·xshell·ddl
2401_839633914 小时前
Flutter 框架跨平台鸿蒙开发 - 声音密码锁
服务器·flutter·华为·harmonyos
酸钠鈀4 小时前
AI WB2 SDK Ubuntu 环境搭建
linux·运维·ubuntu
志栋智能4 小时前
超自动化巡检:实现运维“事前预防”的关键拼图
大数据·运维·网络·人工智能·机器学习·自动化
Robot_Nav4 小时前
双系统Linux死机解决方法
linux·运维·服务器