4. 网络传输优化:TCP vs UDP模式选择、MTU与MSS调优、NAT穿透与防火墙策略

网络传输这块,说白了就是RTSP推流的"血管"。血管堵了,再好的编码器、再强的服务器都白搭。我在项目中见过太多案例——推流端配置拉满,结果画面卡成PPT,最后查下来全是网络层的问题。

这一章我们聚焦三个核心问题:选TCP还是UDP?怎么让数据包不碎不丢?怎么穿透内网和防火墙?嗯,一个一个来。

4.1 TCP vs UDP:RTSP推流的传输层抉择

RTSP本身是控制协议,但媒体数据的传输方式可以灵活选择。我个人的习惯是:先看场景,再定协议。

对比维度 TCP UDP
可靠性 有重传、有序到达 无重传、可能丢包乱序
延迟 较高(重传+拥塞控制) 较低(无确认机制)
防火墙友好度 高(HTTP/HTTPS端口常见) 低(容易被拦截)
适用场景 公网、弱网、要求稳定 局域网、低延迟直播

核心结论:公网推流优先选TCP,局域网低延迟场景选UDP。但要注意——RTSP over UDP的端口范围通常需要协商,很多防火墙默认会拦截高位UDP端口。

我记得有一次帮客户排查推流卡顿,他们坚持用UDP,说延迟低。结果发现运营商对UDP流量做了限速,丢包率高达15%。换成TCP后,虽然延迟多了几十毫秒,但画面流畅了。你想想看,丢包15%的情况下,UDP的画面基本没法看。

4.1.1 RTP over RTSP(TCP模式)

TCP模式下,RTP数据包被封装在RTSP的TCP连接中传输。具体做法是使用Transport: RTP/AVP/TCP;unicast;interleaved=0-1这样的头字段。

// 客户端请求
SETUP rtsp://example.com/stream RTSP/1.0
CSeq: 3
Transport: RTP/AVP/TCP;unicast;interleaved=0-1

// 服务器响应
RTSP/1.0 200 OK
CSeq: 3
Transport: RTP/AVP/TCP;unicast;interleaved=0-1;ssrc=12345678
Session: 987654321

这里interleaved=0-1表示RTP数据使用通道0,RTCP数据使用通道1。数据直接在同一个TCP连接里交错发送。好处很明显——只需要一个端口,防火墙配置简单。

实战技巧:TCP模式下的RTP数据包前面会加4字节的帧头($ + 通道号 + 2字节长度)。解析时一定要按这个格式拆包,我见过有人直接当裸RTP解析,结果全乱套了。

4.1.2 RTP over UDP(UDP模式)

UDP模式使用独立的端口传输RTP和RTCP。典型的Transport头是这样的:

Transport: RTP/AVP;unicast;client_port=5000-5001

客户端端口5000收RTP,5001收RTCP。服务器会从自己的端口向这两个端口发数据。

为什么会有人坚持用UDP?因为延迟确实低。没有TCP的慢启动、拥塞控制、重传机制,数据包发出去就不管了。在局域网内,UDP的端到端延迟可以控制在10ms以内。

注意:UDP模式需要额外的NAT穿透处理。如果推流端和服务器之间有NAT设备,必须确保RTP和RTCP的端口映射都正确。我曾经遇到一个案例,RTP端口映射了但RTCP没映射,结果服务器收不到接收报告,一直以最低码率推流。

4.2 MTU与MSS调优:让数据包不碎不丢

MTU(最大传输单元)和MSS(最大分段大小)是网络传输中容易被忽视的参数。说白了,MTU是网络链路层能承载的最大数据包大小,MSS是TCP层能发送的最大数据段大小。

以太网的默认MTU是1500字节。减去IP头(20字节)和TCP头(20字节),MSS就是1460字节。但问题来了——RTP包的大小可能超过这个值。

4.2.1 为什么MTU调优很重要

当IP包大小超过MTU时,路由器会进行分片。分片带来的问题:

  • 性能下降:分片和重组消耗CPU资源
  • 丢包放大:一个分片丢了,整个包都得重传
  • 延迟增加:重组需要等待所有分片到达

我建议在推流前先做MTU探测。用ping -M do -s 1472 target_ip(Linux)或ping -f -l 1472 target_ip(Windows)测试路径MTU。

# Linux下探测路径MTU
ping -M do -s 1472 192.168.1.100
# 如果返回"Message too long",减小size重试
ping -M do -s 1400 192.168.1.100
# 直到成功,得到路径MTU = size + 28

关键参数:RTP包大小建议控制在路径MTU的90%以内。比如路径MTU是1500,RTP包不要超过1350字节。留出余量给IP选项和隧道开销。

4.2.2 MSS调优实战

对于TCP模式,MSS调优直接影响传输效率。MSS太大,容易触发IP分片;MSS太小,传输效率低。

场景 推荐MSS 说明
标准以太网 1460 MTU 1500 - IP头20 - TCP头20
PPPoE拨号 1452 额外8字节PPPoE头
VPN隧道 1400-1440 取决于隧道封装开销
无线网络 1300-1400 无线链路不稳定,建议偏小

我个人习惯在推流服务器上设置ip tcp mss来全局调整:

# Linux下设置TCP MSS为1400
iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN \
         -j TCPMSS --set-mss 1400

避坑指南:我曾经在云服务器上部署推流服务,发现公网推流总是间歇性卡顿。排查了三天,最后发现是云平台的虚拟化网络MTU只有1400,而我的MSS设成了1460。每次超过1400的包都被分片,分片丢失导致TCP重传,重传又加剧拥塞。把MSS降到1360后,问题彻底解决。

4.3 NAT穿透与防火墙策略

NAT穿透是公网推流绕不开的坎。RTSP的控制信令和媒体流走不同的端口,NAT设备需要正确处理这些映射关系。

4.3.1 NAT类型与穿透方案

NAT分为四种类型,穿透难度依次递增:

NAT类型 特点 穿透难度
全锥形 任何外部主机都能通过映射地址访问 低
受限锥形 只允许内部主机曾访问过的外部IP访问 中
端口受限锥形 限制外部IP和端口 中高
对称NAT 每个外部目标使用不同的映射 高

对于RTSP推流,我推荐以下穿透策略:

  • TCP模式:使用单一端口,NAT映射简单,推荐首选
  • UDP模式:使用STUN/TURN服务器辅助穿透
  • 对称NAT:必须使用TURN中继,否则无法穿透

4.3.2 防火墙策略配置

防火墙配置的核心原则是:最小权限,按需开放。

# 推流服务器防火墙规则示例(iptables)
# 允许RTSP控制端口(默认554)
iptables -A INPUT -p tcp --dport 554 -j ACCEPT

# 允许RTP/RTCP UDP端口范围(假设使用50000-51000)
iptables -A INPUT -p udp --dport 50000:51000 -j ACCEPT

# 允许已建立的连接回包
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# 默认拒绝其他入站
iptables -P INPUT DROP

注意:UDP端口范围不要开太大。我见过有人直接开了1024-65535,这等于把防火墙关了。合理的做法是根据并发推流数计算端口需求,每个流需要2个端口(RTP+RTCP),再留20%余量。

4.3.3 实战中的NAT穿透方案

根据我的经验,不同场景的推荐方案:

  • 局域网内推流:直接使用UDP,无需NAT处理
  • 公网推流(推流端在NAT后):TCP模式 + 端口映射
  • 公网推流(两端都在NAT后):TCP模式 + TURN中继
  • 移动网络推流:TCP模式 + 自适应码率

我记得有一次给一个安防项目做方案,摄像头在多个不同运营商的NAT后面,推流到中心服务器。一开始用UDP模式,各种穿透失败。后来全部改成TCP模式,配合服务器端的端口复用,稳定运行了两年没出过问题。

核心建议:除非你对网络环境有绝对控制权(比如纯局域网),否则默认使用TCP模式。TCP的可靠性、防火墙友好度和NAT穿透便利性,远超过那点延迟优势。延迟问题可以通过调整TCP参数(如Nagle算法、窗口大小)来优化。

RTSP推流网络传输优化决策流程 推流网络环境评估 是否在公网环境? 是 否 TCP模式 + 端口映射 MTU探测 + MSS调优 UDP模式(低延迟) RTP包大小控制 防火墙策略配置 稳定推流上线 公网默认TCP,局域网可选UDP

网络传输优化没有银弹。我的建议是:先跑通,再优化。先用TCP模式把推流跑起来,然后根据实际网络状况逐步调整MTU、MSS和防火墙策略。等系统稳定了,再考虑是否切换到UDP模式来降低延迟。