TCP 三次握手和四次挥手:从入门到掉坑指南
大家好,我是33blog的站长。今天想和大家聊聊 TCP 连接的那些事儿。作为一个经常和网络打交道的码农,我见过太多因为不理解 TCP 握手/挥手而踩坑的案例了。今天就让我们用最接地气的方式,把这个看似高深的概念讲明白。
一、TCP 连接就像谈恋爱
第一次看到 TCP 三次握手时,我脑子里浮现的就是相亲场景:
- 客户端:”Hi,能认识一下吗?”(SYN)
- 服务端:”好啊,我也正想认识你”(SYN-ACK)
- 客户端:”那我们开始交往吧!”(ACK)
看,这不就是三次握手嘛!其实网络通信和人际交往有很多相似之处,都需要建立信任关系。
二、三次握手详解
让我们用 Wireshark 抓包来看个真实案例:
No. Time Source Destination Protocol Info
1 0.000000 192.168.1.100 93.184.216.34 TCP [SYN] Seq=0
2 0.028763 93.184.216.34 192.168.1.100 TCP [SYN, ACK] Seq=0 Ack=1
3 0.028794 192.168.1.100 93.184.216.34 TCP [ACK] Seq=1 Ack=1
这里有个坑我踩过:第二次握手时服务端会同时发送 SYN 和 ACK。刚开始我总想不明白为什么要合并发送,后来才懂这是为了节省网络开销。
三、为什么不是两次握手?
新手常问:既然最终都要确认,为什么不能简化为两次?这里有个真实案例:
去年我们线上服务出现过因为网络延迟,导致旧的连接请求在新连接建立后才到达的情况。如果是两次握手,服务端就会错误地建立连接。而三次握手能有效避免这种”历史连接”问题。
四、四次挥手:优雅的分手
如果说握手像恋爱,那么挥手就是分手了。但 TCP 的分手更文明:
1. 客户端:"我要走了"(FIN)
2. 服务端:"知道了"(ACK)
3. 服务端:"我也要走了"(FIN)
4. 客户端:"好的,再见"(ACK)
这里有个性能优化点:第二步和第三步不能合并,因为服务端可能还有数据要发送。我见过有人强行合并导致数据丢失的惨案。
五、TIME_WAIT 的烦恼
说到挥手,不得不提 TIME_WAIT 状态。有一次我们的服务器因为这个状态堆积导致无法创建新连接,当时急得我直冒汗。
简单来说,主动关闭连接的一方会保持 TIME_WAIT 状态 2MSL(约1-4分钟),这是为了:
- 确保最后一个 ACK 能到达
- 让网络中旧的报文段消失
解决方案?可以调整内核参数,但千万别禁用,否则会出现各种灵异问题。
六、实战建议
根据我的踩坑经验,给大家几个实用建议:
- 写网络程序时,一定要正确处理连接关闭
- 遇到连接问题,先用 tcpdump 或 Wireshark 抓包
- 理解原理比死记硬背更重要
记住,TCP 设计者的智慧远超我们想象,每个看似多余的步骤都有其深意。希望这篇文章能帮你少走些弯路!
用相亲来比喻三次握手太形象了!一下就明白了
想知道TIME_WAIT状态能不能设置得更短一点?遇到过类似问题
看完这篇文章感觉以前踩得坑都值了 😂 收藏了收藏了
建议补充下为什么四次挥手不能合并,文章里提到原因但只是一笔带过
作为一个前端小学生,终于get到网络这块的知识点了!
真实的Wireshark截图好评!希望以后多出这种实操教程
作者考虑出视频版吗?有些概念看动图可能更好理解 🤔
遇到过强行合并挥手导致数据丢失+1,血的教训啊
TCP设计真是精妙,感觉每个细节都值得研究
看完想重学计算机网络了!解释得太通透了