实时传输协议:RealtimeTransportProtocol(RTP)。 实时传输控制协议:RealtimeTransportControlProtocol(RTCP)。 RFC文档为RFC3550(RFC1889为其过期版本)详细介绍了RTPRTCP相关协议。 RTP对音频、视频、图像等多种种需要实时传输的多媒体数据提供端到端的实时传输服务。RTP为Internet上端到端的实时传输提供时间信息和流同步,但并不保证服务质量,服务质量由RTCP来提供。 本章对RTP进行简介和实例说明,RTCP在后面章节详细解释。RTP协议详解 RTP初始设计是用来满足参与者媒体会议的需要,它没有限定于专门的应用。但随着在单播或多播网络需求中应用实时数据传输的推广。RTP现在广泛的应用在流媒体直播、会议、可视电话等多个领域中。 简单的多播音频会议。语音通信通过一个多播地址和一对端口来实现。一个用于音频数据(RTP),另一个用于控制包(RTCP)。 音频和视频会议。如果在一次会议中同时使用了音频和视频会议,这两种媒体将分别在不同的RTP会话中传送,每一个会话使用不同的传输地址(IP地址端口)。如果一个用户同时使用了两个会话,则每个会话对应的RTCP包都使用规范化名字CNAME(CanonicalName)。与会者可以根据RTCP包中的CNAME来获取相关联的音频和视频,然后根据RTCP包中的计时信息(Networktimeprotocol)来实现音频和视频的同步。 基于UDP实现的,RTP用来为端到端的实时传输提供时间信息和流同步,但并不保证服务质量。服务质量由RTCP来提供。 整体协议字段如图所示: 图1rtp协议 1。RTP协议之Header固定头结构解析 图2Header固定头 Header固定头有12个固定字节,各字段按比特计算,代表含义如下所示: (1)版本(V):2比特,此定义了RTP的版本。此协议定义的版本是2。 (2)填充(P):1比特,若填料比特被设置,则此包包含一到多个附加在末端的填充比特,填充比特不算作负载的一部分。填充的最后一个字节指明可以忽略多少个填充比特。填充可能用于某些具有固定长度的加密算法,或者用于在底层数据单元中传输多个RTP包。 (3)扩展(X):1比特,设置扩展比特标识。0代表无扩展头,1代表有扩展头。 (4)CSRC计数(CC):4比特,CSRC计数包含了跟在固定头后面CSRC识别符的数目。 (5)标志(M):1比特,标志的解释由具体协议规定。它用来允许在比特流中标记重要的事件,如帧边界。 (6)负载类型(PT):7比特,此定义了负载的格式,由具体应用决定其解释,协议可以规定负载类型码和负载格式之间一个默认的匹配。其他的负载类型码可以通过非RTP方法动态定义。RTP发送端在任意给定时间发出一个单独的RTP负载类型;此不用来复用不同的媒体流。 (7)序列号(sequencenumber):16比特,每发送一个RTP数据包,序列号加1,接收端可以据此检测丢包和重建包序列。序列号的初始值是随机的(不可预测),以使即便在源本身不加密时(有时包要通过翻译器,它会这样做),对加密算法泛知的普通文本攻击也会更加困难。 (8)时间戳(timestamp):32比特,时间戳反映了RTP数据包中第一个字节的采样时间。时钟频率依赖于负载数据格式,并在描述文件(profile)中进行描述。也可以通过RTP方法对负载格式动态描述。 (9)SSRC:32比特,用以识别同步源。标识符被随机生成,以使在同一个RTP会话期中没有任何两个同步源有相同的SSRC识别符。尽管多个源选择同一个SSRC识别符的概率很低,所有RTP实现工具都必须准备检测和解决冲突。若一个源改变本身的源传输地址,必须选择新的SSRC识别符,以避免被当作一个环路源。 (10)CSRC列表:0到15项,每项32比特,CSRC列表识别在此包中负载的所有贡献源。识别符的数目在CC域中给定。若有贡献源多于15个,仅识别15个。CSRC识别符由混合器插入,并列出所有贡献源的SSRC识别符。 2。RTP协议之Header扩展头结构解析 RTPHeader固定长度12字节,在一些情况下无法满足需要,需要扩展。在固定头中标识了是否有扩展字段相关信息。 如果RTP标准头部扩展(X)位为1,就表示CSRC后面还有一些额外的RTP扩展头,rfc5285对headerextension做了拓展,支持两种类型的拓展头OnebyteHeader和TwobyteHeader 图3扩展头 扩展头(ExtensionsHeader)所有信息都包含在CC中,可以得知扩展头长度:如CC4,ExtensionsHeadersize44(字节)432(bit)。 前4个字节来区分用何种类型扩展头definedbyprofile(占2个字节):〔OnebyteHeader标识0xBEDETwobyteHeader标识0x1000〕,length表示除去definedbyprofile和length字段之外的ExtensionsHeader长度说明(占2个字节); 图4OnebyteHeader 如上图4所示第一个16为固定为0XBEDE标志,意味着这是一个onebyte扩展,length3说明headerextension的总长度为332bit96bit12byte。 每个扩展头首先以一个byte开始,ID为标识,占4bit,后4bit是L的长度代表后面紧跟数据长度(此时数据长度为L1),比如L0时,紧跟后面有1个byte的data,同理第二个扩展头的L1说明后面还有2个byte的data,但是注意,其后没有紧跟第三个扩展头,而是添加了2个byte大小的全0的data,这是为了作填充对齐,因为扩展头是以为32bit作填充对齐的 图5TwobyteHeader 如上图5所示第一个16为固定为0X1000标志,意味着这是一个twobyte扩展,length3说明headerextension的总长度为332bit96bit12byte。 每个扩展头首先以一个byte开始,ID为标识,占8bit,后8bit是L的长度代表后面紧跟数据长度(此时数据长度为L,表示真实的长度),比如L0时,紧跟没有data,同理第二个扩展头的L1说明后面还有1个byte的data,但是注意,其后没有紧跟第三个扩展头,而是添加了1个byte大小的全0的data,这是为了作填充对齐,因为扩展头是以为32bit作填充对齐的 3。RTP协议之PlayloadPadding解析 注释:buffer为RtpPacket数据,size为RtpPacket数据长度,payloadoffset为RtpPacket数据真正载荷的偏移量,cc为固定头中字段CSRC计数(CC)。 一段RtpPacket数据包由RtpHeaderRtpBody组成; RtpHeader由FixHeaderExtensionsHeader组成; RtpBody由PlayloadPadding组成; 在FixHeader中标识了是否有填充数据字段填充(P);若为1,则有填充字段;如何计算填充数据长度?在RtpPacket包最后一位标记了填充数据长度。注意填充数据长度也包含RtpPacket包最后一位。 if(P) paddingsizebuffer〔size1〕; else paddingsize0; Playload是RtpPacket数据所承载的真实数据,长度为: payloadoffsetFixedHeaderSizecc4; payloadsizesizepayloadoffsetpaddingsize; 4。RTP实例演示 图6wirsharkRtpPacket 如上图6所示,抓取wirshark获取的rtp包,从中可以看到rtp固定头信息和扩展头信息。截取一段RTP包的buffer数据分析如下: 9060027c00135150000311a6bede000151027c007c85b80000081063 90是VPXCC,把90换成二进制10000000 V是10;P是0;X是1;CC是0000(这个地方有误); 60是MPT,把60换成二进制01100000 M是0;PT是1100000; 027e是SequenceNum; 00135150是Timestamp; 000311a6是SSRC; bede是扩展头definedbyprofile(OnebyteHeader标识); 0001是length字段,说明有一个扩展字段; 51是扩展字段标识和长度,把51换成二进制01010001; 标识是5; 长度是1,其真实长度是112; 027c是扩展字段内容; 00是填充字段,要保证4的倍数; 5。RTP代码解析 此段代码是对RtpPacket的解析,代码中进行了相关注释!!! 请继续关注本人系列作品!欢迎讨论!!!