TCP / UDP 对比介绍

TCP / UDP 对比介绍

传输层两大协议;IP负责把数据包送到目标机器,TCP/UDP负责机器上对应程序之间的数据交付。

UDP 用户数据报协议(User Datagram Protocol)

核心特点

  1. 无连接:通信前不需要握手,直接发数据包;不用维护连接状态。
  2. 不可靠 :不保证到达、不保证顺序、不保证不重复。
    • 数据包可能丢包
    • 数据包乱序到达(先发的后到)
    • 数据包重复收到
  3. 面向数据报:UDP保留报文边界,一次send对应一个完整报文,接收必须一次读完;不会粘包。
  4. 头部很小,8字节,开销极低。

优点

  • 延迟低,没有握手、重传、拥塞控制开销。
  • 没有连接维护,可以一对多广播、组播。

缺点

  • 可靠性全部需要应用层自己实现:序号、ACK确认、重传、去重、排序。
  • 网络差环境丢包现象明显。

典型使用场景

  • 直播、语音视频、实时游戏帧同步(帧同步底层大多UDP)、DNS查询。

游戏中UDP常见问题

  1. 丢包:关键消息直接没收到;
  2. 乱序:状态消息时序错乱;
  3. 重复包:同一消息收到多次,业务要做幂等;

所以很多游戏框架(ENet、KCP)都是在UDP之上实现可靠传输


TCP 传输控制协议(Transmission Control Protocol)

核心特点

  1. 面向连接:通信前必须建立连接(三次握手);结束要四次挥手断开连接。
  2. 可靠传输 :保证数据送达、保证顺序、自动去重。
    • 序列号 Sequence Number
    • ACK确认应答,没收到ACK自动超时重传
  3. 面向字节流 :没有报文边界,是一串连续字节流 → 会发生粘包、拆包(面试高频)
  4. 自带拥塞控制、流量控制。
  5. TCP头部最少20字节,可变。

关键机制

  1. 序列号与ACK确认

    每一个字节数据分配序号;接收方回复ACK告诉发送方"我收到几号之前的数据"。发送方超时没收到ACK,自动重传。

  2. 流量控制(滑动窗口)

    接收方告诉发送方自己还能接收多少缓冲区,防止发送太快把接收缓冲区打满。

  3. 拥塞控制

    网络链路拥堵时自动降低发送速率,避免网络进一步恶化;慢启动、拥塞避免、快重传、快恢复。

TCP三次握手(建立连接)

客户端C,服务端S

  1. C → S:SYN 同步报文,请求建立连接
  2. S → C:SYN+ACK,同意连接
  3. C → S:ACK,确认;连接建立,可以收发数据。

为什么要三次,不是两次?

防止旧的过期无效连接请求报文到达服务器,服务器错误建立无用连接浪费资源。

TCP四次挥手(断开连接)

TCP是全双工,双方可以独立关闭自己发送方向。

  1. C→S FIN:客户端关闭自己的发送通道(我不再发数据)
  2. S→C ACK:收到关闭请求
  3. S→C FIN:服务端也关闭自己发送通道
  4. C→S ACK:确认断开。

客户端会进入TIME_WAIT状态,等待2MSLS;确保对方收到最后的ACK,防止残留数据包干扰下一次连接。

TCP两大经典坑:粘包 & 拆包

因为TCP是字节流,没有消息边界。

  • 粘包:多次发送的小数据包,内核缓冲区合并,一次全部读到。send1+send2,recv一次拿到两段拼在一起。
  • 拆包:一条大消息太大,底层拆分多个TCP片段,多次recv才能读完完整消息。

✅应用层解决方案(游戏网络必背)

  1. 长度前缀法(最常用) :每条消息 =【消息长度4字节】+【消息二进制内容】
    接收端先读4字节得到消息体长度,再读取对应字节,切分出一条完整消息。
  2. 特殊分隔符(很少游戏用,文本协议如HTTP)

TCP优缺点

✅优点:内核提供可靠、有序,业务不用自己处理丢包乱序。

❌缺点:

  1. 握手、重传、拥塞控制带来额外延迟;网络抖动时重传会造成延迟突增;
  2. 粘包拆包必须业务层处理;
  3. 连接资源有限,每一条连接占用内核内存。

使用场景

HTTP/HTTPS、RPC、账号登录、道具交易、MMORPG状态同步(大部分状态同步走TCP)。


TCP vs UDP 对比总表

对比项 TCP UDP
连接特性 面向连接(三次握手/四次挥手) 无连接
可靠性 可靠:不丢包、有序、自动去重 不可靠:丢包、乱序、重复都可能发生
传输模式 字节流,粘包拆包 数据报,保留报文边界,无粘包
头部大小 最小20字节 8字节
流量/拥塞控制 内核自带滑动窗口、拥塞控制 无,完全应用层控制
延迟 较高,抖动网络延迟波动大 低延迟
广播组播 不支持 支持
适用场景 登录、交易、状态同步、HTTP 语音、直播、帧同步游戏、DNS

游戏网络选型(面试高频)

  1. 状态同步(MMO):大多TCP;关键指令可靠;对延迟容忍略高。
  2. 帧同步(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的知识以达到查漏补缺
相关推荐
m0_614523551 小时前
故障排查:移动物体表面贴图为什么会漂移?从稳定纹理到连续帧验收
网络·人工智能·贴图
星栖与芯1 小时前
STM32MP157 M4 指针避坑(三):生命周期与内存踩踏——HardFault 重灾区
java·网络·stm32
SKH.2 小时前
网络(4)HTTP协议与TCP并发服务器
网络·tcp/ip·http
(Charon)2 小时前
【C++】网络缓冲区设计(一):为什么需要Buffer?输入输出缓冲区与统一接口
网络
lzfshub2 小时前
Open-DIS Python发送DIS实体状态PDU:实现坦克炮塔与主炮部件参数
java·网络·python·dis
SatanII2 小时前
OpenStack核心组件详解|Keystone+Glance+Nova+Cinder原理与实操笔记
网络·笔记·openstack
吹什么轩2 小时前
linux网络:UDP原理
linux·网络·udp
你不是我我4 小时前
【AI 测评】群晖 NAS 部署 Vaultwarden:从 HTTPS 到浏览器自动填充的完整密码管理流程
网络协议·http·https
啊阿狸不会拉杆11 小时前
《计算机网络-自顶向下方法》5.4 ISP之间的路由选择:BGP 读书笔记
网络·计算机网络·接口隔离原则