4. SRT协议深度解析:UDT基础、ACK/NACK机制与加密传输

SRT这个协议,说白了就是UDT协议的一个“超级进化版”。我最早接触UDT是在做跨国文件传输的时候,那时候就觉得这协议挺聪明——能在高延迟、高丢包的网络里把数据稳稳送过去。后来SRT出来,把UDT的核心机制拿过来,针对实时音视频做了大量优化。嗯,今天我们就把它拆开看看。

4.1 UDT:SRT的底层基石

UDT(UDP-based Data Transfer Protocol)是SRT的“亲爹”。它解决了一个核心矛盾:TCP在丢包时性能断崖式下降,而UDP又不可靠。UDT在UDP之上加了一层可靠传输控制,但它的拥塞控制算法和TCP完全不同。

核心区别:TCP是“丢包即拥塞”,UDT/SRT是“丢包可能只是网络抖动”。这个理念差异,决定了它们在弱网下的表现天差地别。

UDT有两个关键机制:

  • 基于速率的拥塞控制:不像TCP那样靠窗口滑动,UDT用发送速率来控制流量。它会根据RTT和丢包率动态调整发送速率。
  • 选择性确认(SACK):只重传真正丢失的包,而不是像早期TCP那样“丢一个包就重传后面所有”。

SRT在UDT基础上做了三件事:

  1. 砍掉了UDT中不适用于实时传输的“慢启动”和“拥塞避免”阶段
  2. 加入了实时传输需要的低延迟模式
  3. 增加了AES加密支持

我的经验:如果你看过UDT的RFC,会发现SRT的报文头结构基本继承了UDT的格式,只是在扩展字段里塞了SRT自己的控制信息。所以理解UDT,就等于理解了SRT的一半。

4.2 ACK/NACK机制:SRT的“精准打击”

SRT的可靠性不靠TCP那种“全量确认”,而是靠ACK和NACK的配合。我个人觉得,这是SRT最精妙的设计之一。

4.2.1 常规ACK:心跳与流量反馈

接收端会定期发送ACK包给发送端。这个ACK包里包含:

  • 已接收到的最大序列号
  • 接收端的RTT估算
  • 接收端的可用带宽估计

发送端收到ACK后,会更新自己的发送速率和RTT估算。注意,SRT的ACK不是每个包都确认,而是周期性发送——默认每10ms或每收到64个包发一次。

4.2.2 NACK:只重传真正丢了的包

这才是SRT的杀手锏。接收端检测到序列号不连续时,会立即发送NACK包,告诉发送端:“我丢了哪些包,赶紧重传。”

关键点:NACK只包含丢失包的序列号列表,而不是整个窗口。这意味着重传开销极低,尤其适合高丢包但低延迟的场景。

我曾经在一个项目中遇到过奇葩问题:网络丢包率高达15%,但延迟要求低于200ms。用TCP直接卡死,用SRT的NACK机制,重传只针对丢失的包,整体延迟控制在150ms以内。嗯,那次之后我就彻底成了SRT的粉丝。

4.2.3 快速重传与超时重传

SRT有两种重传触发方式:

重传类型 触发条件 特点
快速重传 收到NACK后立即重传 延迟低,适合实时场景
超时重传 超过RTO(重传超时时间)未收到ACK 兜底机制,防止NACK丢失

避坑指南:我曾经遇到过RTO设置过小导致的重传风暴。SRT的RTO默认是RTT的4倍,但在高抖动网络里,建议手动调大。否则,网络稍微波动一下,发送端就开始疯狂重传,反而加剧拥塞。

4.3 加密传输:SRT的安全防线

SRT原生支持AES加密,这是它和RTMP、HLS的一个显著区别。RTMP的加密要靠RTMPS(加TLS层),HLS的加密要靠HLS AES-128(加解密流程复杂)。而SRT直接在协议层内置了加密。

4.3.1 加密模式

SRT支持两种加密模式:

  • 无加密:明文传输,适合内网或测试环境
  • AES-128/256:使用预共享密钥(PSK)进行加密

加密是在SRT的payload层做的,不影响控制包(ACK/NACK)的传输。这意味着加密不会影响拥塞控制的效率。

4.3.2 密钥交换

SRT使用简单的PSK模式。发送端和接收端需要预先配置相同的密钥。密钥通过SRT握手阶段协商,握手完成后,后续所有数据包都用这个密钥加密。

注意:SRT的密钥交换是“带外”的——你需要通过其他安全渠道(比如电话、邮件、密钥管理系统)把密钥分发给两端。SRT本身不提供密钥分发机制。

4.3.3 加密对性能的影响

我做过测试,AES-128加密对SRT的吞吐量影响大约在5%-10%之间。对于实时视频传输来说,这个开销完全可以接受。但如果你的CPU比较弱(比如嵌入式设备),建议用AES-128而不是AES-256,能省不少计算资源。

我的建议:在公网传输时,永远开启加密。我曾经见过一个案例,某直播平台用SRT明文传输,结果被中间人篡改了视频流,插入了恶意广告。开启AES-128加密后,这个问题再也没出现过。

4.4 SRT协议栈全景图

下面这张图展示了SRT协议栈的完整结构。你可以看到,SRT在UDP之上,由UDT提供可靠传输基础,SRT层负责实时控制、加密和流管理。

SRT协议栈结构 应用层(视频/音频数据) SRT层(加密/流控制/模式切换) UDT层(ACK/NACK/拥塞控制) UDP层(不可靠传输) IP层(网络层) AES加密 实时模式 ACK/NACK 速率控制

4.5 实战中的参数调优

SRT的参数很多,但真正影响互通质量的,我总结下来就这几个:

参数 默认值 推荐值(弱网) 说明
latency 120ms 200-400ms 接收端缓冲区大小,越大抗抖动能力越强
rcvlatency 120ms 150-300ms 接收端延迟,影响播放启动速度
peerlatency 120ms 200-400ms 对端延迟,用于同步
maxbw 0(自动) 实际带宽的80% 最大发送带宽,防止拥塞
passphrase 空 16位以上随机字符串 AES加密密钥

避坑指南:我曾经在跨洋传输时把latency设成了默认的120ms,结果视频频繁卡顿。后来发现,跨洋RTT本身就接近200ms,120ms的缓冲区根本不够用。把latency调到300ms后,问题解决。记住:缓冲区大小至少要大于RTT,否则SRT的NACK机制来不及发挥作用。