三次握手四次挥手的那些坑:你以为懂了其实可能没全懂!

先来道送命题:三次握手到底握了个啥?

(敲黑板)TCP三次握手可不是简单的"你好-我好-大家好"的客套话!这个经典流程里每个报文都暗藏玄机:

  1. SYN=1, seq=x(客户端:兄弟在吗?我这有个随机数x)
  2. SYN=1, ACK=1, seq=y, ack=x+1(服务端:在的在的!我也有随机数y,确认收到你的x)
  3. ACK=1, seq=x+1, ack=y+1(客户端:收到你的y!咱们可以开搞了)

(灵魂拷问)为什么不能两次握手?举个栗子🌰:如果客户端第一次SYN在网络里卡了半小时,服务端收到过期请求直接建立连接,这时候客户端早就不认账了,服务端就成傻等的"望夫石"了!

四次挥手的隐藏关卡

你以为四次挥手就是简单的拜拜流程?大错特错!这个分手过程可比谈恋爱复杂多了:

客户端:FIN(我想分手了)
服务端:ACK(收到分手请求)
服务端:FIN(我也想分了)
客户端:ACK(好的分吧)

(重点来了)中间等待的TIME_WAIT状态才是真正的魔鬼!这个2MSL的等待期(一般1-4分钟)可不是闲着没事干:

  1. 确保最后一个ACK能重传
  2. 让网络中残留的旧报文彻底消失
  3. 防止出现"鬼影连接"(旧连接的报文误入新连接)

但现实中很多程序员直接setsockopt(SO_REUSEADDR)跳过了这个阶段,结果上线就翻车(别问我怎么知道的)!

面试必杀题精讲

Q1:为什么建立连接三次,关闭要四次?

(拍大腿)因为TCP是全双工的!关闭时需要双方各自确认关闭。当客户端发FIN时,服务端可能还有数据要传,所以先ACK确认关闭请求,等数据传完再发自己的FIN。

Q2:CLOSE_WAIT太多怎么办?

(血泪教训)这通常是被动关闭方(服务端)没有正确close socket导致的。用netstat一看满屏CLOSE_WAIT,赶紧检查代码是不是漏了关闭操作,或者线程卡在某个IO操作了。

Q3:SYN洪水攻击原理?

攻击者疯狂发SYN包但不完成握手,把服务端的半连接队列塞满。防御方案可以试试:

  • 启用syncookies
  • 调整net.ipv4.tcp_max_syn_backlog
  • 限制单个IP的SYN速率

实战抓包分析

用Wireshark抓个访问百度的过程(命令行curl www.baidu.com),你会看到这样的名场面:

No.  Time        Source           Destination      Protocol Info
  1 0.000000    192.168.1.100    14.215.177.39    TCP      59842 → 80 [SYN] Seq=0
  2 0.023402    14.215.177.39    192.168.1.100    TCP      80 → 59842 [SYN, ACK] Seq=0 Ack=1
  3 0.023521    192.168.1.100    14.215.177.39    TCP      59842 → 80 [ACK] Seq=1 Ack=1
  4 0.023687    192.168.1.100    14.215.177.39    HTTP     GET / HTTP/1.1 

(注意看)第三次握手的ACK包居然只有54字节!这个ACK包可以携带应用数据,这就是著名的TCP延迟确认机制(RFC1122)。很多性能调优的关键就在这些细节里!

高手才知道的骚操作

  • 半关闭shutdown():像HTTP/1.1的keep-alive就是靠这个实现的,可以单独关闭写通道
  • TCP_DEFER_ACCEPT:等真的有数据来了才唤醒应用进程,专治各种SYN洪水
  • TCP_FASTOPEN:在SYN包就带数据,减少一次RTT时间(但需要客户端和服务端都支持)
  • SO_LINGER:控制close()行为,强行发送RST包跳过TIME_WAIT(慎用!)

终极面试大杀器

被问到"如果第二次握手丢包会怎样?"时,请淡定回答:

  • 客户端收不到SYN-ACK会超时重传SYN(默认重试5次,间隔1s,2s,4s,8s,16s)
  • 服务端有半连接队列维护这些未完成的握手
  • 如果服务端重传SYN-ACK,客户端收到后可能同时建立多个连接(但内核会正确处理)

最后送大家一个调优口诀:
三次握手防乱序,四次挥手保数据;
TIME_WAIT虽讨厌,安全保障不能弃;
内核参数别瞎改,线上故障难预期!

(看完这篇还搞不懂三次握手四次挥手?建议直接打印本文贴在工位上!)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值