1.SRT的前世今生
SRT是安全(Security)可靠IReliable)传输(Transport)的首字母组合,简单来说SRT就是一个安全可靠的传输协议。
SRT源自UDT协议。UDT创建于2001年,其设计目标是在公共网络上以最短的时间传输文件。UDT开发者向IETF提交过4份草案,其最终版本停留在了2013年。同样是在2013年,Haivision(一家编码器供应商)扩展了UDT的实时音视频传输能力,并在4年后(2017年)将其开源并取名为SRT。
2.选择TCP还是UDP?
SRT作为流媒体传输协议中的一种,在详细讲解之前,需要先弄清楚流媒体传输协议和我们通常所说的传输层协议TCP、UDP有什么不同?
我们通常所说的流媒体传输协议属于应用层协议,而TCP、UDP则是属于传输层协议,也就是说流媒体传输协议其实是依赖于传输层协议才能工作的,如图1所示。因此所有的流媒体协议其底层都通过使用TCP或者UDP来实现网络传输。
图1
流媒体协议底层应该选择TCP还是UDP?
主流的流媒体协议选择TCP和UDP协议的都有,例如RTMP协议底层选择的是TCP,而QUIC、SRT协议选择的是UDP。但从趋势来看,新的流媒体协议大都选择UDP作为底层传输协议,其主要原因和流媒体业务本身的特性及TCP特性有关。
从流媒体最常见的业务直播来看,用户需要直播出流快,延时低,不卡顿,在遇到弱网的情况下,能接受损失一部分画面,但是希望能快速恢复。
但是这种要求对于TCP协议而言,则很难做到这些。
首先,TCP协议需要经过3次握手才能建立链接,如要通过TLS加密则还需要4次的握手,要是上层还有流媒体协议,则需要更多的交互流程,因此在建立链接方面,TCP协议交互流程太多,不适合快速出流。
其次,由于TCP协议是一个高可靠且有序的协议,因此如果出现序号较低的数据包丢了,即使序号高的已经收到了,也要等序号低的重传接收后才能使用,导致当前窗口阻塞在原地(TCP队头阻塞),要是重传的数据包也丢失,触发再次重传需要等待的时间会加倍(重传策略温和),而这个机制会影响数据的传输效率,对于实时性要求较高的流媒体业务,是不可接受的。
最后,在遭遇弱网情况下,TCP协议的慢启动和拥塞避免算法都会大幅度的降低自身的带宽占用,从而保护整个通信链路的稳定(TCP是一个无私的协议),所以在这种策略下一旦遭遇弱网,表现出来就是直播画面卡顿,基本没有弱网对抗能力。
总结,基于以上几点,TCP协议并不适合作为流媒体传输协议的底层协议,其协议在设计之初并没有考虑实时性的要求,下面我们一起看一下SRT协议如何解决上面提到的问题
3.SRT协议详解
SRT协议通过简单的握手、固定的延时量、ARQ(自动重传请求)、FEC(前向纠错)以及ACK、NACK等策略解决TCP协议在流媒体业务上存在的问题。
3.1. SRT如何解决握手耗时长问题?
SRT握手如图2所示,通过2次握手和参数交换即可快速建立起一个SRT链接(总耗时:2RTT),相比基于TCP的流媒体协议RTMP 3RTT的握手时间,总耗时减少1个RTT。
图2
3.2. SRT如何实现可靠传输
从图2流程图中发现SRT握手结束之后,就可以发媒体数据和控制指令,媒体数据结构如图3所示。
图3
- 数据包序列号:数据包序号的初始值在握手时确定,之后每发一个数据包,数据包序号就会加1;
- 报文序号:报文序号从0开始,之后每发一个数据包,报文序号就会加1,报文序号前4个标志位功能如图3所示;
- 时间戳:以建立时间为基准,单位为微秒;
- 目的地端口套接字ID:在多路复用的时候可以用来区分不同的SRT流。
ACK控制指令如图4所示。
图4
SRT通过数据包序列号和报文序号,能明确那些数据包已经被发送出去,通过接收端发送过来的ACK控制指令就知道发送出去的哪些数据已经被成功接收了。如果出现丢包等情况,接收端通过NAK控制指令(如图5所示)通知发送端重传数据。通过以上方式,SRT实现了可靠传输。
图5
3.3. SRT如何实现解决队头阻塞问题
上文描述了SRT如何实现可靠传输,从实现来看,发送端必须有一个发送缓存区,接收端也需要一个接收缓冲区才能实现在丢包后数据重传的机制(这和TCP的实现原理相似)。SRT协议通过设置固定延时量来统一规定发送缓冲区和接收缓冲区的大小。
发送缓冲区用来保存有可能需要重发的数据包,一旦数据包收到了肯定应答(ACK),则该数据包会被清理出发送缓冲区(这点和TCP也类似),一旦发送缓冲区某个数据包一直收不到肯定应答,则该数据包在超过固定延时时间后也会被清理出发送缓冲区,SRT通过这种方式解决了TCP队头阻塞的问题。说到这里需要澄清一个事实,就是SRT虽然是可靠的传输协议,但是这个可靠是有条件的,只有在固定延时量下,数据的发送时可靠的,一旦超出固定延时时间,数据还是会被丢弃,其实这也符合媒体业务的特点(在异常情况下,允许丢失一部分数据,但是要能快速恢复)。
3.4. SRT如何实现实现自适应问题
从图4的ACK内容可以发现,ACK中带有许多网络参数,例如RTT时间等。通过RTT时间和链路带宽等参数,SRT就可以估计整个网络状态,从而实现自适应的调整。需要说明的是SRT的发送策略较为激进,不像TCP协议一样是一个无私的协议。SRT在网络较差的情况下依然会保持较大的发送速率,也正是因为这个特点,在网络状况不好的时候,SRT能够占用更大的网络带宽实现媒体数据的发送,保证流畅度。
但是如果网络中都是类似于SRT这种发送策略激进的协议,到后面会出现谁的数据也发不出去的情况,因此在业务的选择上可以综合考虑SRT和TCP协议的特点,优先保证重要业务占用网络带宽。
3.5. SRT得与失
除了以上对于SRT的介绍之外,SRT还能实现媒体数据的多路复用,其原理是利用SRT数据包中的目的地端口套接字字段(如图3所示),多个SRT端口套接字绑定在同一个UDP端口上即可实现SRT的多路复用。
SRT协议在有损网络情况下表现也较其他流媒体协议更有优势,除了上面阐述的机制之外,SRT协议中使用精准时间戳(如图3所示)保证接收端收到的数据能准确的还原发送端的码率特性和固定的帧间隔。
虽然SRT协议有很多优势,但是有一些缺点也不容忽视。首先就是SRT协议带宽占用高;其次SRT协议传输策略激进,会影响同网络下的其他用户;最后由于SRT底层是走的UDP,而防火墙对于UDP并不友好,会导致握手失败。
4.如何评价一个新的流媒体协议?
通过对SRT协议的分析,我们了解到一个优秀的流媒体协议首先应该要能满足以下要求👇
1.能快速的和对方建立链接
2.能知道数据是否已经送达
3.能检测数据是否丢失了,确认丢失后能及时重传
4.能尽快的发送数据
5.能适应对方的接收能力变化,接收能力强是加快发送,接收能力弱时降低发送
6.能自动适应网络变化,网络差时降低发送,网络好时增加发送,占用带宽合理
将以上几点进行总结,一个好的流媒体协议的评价方向有:
- 快速的连接速度
- 良好的确认机制
- 快速的发送机制
- 合理的重传策略
- 优秀自适应能力
有了以上评价标准,我们就能快速的评价一个我们没有接触过的流媒体协议是否优秀,以及通过这种方式比较市面上常见的流媒体协议的优劣,评价五维图如图6所示。
图6
5.总结
目前没有一种流媒体协议在设计方面全方位领先其他协议,流媒体协议的选择需要与具体的业务相结合,只有在确定了具体的业务之后,才有协议设计的优劣之分。同时,我们也必须清楚,协议设计的领先并不是选择的这个协议的唯一标准,还需要考虑行业的现状以及服务提供商的的状况,正如RTMP协议虽然已经停更将近10年,但是由于大量的服务提供商还在使用这个协议,所以其兼容性特别好,一时半会不会消失。