ZLMediaKit 传输协议选型:TCP 与 UDP 快速选择指南
【免费下载链接】ZLMediaKitWebRTC/RTSP/RTMP/HTTP/HLS/HTTP-FLV/WebSocket-FLV/HTTP-TS/HTTP-fMP4/WebSocket-TS/WebSocket-fMP4/GB28181/SRT/STUN/TURN server and client framework based on C++11项目地址: https://gitcode.com/GitHub_Trending/zl/ZLMediaKit
ZLMediaKit 拉流播放卡顿,不知道该上 TCP 还是 UDP?它是一套支持 RTSP/RTMP/WebRTC 等多协议的 C++ 框架,传输协议选型直接决定播放体验。三分钟做出决定,改好 config.ini 即完事。
⚡ 15 秒速选:场景对号入座速查表
选型前先弄清两者差别,一句话版本:
- TCP:先建连接(三次握手:两端互发 3 个包"打招呼"把连接敲定),每发一段数据要等对方回执,等不到就重发(重传:把没确认的包再发一遍)。稳,但每次确认都费时间。
- UDP:不建连接、不等回执、不重发,发完就忘。快,但丢了的包就是丢了。
所以:
| 你的网络环境 / 业务场景 | 推荐协议 | 一句话理由 |
|---|---|---|
| 公网、弱网、直播分发 | TCP | 重传补上丢的包,画面可能等一等,但不会花 |
| 视频监控、视频会议等实时互动(GB28181) | UDP | 实时性优先,偶尔一帧失真可以忍 |
| 局域网、专线、机房互联 | UDP | 网络本来就稳,省掉确认和重传的开销 |
| 点播、重要录像分发 | TCP | 完整性比速度重要 |
结论先行:公网选 TCP,局域网选 UDP,互动选 UDP,分发选 TCP。
🛡️ 求稳路线:config.ini 里如何把 TCP 用好
TCP 的可靠靠三件事:连接、确认、重传。发送方没收到回执就不算送达,超时就把同一个包再发一遍;接收方缓冲快满时,TCP 还会自动让发送方降速(流量控制)。这套机制把"丢包"变成了"等待",画面会卡,但数据是完整的。
代价就是延迟:每次确认都要等一个来回,遇到重传超时卡顿更明显。
什么时候用它:
- RTMP、HTTP-FLV 在 ZLMediaKit 里天然走 TCP,没有得选。
- RTSP 播放时,RTP 部分可以选 TCP。服务器把 RTP 包封装进 TCP 流,每两个包配一对编号(Transport 头里的 interleaved,直白说就是"给包编个序号,让接收端按序拼回"),协商逻辑在 src/Rtsp/RtspSession.cpp。
两个关键参数:
[general] mergeWriteMS:默认0表示数据一到就写 socket,纯实时;改成10是攒够 10ms 再批量写,性能更好但多 10ms 延迟。开启后还会关闭 TCP_NODELAY("小包立即发"模式)并启用 MSG_MORE 批量发送提示。[rtmp] handshakeSecond、[rtmp] keepAliveSecond:默认都是 15 秒。弱网下握手或空闲偏慢,放宽到30能少被服务器断连。
🚀 求快路线:config.ini 里一行参数强制 UDP
UDP 的原理正好相反:无连接、无确认、无重传。延迟天然低,协议头部开销小。但丢包即丢,公网环境会变成花屏、撕裂。
适合:
- 局域网监控、专线、机房互联;
- GB28181、视频会议这类实时互动,实时性比偶尔一帧失真重要;
- 4K 等高带宽场景,头部开销小,省的是真金白银的带宽。
ZLMediaKit 的 UDP 接收端实现在 src/Rtsp/UDPServer.cpp,配合三个参数:
[rtsp] rtpTransportType:强制协商开关,0TCP、1UDP、2多播、-1不限制(默认)。[rtsp] lowLatency:置1后转发不缓存 RTP 包,延迟降一帧,并发也更好。[rtp_proxy] udp_recv_socket_buffer:UDP 接收缓冲区,默认 4194304(4MB),收大流时加大可防溢出丢包。
补一句:WebRTC 底层其实也是 UDP,但多打了"补丁"——NACK(接收方主动上报哪个序号丢了,要求补发),等于在 UDP 之上叠了一层重传。细节见 webrtc/readme.md。
动手三步:ZLMediaKit TCP/UDP 配置 3 行改完
全部改动都在 conf/config.ini。
第 1 步:定 RTSP 传输方向——找[rtsp]段的rtpTransportType,改成1(或0)。
[rtsp] # 强制协商rtp传输方式 (0:TCP,1:UDP,2:MULTICAST,-1:不限制) rtpTransportType=1效果:客户端请求了"不对"的传输方式时,服务器回 461 Unsupported transport,客户端(目前支持 FFmpeg 和 VLC)会重新 SETUP 切到你指定的协议。
第 2 步:UDP 路线降延迟——找[rtsp]段的lowLatency,改成1。
效果:转发时不再缓存 RTP 包,延迟降一帧左右,网络好的时候体感立竿见影。
第 3 步:TCP 路线提吞吐——找[general]段的mergeWriteMS,改成10。
效果:数据攒够 10ms 批量写 socket,系统调用变少、并发更好,代价是延迟多 10ms。追求极致实时就保持默认0。
出问题自检清单:症状、原因、参数逐条对
- 症状:RTSP 客户端播不了,报 461 → 可能原因:强制协商的传输类型和客户端请求的不一致 → 该调:
[rtsp] rtpTransportType改回-1(不限制) - 症状:UDP 播放花屏、撕裂 → 可能原因:公网丢包,UDP 没有重传兜底 → 该调:切
rtpTransportType=0走 TCP,或改用 WebRTC(NACK 重传,[rtc] nackMaxCount控制最多重传请求次数,默认 15) - 症状:RTMP 连接频繁断开 → 可能原因:默认 15 秒超时对弱网太苛刻 → 该调:
[rtmp] handshakeSecond、[rtmp] keepAliveSecond改到30 - 症状:UDP 大流偶发卡顿 → 可能原因:接收缓冲区溢出 → 该调:
[rtp_proxy] udp_recv_socket_buffer从默认 4194304 往上加 - 症状:整体延迟偏高 → 可能原因:低延迟/即时发送未配置 → 该调:UDP 路线开
[rtsp] lowLatency=1;TCP 路线保[general] mergeWriteMS=0即发即走
下一步往哪走
"UDP 的身子 + 重传的补丁"让 WebRTC 正在成为实时互动场景的主流答案,业务要往双向互动走就提前关注。完整参数见 README.md,UDP 接收与 RTSP 协商的源码在 src/Rtsp/。
【免费下载链接】ZLMediaKitWebRTC/RTSP/RTMP/HTTP/HLS/HTTP-FLV/WebSocket-FLV/HTTP-TS/HTTP-fMP4/WebSocket-TS/WebSocket-fMP4/GB28181/SRT/STUN/TURN server and client framework based on C++11项目地址: https://gitcode.com/GitHub_Trending/zl/ZLMediaKit
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考