TCP 与 UDP:从核心区别到面试必问的可靠性机制
TCP 与 UDP:从核心区别到面试必问的可靠性机制
一、开篇:为什么面试总爱问 TCP/UDP?
网络传输层位于 OSI 七层模型或 TCP/IP 四层模型的中间,承上启下。面试官喜欢问 TCP/UDP,是因为它们能考察一个人对网络通信本质的理解:是否可靠、如何控制速度、怎样建立/断开连接。
一句话定义:
- TCP:面向连接的、可靠的、基于字节流的传输协议
- UDP:无连接的、不可靠的、基于数据报的传输协议
生活类比:
- TCP 像打电话:先拨号、等待对方接通、确认能听到、再开始说话
- UDP 像寄快递或发广播:只管发出,不管对方是否收到,也不保证顺序
二、TCP 核心机制详解
1. 三次握手与四次挥手
三次握手过程(线性时间 + 大白话)
- 客户端 → 服务端:我想跟你说话,这是我的序列号(SYN),客户端进入
SYN-SENT - 服务端 → 客户端:收到,我也想说,这是我的序列号(SYN-ACK),服务端进入
SYN-RCVD - 客户端 → 服务端:收到你的确认,开始说话(ACK),双方进入
ESTABLISHED
为什么是三次,而不是两次或四次?
- 一次/两次无法确认双方都能收发
- 四次浪费了一次往返
- 三次刚好以最小次数完成:双向可达确认 + 初始序列号同步,同时还能防止历史失效的连接请求突然到达
四次挥手过程(线性时间 + 大白话)
- 主动关闭方(A):我说完了,不会再发数据(FIN),进入
FIN-WAIT-1 - 被动关闭方(B):知道了,但我可能还有话要说(ACK),进入
CLOSE-WAIT;A 进入FIN-WAIT-2 - B:我也说完了,挂吧(FIN),进入
LAST-ACK - A:好的,确认关闭(最后一个 ACK),进入
TIME-WAIT,等待 2MSL 后彻底关闭
为什么是四次,而不是三次?
TCP 是全双工通信,每一方向必须单独关闭。第二次和第三次不能合并,因为 B 可能还有数据要发。
TIME_WAIT 的作用(2MSL)
- 确保最后一个 ACK 能到达对方(如果丢失,对方会重发 FIN)
- 让旧连接的所有残留报文从网络中消失,不影响新连接
2. 可靠性是如何实现的?
- 确认应答(ACK):每收到一个 TCP 包,必须回复 ACK
- 超时重传(RTO):发送后若超时未收到 ACK,则重传
- 序列号与去重:解决网络乱序和重复包问题
- 校验和:检测数据在传输中是否损坏
- 流量控制
- 拥塞控制
3. 流量控制
- 滑动窗口机制:接收方通过通告窗口大小,告诉发送方还能收多少数据,防止接收方被淹没
4. 拥塞控制(面试加分项)
TCP 不仅关心接收方能不能收,还关心网络堵不堵。
- 拥塞窗口(cwnd):发送方根据网络拥塞程度自己计算的控制窗口
- 接收窗口(rwnd):接收方通告的窗口
四大算法:慢启动 → 拥塞避免 → 快重传 → 快恢复
简单理解:先试探网速,遇到丢包就降速,逐步恢复。
三、UDP 核心机制详解
1. UDP 特点
- 无连接、无状态、不可靠
- 面向报文:不合并、不拆分应用层数据
- 头部仅8 字节(源端口、目的端口、长度、校验和)
2. 什么时候用 UDP?
- 实时性要求高:视频通话、直播、在线游戏
- 允许一定丢包:DNS 查询、SNMP、TFTP
- 广播/多播场景:DHCP、组播视频
3. 面试高阶追问:UDP 如何实现可靠性?
答案:应用层自己实现。
典型例子:
- QUIC 协议(HTTP/3 使用):基于 UDP,但提供类似 TCP 的可靠性、加密、多路复用
- RTP、KCP、UDT 等
四、TCP vs UDP 关键对比表
| 对比维度 | TCP | UDP |
|---|---|---|
| 连接性 | 面向连接 | 无连接 |
| 可靠性 | 确认、重传、排序 | 尽最大努力交付 |
| 速度 | 慢(握手、拥塞控制) | 快 |
| 头部大小 | 20–60 字节 | 8 字节 |
| 丢包处理 | 重传直到成功 | 直接丢弃 |
| 适用场景 | HTTP、SSH、FTP、SMTP | 音视频、DNS、游戏、SNMP |
五、真实场景选择指南
- 网页浏览 / 文件下载→ TCP(必须完整、有序)
- 视频直播 / 会议→ UDP(容忍花屏,不能卡顿)
- 游戏→ 混合:位置同步用 UDP,聊天/登录用 TCP
- DNS→ UDP(一个请求一个响应,超时则重试)
六、常见面试题盲区扫雷
1. UDP 包的最大长度是多少?
理论 64KB,实际受 MTU 限制通常小于 1500 字节,否则 IP 分片。
2. TCP 的 Keep-Alive 是心跳包吗?
是保活机制,但默认 2 小时才发一次,远不如应用层心跳实用。
3. SYN Flood 攻击是什么?
大量伪造 SYN 使服务器半连接队列耗尽。防攻击方案:SYN Cookie。
补充问答(三次握手 & 四次挥手)
关于三次握手
| 术语 | 含义 |
|---|---|
| SYN | 同步序列号,请求建立连接 |
| SYN-ACK | 服务端对 SYN 的确认,同时发起自己的 SYN |
| ACK | 确认应答 |
| SYN-SENT | 客户端已发 SYN |
| SYN-RCVD | 服务端已收 SYN 并回复 SYN-ACK |
| ESTABLISHED | 连接已建立 |
全双工 vs 其他通信方式:
- 单工:收音机(单向)
- 半双工:对讲机(轮流说)
- 全双工:电话、TCP(同时收发)
关于四次挥手
| 术语 | 含义 |
|---|---|
| FIN | 终止连接,表示不再发送数据 |
| 2MSL | 2 倍最大报文生存时间,TIME_WAIT 持续时长 |
最后一个 ACK:
四次挥手第 4 步中,主动关闭方回复的确认。若丢失,被动方会重发 FIN,因此主动方必须等待 2MSL。
写在最后
这篇博客不仅是面试笔记,更是一份可随时查阅的 TCP/UDP 知识地图。建议你边看边画图,把“三次握手、四次挥手、滑动窗口”亲手画一遍,面试时才能信手拈来。
本回答由 AI 生成,内容仅供参考,请仔细甄别。
三次握手、四次挥手的图画一下
以下是三次握手和四次挥手的时序图(文字版),你可以直接复制到博客中,或者据此画成手绘图。画图时建议用垂直方向代表时间从上到下,水平方向代表客户端和服务端。
一、TCP 三次握手时序图
客户端 服务端 | | | -------- SYN (seq=x) -------> | | | SYN-SENT | | | <---- SYN-ACK (seq=y, ack=x+1) | | | SYN-RCVD | | | ------- ACK (ack=y+1) -------> | | | | | ESTABLISHED | ESTABLISHED |每一步对应的状态变化
| 步骤 | 方向 | 报文 | 客户端状态 | 服务端状态 |
|---|---|---|---|---|
| 1 | 客户端 → 服务端 | SYN (seq=x) | SYN-SENT | LISTEN |
| 2 | 服务端 → 客户端 | SYN-ACK (seq=y, ack=x+1) | SYN-SENT → ESTABLISHED | SYN-RCVD |
| 3 | 客户端 → 服务端 | ACK (ack=y+1) | ESTABLISHED | SYN-RCVD → ESTABLISHED |
二、TCP 四次挥手时序图
主动关闭方(客户端) 被动关闭方(服务端) | | | --------- FIN (seq=u) -------> | | | CLOSE-WAIT | | | <-------- ACK (ack=u+1) ------- | | | | FIN-WAIT-2 | | | | <-------- FIN (seq=v) -------- | | | LAST-ACK | | | --------- ACK (ack=v+1) -------> | | | | TIME-WAIT (2MSL) | CLOSED | ↓ | | CLOSED |每一步对应的状态变化
| 步骤 | 方向 | 报文 | 主动方状态 | 被动方状态 |
|---|---|---|---|---|
| 1 | 主动方 → 被动方 | FIN | ESTABLISHED → FIN-WAIT-1 | ESTABLISHED |
| 2 | 被动方 → 主动方 | ACK | FIN-WAIT-1 → FIN-WAIT-2 | ESTABLISHED → CLOSE-WAIT |
| 3 | 被动方 → 主动方 | FIN | FIN-WAIT-2 → TIME-WAIT | CLOSE-WAIT → LAST-ACK |
| 4 | 主动方 → 被动方 | ACK | TIME-WAIT (等待2MSL后关闭) | LAST-ACK → CLOSED |
三、UDP 头部结构图
+-------------------------------+-------------------------------+ | 16 位源端口 | 16 位目的端口 | | (Source Port) | (Destination Port) | +-------------------------------+-------------------------------+ | 16 位长度 | 16 位校验和 | | (UDP Length) | (Checksum) | +-------------------------------+-------------------------------+ | | | 数据部分 (Data) | | (长度 = UDP长度 - 8 字节) | +-----------------------------------------------------------------+各字段含义表
| 字段 | 占用空间 | 含义 | 说明 |
|---|---|---|---|
| 源端口 | 16 位(2 字节) | 发送方的端口号 | 可选,不需要回复时可填 0 |
| 目的端口 | 16 位(2 字节) | 接收方的端口号 | 必填,用于交付到正确应用 |
| UDP 长度 | 16 位(2 字节) | UDP 报文总长度(头部 + 数据) | 最小为 8 字节(仅有头部) |
| 校验和 | 16 位(2 字节) | 检测数据是否损坏 | 可选在 IPv4,IPv6 下为必填 |
| 数据部分 | 可变 | 应用层载荷 | 例如 DNS 查询、视频流等 |
关键点:UDP 头部固定只有8 字节,比 TCP 的 20–60 字节轻量得多。
与 TCP 头部对比图(加分项)
TCP 头部(至少 20 字节) UDP 头部(8 字节) +------------------+ +------------------+ | 源端口 | 目的端口 | | 源端口 | 目的端口 | +------------------+ +------------------+ | 序列号 | | 长度 | 校验和 | +------------------+ +------------------+ | 确认号 | +------------------+ | 偏移 | 标志 | 窗口 | +------------------+ | 校验和 | 紧急指针 | +------------------+ | 选项(可选) | +------------------+希望这篇关于TCP 与 UDP的文章能够帮助到你。欢迎点赞、评论、收藏。
