3. 网络基础与推流:TCP/UDP协议选择、网络带宽估算、丢包与延迟分析
做RTSP推流,说白了就是在跟网络打交道。我见过太多人上来就调编码参数、改推流地址,结果问题出在最基础的网络选择上。这一章咱们就把网络这块掰开揉碎了讲清楚。
3.1 TCP vs UDP:推流到底该选谁?
RTSP本身是一个控制协议,真正传视频数据走的是RTP。而RTP可以跑在TCP上,也可以跑在UDP上。这个选择,直接影响你的推流能不能稳得住。
| 特性 | TCP | UDP |
|---|---|---|
| 可靠性 | 有重传,数据完整 | 无重传,可能丢包 |
| 延迟 | 较高(重传导致) | 低,无确认机制 |
| 穿透性 | 好,防火墙友好 | 差,NAT容易阻断 |
| 适用场景 | 弱网、公网推流 | 内网、低延迟直播 |
我个人习惯是:公网推流首选TCP,内网低延迟场景用UDP。为什么?
UDP虽然快,但有个致命问题——它不保证数据到达。我在项目中遇到过,用UDP推流到公网服务器,画面每隔几秒就花一下。查了半天,是中间某个路由器把大包丢了,客户端收不到关键帧,直接卡死。
TCP就不一样了。它自带重传机制,丢了的包会重新发。代价是延迟会高一些,但换来的是画面稳定。你想想看,直播时画面偶尔延迟半秒,和画面频繁花屏,哪个更让人崩溃?
核心结论:
- 公网/跨运营商推流 → 用TCP
- 内网/局域网推流 → 可以用UDP
- 移动网络(4G/5G)→ 强烈建议TCP
3.2 网络带宽估算:别等卡了才想起来算
很多新手犯的错:编码器设了4Mbps码率,结果上行带宽只有2Mbps,推流当然卡。带宽估算这事,应该在部署前就做完。
我一般按这个公式估算:
所需带宽 = 视频码率 + 音频码率 + 协议开销(约10%~15%)
举个例子:
- 视频码率:4 Mbps
- 音频码率:128 Kbps
- 协议开销:约15%
- 实际需要带宽 ≈ (4 + 0.128) × 1.15 ≈ 4.75 Mbps
注意:这里的带宽是上行带宽,不是你家宽带的下载带宽。很多家庭宽带上下行不对等,100M下行可能只有10M上行。推流前一定先测一下上行速度。
怎么测?我推荐用 iperf3,简单粗暴:
# 服务端(在推流目标机器上跑)
iperf3 -s
# 客户端(在推流机器上跑)
iperf3 -c 目标IP -u -b 5M -t 30
这个命令会发30秒的UDP流量,测试实际能跑多少。如果丢包率超过1%,说明带宽不够或者网络质量差,得降码率或者换TCP。
3.3 丢包与延迟分析:问题到底出在哪?
推流卡顿,要么是丢包,要么是延迟。但很多人分不清到底是哪个。我教你们一个简单的排查方法。
3.3.1 丢包怎么看?
用 ping 加参数就能看个大概:
ping 目标IP -c 100 -i 0.1
看输出里的 packet loss 字段。如果丢包率超过0.5%,推流大概率会出问题。
更精确的,用 mtr 工具:
mtr -r -c 100 目标IP
这个工具会显示每一跳的丢包率。我曾经用这个发现,问题出在某个运营商的骨干节点上——中间一跳丢了3%的包,导致整个链路不稳。
3.3.2 延迟怎么量?
延迟分两种:
- 网络延迟(RTT):数据包从A到B再回来的时间
- 端到端延迟:从摄像头采集到客户端显示的时间
网络延迟用 ping 就能看。端到端延迟就复杂了,我一般用 ffprobe 分析推流日志:
ffprobe -v quiet -print_format json -show_streams rtsp://推流地址
看里面的 start_time 和 duration 字段,能估算出大概的延迟。
我的经验值:
- 内网UDP推流:端到端延迟 < 200ms
- 公网TCP推流:端到端延迟 500ms ~ 2s
- 如果超过3s,说明网络或编码器有问题
3.4 核心知识体系
下面这张图,把本章的核心逻辑串起来了。建议保存下来,排查问题时对着看。
3.5 避坑指南
最后分享几个我踩过的坑:
- 别信运营商给的带宽数字——实际可用带宽往往只有标称的60%-70%。我曾经在某个机房,标称100M上行,实际跑iperf3只有40M。
- UDP推流一定要加FEC(前向纠错)——不加的话,丢一个包画面就花一片。加了之后,丢几个包还能恢复。
- TCP推流注意窗口缩放——默认TCP窗口可能不够大,导致吞吐量上不去。可以调大
net.core.wmem_max和net.core.rmem_max。
一句话总结:网络是推流的地基。协议选对、带宽算准、丢包延迟盯住,推流就稳了一半。