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

相关推荐
米高梅狮子9 小时前
Ceph 分布式存储 部署
linux·运维·数据库·分布式·ceph·docker·华为云
WUYOUGYLU9 小时前
云服务器怎么选、怎么用,才不花冤枉钱
运维·服务器
不昀9 小时前
VOOHU沃虎:音频变压器的匝数比和阻抗比如何换算?
网络·音视频·以太网·网络通信·电子元器件
小明同学019 小时前
C++后端项目:统一大模型接入 SDK(四)
服务器·开发语言·c++·计算机网络·chatgpt
yqcoder9 小时前
数据的“包装方式”:深入解析 HTTP Content-Type
网络·网络协议·http
曦夜日长9 小时前
Linux系统篇,开发工具(五):git的基本使用和浅层认识
linux·运维·服务器
Harm灬小海9 小时前
【云计算学习之路】学习Centos7系统-ROOT密码重置方法
linux·运维·服务器·学习·云计算
IT瑞先生9 小时前
企业云服务器选型分析
运维·服务器
weixin_453639599 小时前
Docker Redis 本地能 Ping 通但 6379 端口连不上?排查记录与解决
linux·redis
Python-AI Xenon10 小时前
Linux逻辑卷(LVM)初始化与文件系统选型全指南
linux·运维·性能测试·存储