协议值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 后,确认所有数据已传输完成,无需等待,可直接关闭。


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

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

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

相关推荐
笨鸟先飞,勤能补拙1 小时前
Web 服务器与计算机网络全景原理
运维·服务器·前端·网络·人工智能·计算机网络·web安全
KindSuper_liu1 小时前
Unity 游戏网络基础:从 TCP、UDP 到 HTTP、TLS 与 Best HTTP
网络·游戏·unity
caimouse1 小时前
ReactOS 图形系统分析(3):显示驱动 DDI framebuf.dll
linux·运维·网络
M158227690551 小时前
四通道 Profinet 转 Modbus RTU 网关 SG-PN-Modbus_4 全场景落地详解
网络·工控布线
佳児素花痴╮2 小时前
网络问题与基础理论
运维·服务器·网络
Oflycomm2 小时前
IPC网络摄像机与安防监控:Wi-Fi 6模组、AOV低功耗与边缘AI的产业落地
网络·人工智能·安防监控·wifi6·ipc网络摄像机
0x532 小时前
Java网络编程(四)
java·网络
highreport2 小时前
HighReport报表工具定时调度和邮件定时发送
运维·服务器·数据库
TonyLee0172 小时前
Claude Code + DeepSeek:服务器安装与使用笔记
linux·服务器·deepseek·claude code
St_rive2 小时前
Pytest skip&&skipif跳过⽤例
运维·服务器·pytest