Secure Reliable Transport(SRT)是安全、可靠、低延时的多媒体实时传输协议。SRT协议使用AES进行数据加密,运用FEC进行前向纠错,并且有流量控制、拥塞控制。类似于QUIC协议,SRT采用UDP代替TCP,在应用层提供发送确认机制、ARQ自动重传,减少端到端的延迟。
SRT探测实时网络带宽状况,有利于补偿网络拥塞引起的jitter网络抖动和带宽下降。为了实现低延迟码流传输,SRT协议会携带delay、jitter、丢包等信息。SRT提供多路复用机制,允许多个请求共享相同的端口。
目录
一、数据包结构
1、data packet
2、control packet
二、Handshake
1、握手数据包结构
2、加密算法
3、握手类型
三、Keep-Alive
四、ACK于NAK
1、ACK确认应答
2、NAK否定应答
五、丢包请求
六、拥塞控制
1、慢启动
2、拥塞避免
七、Shutdown
SRT的数据包分为data和control两种类型,结构如下:
data数据包格式如下:
Packet Sequence Number:占31位,序列号。
PP:占2位,数据包位置标志位。“10”代表第一个数据包,“00”代表中间数据包,“01”代表最后一个数据包,“11”代表单个数据包。
O:占1位,顺序标志位。
KK:占2位,加密密钥标志位。“00”代表不用加密,“01”代表偶数密钥,“10”代表奇数密钥。
R:占1位,重传包标志位。
Message Number:占26位,消息的序列号。
Timestamp:占32位,时间戳。
Destination Socket ID:占32位,目标socket标识。
控制数据包格式如下:
Control Type:占15位,控制包类型。
Subtype:占16位,特定数据包类型。
Type-specific Information:占32位,特定数据包信息。
Timestamp:占32位,时间戳。
Destination Socket ID:占32位,目标socket标识。
Control Information Field:有效长度。
其中,Control Type控制包类型如下表所示:
Handshake握手属于控制包类型(control type=0x0000),用于交换双方配置信息、连接参数。握手的数据包结构如下:
其中,Encryption Field包括AES的128位、192位和256位,如下表所示:
握手类型占32位,类型如下:
Keep-Alive属于控制包,在上一次数据包超时后发送,用于心跳保活。结构如下:
Acknowledgment(ACK) 属于控制包,用于表示数据包到达确认。所有ACK包可能会携带额外信息,比如RTT、链路容量、传输速率。ACK控制包结构如下:
其中,ACK包类型包括:
Negative Acknowlegement(NAK)也是属于控制包,用于表示否定应答(没有收到数据包)。与TCP的NACK否定应答不同的是,SRT采用NAK表示否定应答。NAK控制包结构如下:
Message Drop Request用于丢包请求,比如TTL触发一个或多个数据包重传超时。发送端发起丢包请求,告诉接收端这些数据包要丢弃。结构如下:
拥塞控制包括两种类型:Live Congestion Control(LiveCC)和File Congestion Control(FileCC)。
Slow Start,慢启动阶段,拥塞窗口CWND_SIZE初始化为16。拥塞窗口上限为MAX_CWND_SIZE,最大接收缓冲区为12MB。
ACK包的经历步骤如下:
如果接收到NAK包,或者RTO重传超时,也会结束慢启动,进入拥塞避免。
拥塞避免阶段,收到ACK包经历的步骤如下:
其中PKT_SND_PERIOD计算公式如下:
inc = 0;
lossBandwidth = 2 * (1000000 / LastDecPeriod);
linkCapacity = min(lossBandwidth, EST_LINK_CAPACITY);
B = linkCapacity - 1000000 / PKT_SND_PERIOD;
if ((PKT_SND_PERIOD > LastDecPeriod) && ((linkCapacity / 9) < B))
B = linkCapacity / 9;
if (B <= 0)
inc = 1 / S;
else
{
inc = pow(10.0, ceil(log10(B * S * 8))) * 0.0000015 / S;
inc = max(inc, 1 / S);
}
PKT_SND_PERIOD = (PKT_SND_PERIOD * RC_INTERVAL) /
(PKT_SND_PERIOD * inc + RC_INTERVAL);
Shutdown控制包,用于表示断开连接。结构如下: