
- [TCP / UDP 对比介绍](#TCP / UDP 对比介绍)
-
- [UDP 用户数据报协议(User Datagram Protocol)](#UDP 用户数据报协议(User Datagram Protocol))
- [TCP 传输控制协议(Transmission Control Protocol)](#TCP 传输控制协议(Transmission Control Protocol))
-
- 核心特点
- 关键机制
- TCP三次握手(建立连接)
- TCP四次挥手(断开连接)
- [TCP两大经典坑:粘包 & 拆包](#TCP两大经典坑:粘包 & 拆包)
- TCP优缺点
- 使用场景
- [TCP vs UDP 对比总表](#TCP vs UDP 对比总表)
TCP / UDP 对比介绍
传输层两大协议;IP负责把数据包送到目标机器,TCP/UDP负责机器上对应程序之间的数据交付。
UDP 用户数据报协议(User Datagram Protocol)
核心特点
- 无连接:通信前不需要握手,直接发数据包;不用维护连接状态。
- 不可靠 :不保证到达、不保证顺序、不保证不重复。
- 数据包可能丢包
- 数据包乱序到达(先发的后到)
- 数据包重复收到
- 面向数据报:UDP保留报文边界,一次send对应一个完整报文,接收必须一次读完;不会粘包。
- 头部很小,8字节,开销极低。
优点
- 延迟低,没有握手、重传、拥塞控制开销。
- 没有连接维护,可以一对多广播、组播。
缺点
- 可靠性全部需要应用层自己实现:序号、ACK确认、重传、去重、排序。
- 网络差环境丢包现象明显。
典型使用场景
- 直播、语音视频、实时游戏帧同步(帧同步底层大多UDP)、DNS查询。
游戏中UDP常见问题
- 丢包:关键消息直接没收到;
- 乱序:状态消息时序错乱;
- 重复包:同一消息收到多次,业务要做幂等;
所以很多游戏框架(ENet、KCP)都是在UDP之上实现可靠传输。
TCP 传输控制协议(Transmission Control Protocol)
核心特点
- 面向连接:通信前必须建立连接(三次握手);结束要四次挥手断开连接。
- 可靠传输 :保证数据送达、保证顺序、自动去重。
- 序列号 Sequence Number
- ACK确认应答,没收到ACK自动超时重传
- 面向字节流 :没有报文边界,是一串连续字节流 → 会发生粘包、拆包(面试高频)
- 自带拥塞控制、流量控制。
- TCP头部最少20字节,可变。
关键机制
-
序列号与ACK确认
每一个字节数据分配序号;接收方回复ACK告诉发送方"我收到几号之前的数据"。发送方超时没收到ACK,自动重传。
-
流量控制(滑动窗口)
接收方告诉发送方自己还能接收多少缓冲区,防止发送太快把接收缓冲区打满。
-
拥塞控制
网络链路拥堵时自动降低发送速率,避免网络进一步恶化;慢启动、拥塞避免、快重传、快恢复。
TCP三次握手(建立连接)
客户端C,服务端S
- C → S:SYN 同步报文,请求建立连接
- S → C:SYN+ACK,同意连接
- C → S:ACK,确认;连接建立,可以收发数据。
为什么要三次,不是两次?
防止旧的过期无效连接请求报文到达服务器,服务器错误建立无用连接浪费资源。
TCP四次挥手(断开连接)
TCP是全双工,双方可以独立关闭自己发送方向。
- C→S FIN:客户端关闭自己的发送通道(我不再发数据)
- S→C ACK:收到关闭请求
- S→C FIN:服务端也关闭自己发送通道
- C→S ACK:确认断开。
客户端会进入
TIME_WAIT状态,等待2MSLS;确保对方收到最后的ACK,防止残留数据包干扰下一次连接。
TCP两大经典坑:粘包 & 拆包
因为TCP是字节流,没有消息边界。
- 粘包:多次发送的小数据包,内核缓冲区合并,一次全部读到。send1+send2,recv一次拿到两段拼在一起。
- 拆包:一条大消息太大,底层拆分多个TCP片段,多次recv才能读完完整消息。
✅应用层解决方案(游戏网络必背)
- 长度前缀法(最常用) :每条消息 =【消息长度4字节】+【消息二进制内容】
接收端先读4字节得到消息体长度,再读取对应字节,切分出一条完整消息。 - 特殊分隔符(很少游戏用,文本协议如HTTP)
TCP优缺点
✅优点:内核提供可靠、有序,业务不用自己处理丢包乱序。
❌缺点:
- 握手、重传、拥塞控制带来额外延迟;网络抖动时重传会造成延迟突增;
- 粘包拆包必须业务层处理;
- 连接资源有限,每一条连接占用内核内存。
使用场景
HTTP/HTTPS、RPC、账号登录、道具交易、MMORPG状态同步(大部分状态同步走TCP)。
TCP vs UDP 对比总表
| 对比项 | TCP | UDP |
|---|---|---|
| 连接特性 | 面向连接(三次握手/四次挥手) | 无连接 |
| 可靠性 | 可靠:不丢包、有序、自动去重 | 不可靠:丢包、乱序、重复都可能发生 |
| 传输模式 | 字节流,粘包拆包 | 数据报,保留报文边界,无粘包 |
| 头部大小 | 最小20字节 | 8字节 |
| 流量/拥塞控制 | 内核自带滑动窗口、拥塞控制 | 无,完全应用层控制 |
| 延迟 | 较高,抖动网络延迟波动大 | 低延迟 |
| 广播组播 | 不支持 | 支持 |
| 适用场景 | 登录、交易、状态同步、HTTP | 语音、直播、帧同步游戏、DNS |
游戏网络选型(面试高频)
- 状态同步(MMO):大多TCP;关键指令可靠;对延迟容忍略高。
- 帧同步(MOBA/竞技) :底层UDP;追求低延迟;上层KCP/ENet实现部分可靠; 帧同步:输入指令用可靠;状态帧可以允许少量丢包。
补充:KCP不是协议,是基于UDP实现的可靠传输库,牺牲一部分带宽换取比TCP更低的延迟,游戏大量使用。
高频面试问答题
Q1:既然UDP不可靠,游戏帧同步为什么不用TCP?
TCP的重传机制是整体等待 ,如果某一段丢包,后面所有数据全部阻塞等待重传完成,会出现明显卡顿;
UDP上层自己实现可靠,可以做到选择性重传,只重传丢失的帧,后续帧可以继续处理,延迟表现更好。
Q2:TIME_WAIT是什么,为什么需要等待2MSL?
客户端四次挥手最后状态;等待足够时间,保证网络中残留旧数据包全部消失,避免旧数据包混入新连接。
Q3:TCP粘包拆包原因和怎么解决?
原因:TCP字节流无消息边界,操作系统缓冲区合并/拆分数据。
解决:长度前缀,包头存消息长度,按长度切割完整消息。
Q4:UDP会不会产生丢包以外问题?
会:乱序、重复收到同一个数据包;业务逻辑要做序号校验、幂等处理。
Q5:全双工半双工?
TCP全双工:连接建立后双方可同时收发;
UDP天然全双工。
总结
TCP面向连接,三次握手建立,四次挥手断开;字节流存在粘包拆包;内核保证可靠有序,自带拥塞流量控制;延迟相对高。
UDP无连接,8字节头部,低延迟;不可靠,丢包乱序重复;面向数据报无粘包;游戏帧同步常在UDP之上封装KCP实现应用层可靠。
TCP粘包拆包标准方案:长度前缀。
🎬 博客主页:https://xiaoy.blog.csdn.net
🎥 本文由 呆呆敲代码的小Y 原创 🙉
🎄 学习专栏推荐:Unity系统学习专栏
🌲 游戏制作专栏推荐:游戏制作
🌲Unity实战100例专栏推荐:Unity 实战100例 教程
🏅 欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!
📆 未来很长,值得我们全力奔赴更美好的生活✨
------------------❤️分割线❤️-------------------------




资料白嫖,技术互助
| 学习路线指引(点击解锁) | 知识定位 | 人群定位 |
|---|---|---|
| 🧡 Unity系统学习专栏 🧡 | 入门级 | 本专栏从Unity入门开始学习,快速达到Unity的入门水平 |
| 💛 Unity实战类项目 💛 | 进阶级 | 计划制作Unity的 100个实战案例!助你进入Unity世界,争取做最全的Unity原创博客大全。 |
| ❤️ 游戏制作专栏 ❤️ | 难度偏高 | 分享学习一些Unity成品的游戏Demo和其他语言的小游戏! |
| 💚 游戏爱好者万人社区💚 | 互助/吹水 | 数万人游戏爱好者社区,聊天互助,白嫖奖品 |
| 💙 Unity100个实用技能💙 | Unity查漏补缺 | 针对一些Unity中经常用到的一些小知识和技能进行学习介绍,核心目的就是让我们能够快速学习Unity的知识以达到查漏补缺 |
