协议值TCP

TCP 三次握手 & 四次挥手


一、TCP 三次握手(建立连接)

核心目的

确保双方收发能力都正常,同步双方初始序列号(ISN),建立可靠的 TCP 连接(为后续数据传输做准备)。

核心标识说明

  • SYN:同步序列号,用于发起连接、同步初始序列号

  • ACK:确认应答,用于确认收到对方的数据

  • ISN:随机初始序列号(每端独立生成,避免历史数据干扰)

流程图(mermaid格式,Markdown可直接渲染)

暂时无法在豆包文档外展示此内容

详细步骤

  1. 第一次握手(客户端 → 服务端):客户端主动发起连接,发送 SYN=1,携带自己的初始序列号 seq=x;客户端状态变为 SYN_SENT(等待服务端响应)。

  2. 第二次握手(服务端 → 客户端):服务端收到 SYN 后,确认客户端能发,同时向客户端发起同步(SYN=1),携带自己的初始序列号 seq=y;并回复 ACK=1,确认号 ack=x+1(表示"我收到了你发送的 x 及之前的所有数据");服务端状态变为 SYN_RCVD。

  3. 第三次握手(客户端 → 服务端):客户端收到服务端的 SYN+ACK 后,确认服务端能收能发,回复 ACK=1,确认号 ack=y+1;客户端状态变为 ESTABLISHED,服务端收到 ACK 后也变为 ESTABLISHED,连接正式建立。


二、TCP 四次挥手(断开连接)

核心目的

TCP 是双向通信协议,双方需独立关闭各自的发送通道,确保双方所有数据都已传输完成,再彻底断开连接(避免数据丢失)。

核心标识说明

  • FIN:结束标志,用于发起关闭连接请求(表示"我没有数据要发送了")

  • ACK:确认应答,与三次握手一致,用于确认收到 FIN 或数据

流程图(mermaid格式,Markdown可直接渲染)

暂时无法在豆包文档外展示此内容

详细步骤

  1. 第一次挥手(客户端 → 服务端):客户端无更多数据要发送,发送 FIN=1,携带当前序列号 seq=u;客户端状态变为FIN_WAIT_1(等待服务端确认)。

  2. 第二次挥手(服务端 → 客户端):服务端收到 FIN 后,回复 ACK=1,确认号 ack=u+1;此时服务端仍可向客户端发送未传完的数据,客户端状态变为 FIN_WAIT_2(等待服务端发起关闭)。

  3. 第三次挥手(服务端 → 客户端):服务端发送完所有剩余数据后,发送 FIN=1,携带当前序列号 seq=v;服务端状态变为 LAST_ACK(等待客户端确认)。

  4. 第四次挥手(客户端 → 服务端):客户端收到 FIN 后,回复 ACK=1,确认号 ack=v+1;客户端状态变为 TIME_WAIT(等待 2MSL 后彻底关闭,防止服务端没收到 ACK 重发 FIN),服务端收到 ACK 后直接变为 CLOSED。


三、高频场景面试题(含解析,适配面试问答)

以下是面试中最常考的 8 道场景题,解析直击考点,避免冗余,直接记核心即可。

★ 三次握手相关面试题

  1. 为什么 TCP 建立连接需要三次握手,而不是两次?

核心解析:核心是「确认双方收发能力都正常」,避免"失效连接请求"导致服务端资源浪费。

假设两次握手:客户端发送的 SYN(连接请求)因网络延迟,很久后才到达服务端,服务端以为是新请求,回复 SYN+ACK 后就建立连接、占用资源,但客户端早已超时关闭,服务端会一直等待客户端数据,造成资源泄漏。

三次握手的第三次,客户端会确认服务端的 SYN+ACK,只有双方都确认"对方能收能发",才建立连接,从根源避免上述问题。

  1. 三次握手过程中,客户端/服务端的状态变化是什么?

核心解析(记简写即可):

  • 客户端:CLOSED → SYN_SENT → ESTABLISHED

  • 服务端:CLOSED → LISTEN → SYN_RCVD → ESTABLISHED

  1. 三次握手时,SYN 为什么不能携带数据?

核心解析:此时连接尚未建立,服务端还未确认客户端的收发能力,若 SYN 携带数据,可能导致数据丢失(服务端未准备好接收);且 SYN 是"连接请求",核心目的是同步序列号,不负责数据传输,设计上就不允许携带数据。

  1. 面试场景题:如果三次握手的第三次 ACK 丢失,会发生什么?

核心解析:服务端会超时重发 SYN+ACK(默认重发 5 次,每次超时时间翻倍),直到收到客户端的 ACK;若一直未收到,服务端会释放连接,客户端则会在 SYN_SENT 状态超时后,关闭连接。

★ 四次挥手相关面试题

  1. 为什么 TCP 断开连接需要四次挥手,而不是三次?

核心解析:TCP 是双向通信,双方的发送通道需要独立关闭。

服务端收到客户端的 FIN(第一次挥手)后,可能还有未传输完的数据,不能立即发送 FIN(无法同时确认关闭请求 + 发起关闭),只能先回复 ACK(第二次挥手),等数据发完后,再发送 FIN(第三次挥手),最后客户端确认(第四次挥手),因此需要四次。

  1. 什么是 TIME_WAIT 状态?为什么需要等待 2MSL?

核心解析:

  • TIME_WAIT 是客户端第四次挥手后进入的状态,持续时间为 2MSL(MSL:最大报文段生存时间,默认 1 分钟)。

  • 目的 1:确保服务端能收到客户端的 ACK(若服务端没收到,会重发 FIN,客户端在 TIME_WAIT 期间能再次回复 ACK)。

  • 目的 2:等待网络中所有失效的报文段消失,避免新连接复用端口时,收到历史报文段干扰。

  1. 面试场景题:服务端出现大量 TIME_WAIT 状态,会有什么问题?怎么解决?

核心解析:

  • 问题:TIME_WAIT 会占用端口和系统资源,大量出现会导致端口耗尽,新连接无法建立。

  • 解决方案(高频考点):

  • 调整内核参数:net.ipv4.tcp_tw_reuse(允许复用 TIME_WAIT 端口)、net.ipv4.tcp_tw_recycle(快速回收 TIME_WAIT 连接)。

  • 缩短 TIME_WAIT 时长:调整 net.ipv4.tcp_fin_timeout(默认 60s,可适当缩短)。

  • 采用长连接(keep-alive),减少频繁建立/断开连接。

  1. 为什么服务端断开连接后是直接 CLOSED,而客户端要进入 TIME_WAIT?

核心解析:客户端是主动发起关闭的一方,需要负责确认服务端的 FIN 已被收到;服务端是被动关闭的一方,收到客户端的 ACK 后,确认所有数据已传输完成,无需等待,可直接关闭。


四、记忆口诀(面试快速回忆)

  • 三次握手:你能发 → 我能收发 → 你能收(同步序列号,确认双方能力)

  • 四次挥手:我发完了 → 收到 → 我也发完了 → 收到(双向关闭,确保数据传完)

相关推荐
AI_Claude_code2 小时前
网络基础回顾:DNS、IP封锁与HTTP/S协议关键点
网络·爬虫·python·tcp/ip·http·爬山算法·安全架构
赖134小0747姐2935电2 小时前
罗德与施瓦茨ZN-Z135经济型网络分析仪校准套件26.5G
网络·功能测试·科技·5g
初願致夕霞2 小时前
Linux_线程
linux·运维·服务器·c++
CDN3602 小时前
高防服务器端口被占用 / 不通?端口映射与协议配置解决
运维·服务器
不吃鱼的猫7482 小时前
【音视频流媒体进阶:从网络到 WebRTC】第01篇-Socket 编程基础:TCP 与 UDP 的选择
网络·音视频·webrtc
“愿你如星辰如月”2 小时前
从零构建高性能 Reactor 服务器:
linux·服务器·c++·websocket·tcp/ip
腾讯蓝鲸智云2 小时前
提升研发效能:DevOps平台高效权限配置与同步方案
运维·服务器·人工智能·云计算·devops
努力努力再努力wz2 小时前
【C++高阶系列】外存查找的极致艺术:数据库偏爱的B+树底层架构剖析与C++完整实现!(附B+树实现的源码)
linux·运维·服务器·数据结构·数据库·c++·b树
财迅通Ai2 小时前
SuperX完成日本全球供应中心首批高性能AI服务器交付,全球战略迈出关键一步
运维·服务器·人工智能·superx·中恒电气