TCP三次握手四次挥手:程序员必会的网络基本功(附面试题解析)

一、当你在刷抖音时,后台发生了什么?

大家天天都在用手机上网(别装了,你现在就在看这篇文章对吧?),但有没有想过当你点击视频的瞬间,手机和服务器之间到底怎么建立连接的?这就是我们今天要聊的TCP三次握手的神奇之处!

举个现实例子:你和女神约咖啡厅见面:

  1. 你:“到星巴克了吗?”(SYN)
  2. 女神:“到了,你呢?”(SYN-ACK)
  3. 你:“我也到了!”(ACK)

这个对话过程是不是很像TCP连接建立?没有第三次确认的话,女神可能还在傻等(这就是为什么必须是三次握手的关键)!

二、三次握手拆解(看我这波操作)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(此处应有灵魂手绘示意图)

1. 第一次握手:SYN攻击的根源

客户端发送SYN包(seq=x),这时候服务器端必须准备好两样东西:

  • 接收缓冲区
  • 发送缓冲区
  • 半连接队列(划重点!面试常考)

2. 第二次握手:服务器的双倍谨慎

服务器返回SYN-ACK包(seq=y, ack=x+1),这里有两个关键数值:

  • 自己的初始序列号y
  • 对客户端序列号x的确认

(这时候如果客户端掉线,服务器会重试5次,每次间隔时间翻倍,总耗时63秒!)

3. 第三次握手:最后的确认

客户端发送ACK包(ack=y+1),此时服务器才会:

  • 把连接从半连接队列移到全连接队列
  • 应用程序调用accept()读取连接

三、四次挥手:分手也要体面

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

分手步骤比建立连接多一步,为什么?因为TCP连接是全双工的,必须双方都确认关闭:

经典分手四部曲:

  1. 客户端:“我要走了”(FIN)
  2. 服务器:“知道了”(ACK)
  3. 服务器:“我也要走了”(FIN)
  4. 客户端:“拜拜”(ACK)

必须注意的TIME_WAIT状态!!!

客户端在发送最后ACK后会进入TIME_WAIT状态,持续2MSL(Maximum Segment Lifetime)时间,这是为了:

  1. 确保最后一个ACK能到达
  2. 让旧连接的包在网络中消失(防止端口复用导致数据混乱)

(这个状态会占用端口号,高并发服务器要特别注意!)

四、面试官最爱问的5大坑题

Q1:为什么是三次握手不是两次?

如果只有两次握手,服务器无法确认客户端是否收到自己的SYN-ACK,可能导致:

  • 服务器资源浪费(维护无效连接)
  • 历史连接干扰(旧SYN包导致新连接混乱)

Q2:四次挥手能变成三次吗?

可以!当服务器收到FIN后,如果已经没有数据要发送,会把FIN和ACK合并发送,这就是"延迟确认"机制(但本质上还是四次的过程)

Q3:CLOSE_WAIT状态过多怎么办?

这是典型的应用层bug!说明服务器没有正确调用close(),常见于:

  • 忘记关闭文件描述符
  • 代码异常未执行关闭逻辑
  • 连接泄露

Q4:SYN Flood攻击原理?

攻击者疯狂发送第一次握手包但不完成后续步骤,耗尽服务器的半连接队列。防御方案:

  • 开启tcp_syncookies
  • 调整半连接队列长度
  • 减少SYN+ACK重试次数

Q5:TIME_WAIT状态有什么危害?

  • 占用端口资源(默认可用端口约28000个)
  • 可能导致新连接建立失败

解决方案:

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

五、真实开发中的血泪教训

去年我们线上服务突然出现大量连接超时,排查后发现是因为Nginx的keepalive_timeout设置过长,导致大量连接堆积在TIME_WAIT状态。调整策略后:

  1. 将超时时间从300s改为60s
  2. 开启tcp_tw_reuse
  3. 增加本地端口范围

立即解决了问题!这个案例告诉我们:光懂理论不够,必须结合系统调优才能真正解决问题。

六、抓包实战分析(Wireshark演示)

用Wireshark抓取一个HTTP请求,你会看到:

  • 前三个包是三次握手(SYN->SYN-ACK->ACK)
  • 中间是HTTP数据交互
  • 最后四个包是四次挥手

重点关注Sequence Number和ACK Number的变化规律,这是理解TCP可靠传输的关键!

七、总结与思考

最后给大家留个思考题:如果网络延迟非常大(比如卫星通信),三次握手会有什么问题?该如何优化?(提示:TCP快速打开机制)

理解三次握手和四次挥手,不仅是面试需要,更是我们处理网络问题的基础。下次遇到Connection timeout之类的报错,希望你能快速定位到是握手阶段还是挥手阶段的问题!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值