4. HLS协议详解
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基础上做了三件事:
- 砍掉了UDT中不适用于实时传输的“慢启动”和“拥塞避免”阶段
- 加入了实时传输需要的低延迟模式
- 增加了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层负责实时控制、加密和流管理。
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机制来不及发挥作用。