☰
TCP 协议面试灵魂 12 问
2026/10/9 7:59:48 网站建设 项目流程

摘要:TCP 是后端、网络、基础架构岗位面试中几乎必考的协议。本文从「TCP 与 UDP 的区别」讲起,依次拆解三次握手、四次挥手、TIME_WAIT、可靠传输、滑动窗口、流量控制、拥塞控制、粘包拆包、KeepAlive、连接状态异常排查以及 SYN Flood 等 12 个高频灵魂问题。


1. 讲一讲 TCP 和 UDP 的区别

1.1 核心区别一览

对比维度TCPUDP
面向连接三次握手建立连接无连接,直接发送
可靠性不丢、不重、不乱序尽力而为,可能丢包乱序
传输形式面向字节流面向报文
头部开销20~60 字节固定 8 字节
通信模式一对一一对一、一对多、多对多
拥塞控制有流量控制和拥塞控制无
典型应用HTTP、HTTPS、FTP、数据库DNS、直播、游戏、NTP

1.2 面向连接 vs 无连接

TCP 通信前要完成三次握手,双方维护连接状态(序列号、窗口大小等)。UDP 直接发数据报,不关心对方是否收到,首包延迟低。

1.3 面向字节流 vs 面向报文

这是理解粘包、拆包的关键。TCP 把数据看作连续字节流,不保留消息边界;UDP 一次 send 就是一个完整数据报,天然保留边界。

1.4 可靠性机制的代价

TCP 的确认、重传、窗口、拥塞控制带来更高延迟和开销;UDP 省去这些机制,换取低延迟,代价是数据可能丢、乱、重复。

1.5 面试标准答法与追问

常见追问:

  • 为什么实时音视频用 UDP?音视频要求实时性,TCP 超时重传会导致阻塞卡顿;音视频可容忍少量丢包,通过编解码补偿。

  • HTTP/3 为什么用 UDP?HTTP/2 在 TCP 上存在队头阻塞,QUIC 基于 UDP 在用户态重新实现可靠传输、加密和流控。


2. TCP 三次握手的详细过程

2.1 三次握手报文详解

步骤报文序列号状态
第一次SYNseq=x客户端 → SYN_SENT
第二次SYN+ACKseq=y, ack=x+1服务端 → SYN_RCVD
第三次ACKack=y+1双方 → ESTABLISHED

2.2 状态机变迁

text

客户端 服务端 | ---------- SYN, seq=x ----------> | 客户端 -> SYN_SENT | | 服务端 -> SYN_RCVD | <------ SYN+ACK, seq=y, ack=x+1 - | | 客户端 -> ESTABLISHED | | ---------- ACK, ack=y+1 --------> | 服务端 -> ESTABLISHED

2.3 初始序列号为什么随机

防止攻击者猜测序列号伪造 TCP 报文(如 RST 攻击)。现代系统结合递增计时器和随机数生成 ISN。

2.4 抓包验证

bash

sudo tcpdump -nn -S host example.com and tcp port 80

2.5 面试答法与常见追问

高频追问:第三次握手的 ACK 丢失怎么办?服务端停留在 SYN_RCVD,超时后重发 SYN+ACK;客户端再次回 ACK。只要网络恢复,连接最终仍能建立。


3. 为什么是三次握手,两次或四次不行吗

3.1 三次握手的本质目标

握手要达成三个确认:客户端确认收发能力、服务端确认收发能力、双方同步初始序列号。

3.2 两次握手为什么不行

历史连接请求问题:滞留的旧 SYN 突然到达服务端,若只有两次握手,服务端会误建连接并浪费资源。三次握手让服务端在收到最终 ACK 后才建立连接。

3.3 四次握手为什么没必要

服务端对 SYN 的确认和自身 SYN 的发起可合并为 SYN+ACK,节省一次往返。

3.4 面试标准答法

三次握手本质是:在不可靠信道上让双方确认收发能力并同步初始序列号。两次握手无法解决历史 SYN 干扰,四次握手多一次不必要往返,三次是正确性与效率的最优平衡。


4. TCP 四次挥手的详细过程

4.1 四次挥手步骤

步骤报文状态变化
第一次客户端发 FIN客户端 → FIN_WAIT_1
第二次服务端回 ACK服务端 → CLOSE_WAIT
第三次服务端发 FIN服务端 → LAST_ACK
第四次客户端回 ACK客户端 → TIME_WAIT,服务端 → CLOSED

4.2 状态变化

text

客户端 服务端 ESTABLISHED ESTABLISHED | --- FIN, seq=u -------------------> | | FIN_WAIT_1 | | <--- ACK, ack=u+1 --------------- | | FIN_WAIT_2 | CLOSE_WAIT | <--- FIN, seq=w, ack=u+1 --------- | | TIME_WAIT | LAST_ACK | --- ACK, ack=w+1 -----------------> | | 等待 2MSL | CLOSED | CLOSED |

4.3 为什么挥手需要四次

TCP 支持半关闭:收到 FIN 只代表对方不再发送数据,但本端可能还有数据要发。因此 ACK 和 FIN 需分开发送。

4.4 大量 CLOSE_WAIT 和 LAST_ACK 的含义

  • 大量 CLOSE_WAIT:服务端收到了 FIN,但应用没有及时 close socket,通常是代码缺陷。

  • 大量 LAST_ACK:服务端已发出 FIN 但没收到 ACK,可能网络丢包、客户端崩溃或防火墙拦截。


5. TIME_WAIT 状态与 2MSL

5.1 为什么需要 TIME_WAIT

  1. 确保最后一个 ACK 可靠到达:ACK 丢失时可重发。

  2. 防止旧连接延迟报文影响新连接:等待 2MSL 让旧报文在网络中自然消亡。

5.2 为什么是 2MSL

MSL 是报文最大生存时间。等待 2MSL 保证最后一个 ACK 和可能重发的 FIN 都能处理完,同时旧连接的双向报文全部失效。

5.3 TIME_WAIT 过多怎么办

  • 调整内核参数:tcp_tw_reuse、tcp_fin_timeout

  • 优化关闭方式:让客户端主动关闭,把 TIME_WAIT 集中到客户端

  • 使用连接复用:HTTP Keep-Alive、连接池

  • 必要时用 SO_LINGER:但要谨慎,强制关闭可能发 RST

5.4 面试标准答法

TIME_WAIT 出现在主动关闭方,持续 2MSL。作用有二:保证最后 ACK 能重发,让旧连接报文失效。优化可通过内核参数、调整关闭时机和连接复用。


6. TCP 如何保证可靠传输

6.1 确认应答与序列号

每个字节都编序列号,接收方返回 ACK 表示下一个期望收到的字节序号。

6.2 超时重传

发送方每发一个报文启动重传定时器,超时 RTO 未收到确认则重发。RTO 通过 RTT 动态计算。

6.3 快速重传

接收方收到乱序报文时立即重发对最后一个连续字节的 ACK。发送方连续收到 3 个相同 ACK 就立即重传,不等超时。

6.4 面试标准答法

TCP 可靠传输依赖:序列号和确认应答确认数据有序到达;超时重传兜底;快速重传基于 3 个重复 ACK 提前判断丢包。配合滑动窗口提升吞吐。


7. TCP 滑动窗口

7.1 为什么需要滑动窗口

停止等待协议每次只发一个报文,带宽利用率极低。滑动窗口允许发送方在未收到确认前连续发送多个报文。

7.2 滑动窗口的工作过程

发送窗口分三部分:已发送未确认、允许发送但未发送、不允许发送。收到新 ACK 后窗口右移,新数据纳入窗口。

7.3 面试标准答法

滑动窗口本质是用窗口批量管理未确认数据。窗口大小由接收方通告的接收窗口和发送方维护的拥塞窗口共同决定,取两者较小值。通过窗口滑动,TCP 在可靠确认和高效传输之间取得平衡。


8. TCP 流量控制

8.1 接收窗口与 rwnd

TCP 头部 Window 字段通告接收方可用缓冲区大小(rwnd)。发送方未确认数据总量不能超过 rwnd。

8.2 零窗口与窗口更新

接收方缓冲满时通告rwnd=0,发送方停止发送。接收方恢复后主动发送窗口更新报文。发送方用坚持定时器定期探测零窗口,避免窗口更新报文丢失导致双方互相等待。

8.3 面试标准答法

流量控制防止发送方压垮接收方,通过报文头部的 Window 字段通告 rwnd。流量控制调节的是发送方与接收方之间的速率,和关注网络状况的拥塞控制不同。


9. TCP 拥塞控制

9.1 慢启动与拥塞窗口

cwnd 初始较小,每收到一个 ACK 翻倍增长(指数上升),这叫慢启动。

9.2 拥塞避免

cwnd 达到 ssthresh 后,每经过一个 RTT 加 1,从指数增长变为线性增长。

9.3 快重传与快恢复

  • 超时重传:ssthresh 减半,cwnd 重置为 1,重新慢启动

  • 快重传(3 个重复 ACK):ssthresh 减半,cwnd 设为减半后的值,进入快恢复

9.4 面试标准答法

拥塞控制是发送方适应网络状况的机制,核心算法包括慢启动、拥塞避免、快重传、快恢复。流量控制看接收方,拥塞控制看网络,两者共同决定实际发送窗口。


10. TCP 粘包与拆包

10.1 问题本质

  • 粘包:多条小消息被合并到一个报文段,接收方一次读到多条

  • 拆包:大消息被拆成多个报文段,接收方一次读不完

10.2 产生原因

  • 粘包:Nagle 算法攒数据;接收方读取不及时

  • 拆包:消息超过 MSS 或发送缓冲区大小

10.3 解决方案

方案说明
定长消息每条消息固定长度,不足补齐
分隔符消息末尾加特殊分隔符
长度字段消息头写入消息体长度
自定义协议消息头含魔数、版本、长度、类型

10.4 面试标准答法

粘包和拆包的本质是 TCP 面向字节流、不保留消息边界。解决方案核心思想都是让应用层自己定义消息边界。


11. TCP KeepAlive 机制

11.1 KeepAlive 是什么

TCP 协议层自带的保活探测机制。连接空闲达到一定时间后,内核周期性发送探测报文,判断连接是否可用。

11.2 关键参数(Linux)

参数作用默认值
tcp_keepalive_time空闲多久后开始探测7200 秒
tcp_keepalive_intvl探测间隔75 秒
tcp_keepalive_probes失败多少次判定失效9 次

11.3 应用层心跳与 TCP KeepAlive 的区别

TCP KeepAlive 是内核行为,只能判断连接是否存活,无法感知应用层是否正常,默认周期很长。业务中通常叠加应用层心跳,间隔更短,能快速发现连接和业务异常。

11.4 面试标准答法

TCP KeepAlive 是协议层保活机制,连接空闲一段时间后由内核周期性探测对端是否存活,主要解决半开连接问题。它不能判断应用是否正常,因此长连接场景通常叠加应用层心跳。


12. TCP 连接状态异常排查

12.1 常见异常状态

状态含义
大量 TIME_WAIT高并发短连接主动关闭,可优化内核参数和连接复用
大量 CLOSE_WAIT对端已发 FIN,本端应用没及时 close,通常是连接泄漏
大量 LAST_ACK本端发出 FIN 但未收到 ACK,可能网络丢包或对端崩溃
大量 SYN_RCVD半连接队列被打满,可能遭受 SYN Flood 或处理能力不足

12.2 排查思路

bash

ss -tan | awk '{print $1}' | sort | uniq -c | sort -rn

定位异常状态后,结合日志、代码和网络拓扑分析:

  • CLOSE_WAIT → 查应用是否忘记 close

  • TIME_WAIT → 看连接是否过于频繁地新建和关闭

  • SYN_RCVD → 检查防火墙、半连接队列大小和是否遭受攻击

12.3 面试标准答法

排查 TCP 连接异常,先通过ss或netstat查看各状态数量分布,再根据状态定位:TIME_WAIT 优化关闭方式和内核参数;CLOSE_WAIT 检查应用是否正确关闭 socket;LAST_ACK 关注网络丢包和对端状态;SYN_RCVD 考虑半连接队列和 SYN 攻击。核心是理解每种状态对应连接生命周期中的哪一步。


13. SYN Flood 攻击与防御

13.1 攻击原理

服务端收到 SYN 后分配半连接资源并回复 SYN+ACK,等待客户端最终 ACK。攻击者伪造大量源 IP 发送 SYN 但不回 ACK,导致半连接队列被占满,正常连接无法建立。

13.2 防御方式

方式说明
SYN Cookie收到 SYN 时不分配资源,根据源地址等计算 Cookie 放进 SYN+ACK;收到正确 Cookie 的 ACK 时才分配资源
缩短 SYN 超时让半连接尽快释放
增大半连接队列提高tcp_max_syn_backlog
SYN 网关/防火墙在前置设备上过滤
限制并发 SYN 速率使用iptables等限速

13.3 面试标准答法

SYN Flood 利用 TCP 三次握手的半连接机制,攻击者伪造源 IP 发送大量 SYN 却从不回 ACK,耗尽服务端半连接资源。防御核心是SYN Cookie,不预先分配资源,等最终 ACK 到来时才分配;辅以半连接队列调优、SYN 超时缩短和前置防护。


总结与速查表

主题核心要点
TCP vs UDP连接、可靠性、传输形式、头部大小、拥塞控制
三次握手SYN、SYN+ACK、ACK;状态 CLOSED→SYN_SENT→ESTABLISHED
为什么三次确认收发能力 + 同步 ISN + 防历史 SYN
四次挥手FIN、ACK、FIN、ACK;半关闭导致
TIME_WAIT2MSL;保证 ACK 可靠 + 旧报文消亡
可靠传输序列号 + 确认应答 + 超时重传 + 快速重传
滑动窗口批量管理未确认数据,取 rwnd 和 cwnd 较小值
流量控制通过 rwnd 调节发送速率,保护接收方
拥塞控制慢启动、拥塞避免、快重传、快恢复,保护网络
粘包拆包面向字节流不保留边界,用定长/分隔符/长度字段解决
KeepAlive内核探活;应用层心跳更灵活
状态排查TIME_WAIT、CLOSE_WAIT、LAST_ACK、SYN_RCVD
SYN Flood半连接耗尽;SYN Cookie + 队列调优防御

面试答题技巧:先讲原理,再讲取舍,最后补充生产实践。能说清楚「为什么这样设计」和「异常时怎么排查」,比单纯背状态名更有说服力。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询