导语 | 音视频时代,WebRTC在形形色色的产品和业务场景下均有落地。在熟悉如何在浏览器获取设备的音视频数据和WebRTC是如何将获取的音视频数据进行网络传输的同时,我们更要夯实一下网络传输协议相关的基础知识,这能帮助我们更深入地学习WebRTC。推荐和前端音视频专题中的文章一起食用。
我们都知道HTTP协议,运行于TCP协议之上,是万维网的运转的基础。作为一名前端开发,我们似乎理所应当熟悉HTTP、TCP协议,以致于HTTP状态码、报文结构、TCP三次握手、四次挥手等等都已经成为了标配的基础面试题。但对于其他协议,我们似乎多多少少感到陌生。
下图是一个TCP/IP通讯协议的4层结构图,在基于网际层的运输层,它提供了节点间的数据传送服务,其中最为人所熟知的TCP协议(Transmission Control Protocol) 和 UDP协议(User Datagram Protocol)。
两个协议本身涉及到内容非常多,但在实际选择使用中,我们不妨直接通过对比TCP和UDP,来去学习和理解它们。
总体上有以下三点不同:
UDP在传输数据之前不需要建立连接,传输双方可以随时发送数据,因此UDP是无连接的。而TCP协议在传输数据之前三次握手建立连接,在结束后需要四次挥手释放连接,具体细节在此不做赘述。
对于UDP,发送接收方应用层只给UDP传输层发送或接收报文,而UDP除了传输外的处理只是对应用层报文添加或摘除UDP首部,保留了应用层报文,因此说UDP是面向报文。
对于TCP而言,TCP只将应用层交下来的数据当做一连串的无结构字节流,仅将他们存入缓存并根据策略构建TCP报文进行发送,而接受方TCP只提取数据载荷部分存入缓存,并同时将缓存字节流交给应用层。TCP不保证双方应用层的发送和接收数据具有对应大小关系。因此说它是面向字节流的,而它也是TCP实现流量控制和拥塞控制的基础。
UDP在传输数据时,发送产生了丢包,发送方不做任何处理。接收方校验首部发现误码,同样也不做任何处理。因此说UDP向上提供的是无连接不可靠服务。
而TCP在传输数据时,如果发生了丢包或者接收方检查了误码(此时会接收方会丢弃),接收方不会回确认报文,则触发接收方超时重发。由此可见,TCP通过其策略确保其传输过程无论发生什么情况,则接收方就能正确收到该数据包,因此说TCP是向上提供面向连接的可靠服务。
既然TCP有这么多优点特性,那么为什么在实时音视频传输中使用UDP呢?
原因在于实时音视频对于延迟特别敏感,而基于TCP协议的做不到足够低。试想一下在丢包的情况下,TCP协议的超时重传机制中RTT是以2的指数的增长。如果7次重传任然失败,理论计算会达到2分钟!在延迟高的情况下,想做到正常的实时通讯显然是不可能的,此时TCP的可靠性反而成了累赘。
但实际情况是,通常实时音频视频数据在传输的少量数据包丢失,对接收者影响并不大。而UDP不属于连接型协议,我们认为它基本是管发不管收,因而具有资源消耗小,处理速度快的优点。
因此UDP在实时性和效率性都很高,在实时音视频传输中通常会选用UDP协议作为传输层协议。
WebRTC也是如此,在信令控制方面采用了可靠的TCP,但是音视频数据传输上,使用了UDP作为传输层协议(如上图右上)。
实时音视频通讯只靠UDP够不够呢?答案显然是不够的!还需要基于UDP的应用层协议,来专门为音视频通讯做更多保障处理。
音视频中一个视频帧数据量需要多个包来传送,并在接收端组成对应帧,正确还原出视频信号。因此要做到至少两点:
而UDP并没有这个能力,所以音视频传输中,并不直接使用UDP,而是需要RTP作为实时音视频中的应用层协议。
RTP全名Real-timeTransportProtocol(实时传输协议),主用于实时传输数据。那么RTP协议提供哪些能力?
包括以下四点:
但不包括:
接下来让我们简单看下RTP协议规范[1]
RTP报文由两部分组成:报头和有效载荷。
以下为RTP协议头的解释,前12字节是固定的,CSRC可以有多个或者0个。
前面提到RTP协议整体上还是比较简单粗暴的,其本身并没有提供按时发送机制或其它服务质量(QoS)保证。因此RTP还需要有一套配套协议为其服务质量提供保证,则就是RTCP协议(全名Real-timeControlProtocol)。
RTP标准定义了两个子协议,RTP和RTCP。
举个例子,在传输音视频时的丢包,乱序,抖动,这些WebRTC在底层都有对应的处理策略。但是如何将这些传输时 “网络质量信息” 实时告诉对方,就是RTCP它的作用。相对于RTP来说,RTCP所占的带宽非常小,通常只有5%。
接下来让我们简单看下RTCP协议规范:首先RTCP报文有多种类型:
以上为SR的协议规范:
通过报告以上信息,各端知道网络传输反馈数据后,就可以根据其做传输策略的调整了。当然协议本身的内容并不只有上面的简单一小段,实际还涉及各项反馈数据的计算方法,这里篇幅有限不展开细讲。
当了解为什么选择UDP协议、以及RTP/RTCP协议做了些什么事情之后,让我们简单总结在传输协议层面上的整个流程:
当应用建立一个RTP会话时,应用程序将确定一对目的传输地址。目的传输地址由一个网络地址和一对端口组成,有两个端口:一个给RTP包,一个给RTCP包。RTP数据发向偶数的UDP端口,而对应的控制信号RTCP数据发向相邻的奇数UDP端口(偶数的UDP端口+1),这样就构成一个UDP端口对。大致流程如下:
纸上得来终觉浅,绝知此事要躬行。接下来让我们通过实际播放WebRTC流媒体,并通过抓包来还原RTP包和RTCP报文的真面目。
Wireshark是一个强大的网络数据包分析软件,可以详细的展示网络数据包的交换过程,是监控网络请求定位网络问题的利器。这个强大的抓包工具,涉及非常多功能,由于这里不是Wireshark教程,更详细的功能课自行搜索挖掘,这里只会讲个大致流程:
其中我们应该着重关注的部分内容: Playload type(PT值):代表负载的类型,其中这里122对照WebRTC的SDP可以确认是H264视频负载类型数据。
时间戳:记录的是采样时刻为6120,还要根据采样率进行换算。
SSRC: 同步源(SSRC)标识符为0x0202c729。以上这些都是RTP头部,最后playload才是承载的媒体数据。
RTP的特点不仅仅支持承载在UDP上,有利于低延迟音视频数据的传输,它允许通过其它协议接收端和发送端协商音视频数据的封装和编解码格式,playload type字段比较灵活支持的音视频数据类型非常多的,具体可以参考:RTP payload formats
让我们再具体看看RTP包的音视频帧:
其中下面seq=21到seq=24的多个数据包,每个单独为一个音频帧,所以时间戳不同。而红色框seq=96到seq=102的多个数据包组成,组成PT=122的一个视频帧,所以这几个报的时间戳也是相同的。这是因为一个视频帧包含数据量较大,需要分开多个包发送。而音频帧较小,则单独一个包发送,从它们的包length大小就能看出视频包比音频包要大的多。另外seq=102的数据包,mark字段为true表示为一个视频帧的最后一个数据包,通过结合seq可以知道音视频数据的接收是否有乱序或者是丢包。
不少人觉得一名开发者在学习使用WebRTC时,能够快速上手实践和业务落地就足够了,再去了解这些传输协议有必要吗?但常常即便你已经清楚如何使用它,不代表你能发挥出它本身最大优势。我认为运用一项技术所达到的上限,往往取决于你对它的底层理解有多深入。
这里简单介绍为什么实时音视频选择UDP作为传输层协议,以及简单介绍WebRTC所涉及协议中比较重要的两个协议RTP/RTCP,像WebRTC技术涉及与融合多方面种技术(音视频处理,传输、安全加密等等)每个模块涉及的协议都能单独写一篇文章,篇幅所限以及本人掌握的内容比较有限,此文无法对更多内容进行展开。如果你想学习实践WebRTC,此文只能让你在其传输协议层面上有初步的认识。由于协议往往涉及底层,平时运用往往关注不到,因此还介绍了如何快速上手抓包来帮助理解,如果想深入学习还需另寻资料深入学习。
[1]RTP协议: https://tools.ietf.org/html/rfc35f50#
紧追技术前沿,深挖专业领域
扫码关注我们吧!