三次握手四次挥手的那些坑,连老司机都可能翻车!!!

各位搞网络的小伙伴注意啦(敲黑板)!今天咱们要聊的这个TCP连接/断开机制,简直是面试必考题+实际调试中的"鬼见愁"。别看原理好像很简单,信不信我随便说几个场景就能让你怀疑人生?

一、连接建立:三次握手真不是凑数

先来段硬核现场还原!当你在浏览器输入www.example.com时,背后发生了什么?

1.1 第一回合:SYN突袭

客户端(你的电脑)突然向服务器发送一个SYN=1的数据包,附带一个随机生成的初始序列号(比如Seq=10086)。这个动作就像突然拍别人肩膀:“嘿兄弟,能听见吗?”

关键点来了(画重点):

  • 随机序列号是为了防止历史连接混淆
  • 此时客户端进入SYN_SENT状态(等回复等到花儿都谢了)

1.2 第二回合:SYN-ACK组合拳

服务器收到SYN后,如果端口开着,就会回个SYN=1, ACK=1的包。这里有两个骚操作:

  1. 确认号填客户端序列号+1(Ack=10087)
  2. 自己也生成随机序列号(比如Seq=2024)

这时候服务器进入SYN_RCVD状态,内心OS:“小样儿,我回应了你可别装死啊!”

1.3 第三回合:终极确认

客户端收到SYN-ACK后,必须回一个ACK=1的包(Ack=2025)。到这里连接才正式建立,双方进入ESTABLISHED状态。

灵魂拷问时刻:为什么非要三次?两次不行吗?
举个栗子🌰:假设网络延迟导致旧SYN包到达,服务器响应后如果只有两次握手,客户端根本不会理会这个"过期的约定",但服务器却傻等资源…三次握手完美解决这种"单相思"问题!

二、连接断开:四次挥手比分手还纠结

断开连接可比建立复杂多了(毕竟分手总是痛苦的)。假设现在客户端主动关闭:

2.1 第一挥:FIN温柔告别

客户端发送FIN=1的包(假设Seq=5000),进入FIN_WAIT_1状态。这相当于说:“我要走了,但还能收你的消息哦~”

2.2 第二挥:ACK确认收到

服务器回个ACK=1(Ack=5001),进入CLOSE_WAIT状态。此时客户端到服务器的通道关闭,但反向通道还开着!

这里有个大坑🕳️:CLOSE_WAIT状态堆积会导致端口占用,常见于服务器没正确调用close()的情况(多少人在这里栽过跟头?)

2.3 第三挥:服务器的FIN暴击

当服务器也准备好关闭时,发送自己的FIN=1包(假设Seq=8000),进入LAST_ACK状态。这波操作相当于:“好的,我也要撤了!”

2.4 第四挥:最后的绅士礼仪

客户端回ACK=1(Ack=8001),进入TIME_WAIT状态。注意这个状态要维持2MSL(最长报文寿命的两倍)!

为什么需要TIME_WAIT?三大理由:

  1. 确保最后一个ACK能到达
  2. 让旧连接的报文在网络中消失
  3. 防止出现"鬼影连接"(听过端口复用的灵异事件吗?)

三、实战踩坑记录

3.1 生产事故:TIME_WAIT过多怎么办?

某次大促时监控突然报警:80端口耗尽!查原因发现短连接产生大量TIME_WAIT。解决方案:

# 调整内核参数
echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse
echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle

(不过要注意NAT环境下的副作用!)

3.2 调试奇遇:半关闭状态

用Python写了个简易代理:

import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.shutdown(socket.SHUT_WR)  # 只关写通道

结果对方服务器一直不返回数据…原来调用shutdown()会触发FIN发送,但recv()还能继续收数据!

四、高频灵魂拷问

Q:握手阶段能传数据吗?
A:第三次握手时可以携带数据(但SYN包本身不能带数据!)

Q:为什么服务端SYN和ACK要合并发送?
A:TCP协议允许将多个标志位同时置1,这是协议栈的优化操作

Q:出现大量SYN_RCVD状态怎么办?
A:八成是遭遇SYN Flood攻击了!赶紧上syncookies:

sysctl -w net.ipv4.tcp_syncookies=1

五、协议栈的隐藏关卡

你以为四次挥手就完了?在某些情况下:

  1. 同时关闭(双方同时发FIN)会进入CLOSING状态
  2. RST复位报文可以直接中断连接(相当于"滚!"的粗暴分手)
  3. Keep-Alive机制会让看似断开的连接"死灰复燃"

六、写在最后

看完这些是不是觉得TCP/IP设计者都是处女座?(笑)最后送大家一个调试锦囊:tcpdump抓包大法好! 下次遇到连接问题,直接:

tcpdump -i any tcp port 80 -nn -v

亲眼看看握手挥手的每个细节,比任何理论都管用!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值