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


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

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

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

相关推荐
道清茗11 分钟前
【RH294知识点汇总】第 9 章 《 自动执行 Linux 管理任务 》常见问题
linux·运维·服务器
北方的流星39 分钟前
华三路由器NAT配置
运维·网络·华三
数据法师2 小时前
开源情报收集工具GhostTrack深度测评:IP、手机号、用户名的合规信息查询方案
网络·网络协议·tcp/ip
丑八怪大丑3 小时前
Java网络编程
linux·服务器·网络
想成为优秀工程师的爸爸3 小时前
第三十篇技术笔记:郭大侠学UDS - 人有生老三千疾,望闻问切良方医
网络·笔记·网络协议·tcp/ip·信息与通信
橙子也要努力变强3 小时前
信号捕捉底层机制-机理篇2
linux·服务器·c++
数智工坊4 小时前
【SAM-DETR论文阅读】:基于语义对齐匹配的DETR极速收敛检测框架
网络·论文阅读·人工智能·深度学习·transformer
CQU_JIAKE4 小时前
4.28~4.30【Q】
linux·运维·服务器
先知后行。4 小时前
Linux 设备模型和platform平台
linux·运维·服务器
Data_Journal5 小时前
如何使用cURL更改User Agent
大数据·服务器·前端·javascript·数据库