RTPRTCP实时传输协议实现课程设计.docx
- 文档编号:8001496
- 上传时间:2023-01-27
- 格式:DOCX
- 页数:16
- 大小:25.07KB
RTPRTCP实时传输协议实现课程设计.docx
《RTPRTCP实时传输协议实现课程设计.docx》由会员分享,可在线阅读,更多相关《RTPRTCP实时传输协议实现课程设计.docx(16页珍藏版)》请在冰豆网上搜索。
RTPRTCP实时传输协议实现课程设计
RTP-RTCP实时传输协议实现
一、设计目的和意义
了解实时传输协议RTP和实时传输控制协议RTCP的基本原理;学习使用RTP数据报发送实时数据,并接收重组;学习实时数据传输控制基本方法;了解媒体内同步和媒体间同步的基本概念。
二、设计原理
1、基本概念
RTP全名是Real-timeTransportProtocol(实时传输协议)。
RTCP全名是Real-timeTransportControlProtocol,即实时传输控制协议。
RTP定义在RFC1889中,是一种提供端对端传输服务的实时传输协议,用来支持网络服务中传输实时数据。
RTCP用来监视服务质量和传送有关与会者的信息,主要功能是为应用程序提供会话质量或者广播性能质量的信息。
多媒体网络通常把RTCP和RTP一起使用。
RTP用来为IP网上的语音、图像、传真等多种需要实时传输的多媒体数据提供端到端的实时传输服务。
RTP的典型应用建立在UDP上,但也可以在TCP或ATM等其他协议之上工作。
RTP为Internet上端到端的实时传输提供时间信息和流同步,但并不保证服务质量,服务质量由RTCP来提供。
RTCP负责管理传输质量在当前应用进程之间交换控制信息。
在RTP会话期间,各参与者周期性地传送RTCP包,包中含有已发送的数据包的数量、丢失的数据包的数量等统计资料,因此,服务器可以利用这些信息动态地改变传输速率,甚至改变有效载荷类型。
RTP和RTCP配合使用,能以有效的反馈和最小的开销使传输效率最佳化,故特别适合传送网上的实时数据。
2、RTP工作机制
威胁多媒体数据传输的一个尖锐的问题就是不可预料数据到达时间。
但是流媒体的传输是需要数据的适时的到达用以播放和回放。
RTP协议就是提供了时间标签,序列号以及其它的结构用于控制适时数据的流放。
在流的概念中”时间标签”是最重要的信息。
发送端依照即时的采样在数据包里隐蔽的设置了时间标签。
在接受端收到数据包后,就依照时间标签按照正确的速率恢复成原始的适时的数据。
不同的媒体格式调时属性是不一样的。
但是RTP本身并不负责同步,RTP只是传输层协议,为了简化运输层处理,提高该层的效率。
将部分运输层协议功能(比如流量控制)上移到应用层完成。
同步就是属于应用层协议完成的。
它没有运输层协议的完整功能,不提供任何机制来保证实时地传输数据,不支持资源预留,也不保证服务质量。
RTP报文甚至不包括长度和报文边界的描述。
同时RTP协议的数据报文和控制报文的使用相邻的不同端口,这样大大提高了协议的灵活性和处理的简单性。
RTP协议和UDP二者共同完成运输层协议功能。
UDP协议只是传输数据包,不管数据包传输的时间顺序。
RTP的协议数据单元是用UDP分组来承载的。
在承载RTP数据包的时候,有时候一帧数据被分割成几个包具有相同的时间标签,则可以知道时间标签并不是必须的。
而UDP的多路复用让RTP协议利用支持显式的多点投递,可以满足多媒体会话的需求。
RTP协议虽然是传输层协议但是它没有作为OSI体系结构中单独的一层来实现。
RTP协议通常根据一个具体的应用来提供服务,RTP只提供协议框架,开发者可以根据应用的具体要求对协议进行充分的扩展。
3、RTCP工作机制
当应用程序开始一个RTP会话时将使用两个端口:
一个给RTP,一个给RTCP。
RTP本身并不能为按顺序传送数据包提供可靠的传送机制,也不提供流量控制或拥塞控制,它依靠RTCP提供这些服务。
在RTP的会话之间周期的发放一些RTCP包以用来传监听服务质量和交换会话用户信息等功能。
RTCP包中含有已发送的数据包的数量、丢失的数据包的数量等统计资料。
因此,服务器可以利用这些信息动态地改变传输速率,甚至改变有效载荷类型。
RTP和RTCP配合使用,它们能以有效的反馈和最小的开销使传输效率最佳化,因而特别适合传送网上的实时数据。
根据用户间的数据传输反馈信息,可以制定流量控制的策略,而会话用户信息的交互,可以制定会话控制的策略。
RTCP主要有4个功能:
用反馈信息的方法来提供分配数据的传送质量,这种反馈可以用来进行流量的拥塞控制,也可以用来监视网络和用来诊断网络中的问题;为RTP源提供一个永久性的CNAME(规范性名字)的传送层标志,因为在发现冲突或者程序更新重启时SSRC(同步源标识)会变,需要一个运作痕迹,在一组相关的会话中接收方也要用CNAME来从一个指定的与会者得到相联系的数据流(如音频和视频);根据与会者的数量来调整RTCP包的发送率;传送会话控制信息,如可在用户接口显示与会者的标识,这是可选功能。
4、RTP的协议层次
RTP(实时传输协议),顾名思义它是用来提供实时传输的,因而可以看成是传输层的一个子层。
RTP被划分在传输层,它建立在UDP上。
同UDP协议一样,为了实现其实时传输功能,RTP也有固定的封装形式。
RTP用来为端到端的实时传输提供时间信息和流同步,但并不保证服务质量。
服务质量由RTCP来提供。
不少人也把RTP归为应用层的一部分,这是从应用开发者的角度来说的。
操作系统中的TCP/IP等协议栈所提供的是我们最常用的服务,而RTP的实现还是要靠开发者自己。
因此从开发的角度来说,RTP的实现和应用层协议的实现没不同,所以可将RTP看成应用层协议。
5、RTP的会话过程
当应用程序建立一个RTP会话时,应用程序将确定一对目的传输地址。
目的传输地址由一个网络地址和一对端口组成,有两个端口:
一个给RTP包,一个给RTCP包,使得RTP/RTCP数据能够正确发送。
RTP数据发向偶数的UDP端口,而对应的控制信号RTCP数据发向相邻的奇数UDP端口(偶数的UDP端口+1),这样就构成一个UDP端口对。
RTP的发送过程如下,接收过程则相反。
1)RTP协议从上层接收流媒体信息码流(如H.263),封装成RTP数据包;RTCP从上层接收控制信息,封装成RTCP控制包。
2)RTP将RTP数据包发往UDP端口对中偶数端口;RTCP将RTCP控制包发往UDP端口对中的接收端口。
6、RTP的封装
一个协议的封装是为了满足协议的功能需求的。
从前面提出的功能需求,可以推测出RTP封装中应该有同步源和时戳等字段,但更为完整的封装是什么样子呢?
请看图1。
VPXCCMPT序列号时戳同步信源(SSRC)标识符特约信源(CSRC)标识符图1RTP的头部格式
版本号(V):
2比特,用来标志使用的RTP版本。
填充位(P):
1比特,如果该位置位,则该RTP包的尾部就包含附加的填充字节。
扩展位(X):
1比特,如果该位置位的话,RTP固定头部后面就跟有一个扩展头部。
CSRC计数器(CC):
4比特,含有固定头部后面跟着的CSRC的数目。
标记位(M):
1比特,该位的解释由配置文档(Profile)来承担.
载荷类型(PT):
7比特,标识了RTP载荷的类型。
序列号(SN):
16比特,发送方在每发送完一个RTP包后就将该域的值增加1,接收方可以由该域检测包的丢失及恢复包序列。
序列号的初始值是随机的。
时间戳:
32比特,记录了该包中数据的第一个字节的采样时刻。
在一次会话开始时,时间戳初始化成一个初始值。
即使在没有信号发送时,时间戳的数值也要随时间而不断地增加(时间在流逝嘛)。
时间戳是去除抖动和实现同步不可缺少的。
同步源标识符(SSRC):
32比特,同步源就是指RTP包流的来源。
在同一个RTP会话中不能有两个相同的SSRC值。
该标识符是随机选取的RFC1889推荐了MD5随机算法。
贡献源列表(CSRCList):
0~15项,每项32比特,用来标志对一个RTP混合器产生的新包有贡献的所有RTP包的源。
由混合器将这些有贡献的SSRC标识符插入表中。
SSRC标识符都被列出来,以便接收端能正确指出交谈双方的身份。
7、RTCP的封装
RTCP的主要功能是:
服务质量的监视与反馈、媒体间的同步,以及多播组中成员的标识。
在RTP会话期间,各参与者周期性地传送RTCP包。
RTCP包中含有已发送的数据包的数量、丢失的数据包的数量等统计资料,因此,各参与者可以利用这些信息动态地改变传输速率,甚至改变有效载荷类型。
RTP和RTCP配合使用,它们能以有效的反馈和最小的开销使传输效率最佳化,因而特别适合传送网上的实时数据。
RTCP也是用UDP来传送的,但RTCP封装的仅仅是一些控制信息,因而分组很短,所以可以将多个RTCP分组封装在一个UDP包中。
RTCP有如下五种分组。
表1RTCP的5种分组类型
类型缩写表示用途200SR(SenderReport)发送端报告201RR(ReceiverReport)接收端报告202SDES(SourceDescriptionItems)源点描述203BYE结束传输204APP特定应用
8、RTP协议传输数据流的收发程序流程图
发送接收
获得接收端的IP地址和端口号获得用户指定的端口号
创建RTP会话创建RTP会话
指定RTP数据接收端设置接收模式
设置RTP会话默认参数接受RTP数据
发送流媒体数据检索RTP数据源
获取RTP数据报
删除RTP数据报
图3RTP协议传输数据流的收发程序流程图
三、详细设计步骤
1、环境搭建
通过RTP协议传输数据流的收发程序,进行实时流媒体数据传输,需要使用JRTPLIB。
JRTPLIB是一个用C++语言实现的RTP库,目前已经可以运行在Windows、Linux、FreeBSD、Solaris、Unix和VxWorks等多种操作系统上。
先要将JRTPLIB库在windows系统下进行编译,之后编译的RTP协议传输数据流的收发源程序,就可运行了。
2、初始化
在使用JRTPLIB进行实时流媒体数据传输之前,首先应该生成RTPSession类的一个实例来表示此次RTP会话,然后调用Create()方法来对其进行初始化操作。
RTPSession类的Create()方法只有一个参数,用来指明此次RTP会话所采用的端口号。
3、数据发送
当RTP会话成功建立起来之后,接下来就可以开始进行流媒体数据的实时传输了。
首先需要设置好数据发送的目标地址,RTP协议允许同一会话存在多个目标地址,这可以通过调用RTPSession类的AddDestination()、DeleteDestination()和ClearDestinations()方法来完成。
目标地址全部指定之后,接着就可以调用RTPSession类的SendPacket()方法,向所有的目标地址发送流媒体数据。
SendPacket()最典型的用法是类似于下面的语句,其中第一个参数是要被发送的数据,而第二个参数则指明将要发送数据的长度,再往后依次是RTP负载类型、标识和时戳增量。
例如:
sess.SendPacket(buffer,5,0,false,10);
对于同一个RTP会话来讲,负载类型、标识和时戳增量通常来讲都是相同的,JRTPLIB允许将它们设置为会话的默认参数,这是通过调用RTPSession类的SetDefaultPayloadType()、SetDefaultMark()等方法来完成的。
为RTP会话设置这些默认参数的好处是可以简化数据的发送。
例如,如果为RTP会话设置了默认参数:
sess.SetDefaultPayloadType(0);
sess.SetDefaultMark(false);
sess.SetDefaultTimeStampIncrement(10);
之后在进行数据发送时只需指明要发送的数据及其长度就可以了。
例如:
sess.SendPacket(buffer,5);
4、数据接收
对于流媒体数据的接收端,首先需要调用PollData()方法来接收发送过来的RTP或者RTCP数据报。
由于同一个RTP会话中允许有多个参与者(源),因此既可以通过调用GotoFirstSource()和GotoNextSource()方法来遍历所有的源,也可以通过调用GotoFisstSourceWithDat()和GotoNextSourceWithData()方法来遍历那些携带有数据的源。
在从RTP会话中检测出有效的数据源之后,接下去就可以调用RTPSession类的GetNextPacket()方法从中抽取RTP数据报,当接收到的RTP数据报处理完之后,要及时释放。
下面的代码示范了该如何对接收到的RTP数据报进行处理:
do{
sess.BeginDataAccess();
if(sess.GotoFirstSourceWithData())
{
do
{
RTPPacket*pack;
uint8_t*data;
size_tlength;
if((outfile=open("/mnt/hgfs/download/temp1.YUV",O_WRONLY|O_CREAT|O_APPEND))<0)
{
perror("openoutfileerror");
return-1;
}
while((pack=sess.GetNextPacket())!
=NULL)
{
data=pack->GetPayloadData();
length=pack->GetPayloadLength();
if((write(outfile,data,length))<0)//将接收到的图片信息写入文中。
{
perror("writeoutfileerror;");
return-1;
}
sess.DeletePacket(pack);
}
}while(sess.GotoNextSourceWithData());
}
sess.EndDataAccess();
close(outfile);
JRTPLIB为RTP数据报定义了3种接收模块,通过调用RTPSession类的SetReceiveMode()方法可以设置下列这些接收模式:
RECEIVEMODE_ALL:
缺省的接收模式,所有到达的RTP数据报都将被接受;
RECEIVEMODE_IGNORESOME:
除了某些特定的发送者之外,所有到达的RTP数据报都将被接受,而被拒绝的发送者列表可以通过调用AddToIgnoreList(),DeleteFromIgnoreList()和ClearIgnoreList()方法来进行设置;
RECEIVEMODE_ACCEPTSOME:
除了某些特定的发送者之外,所有到达的RTP数据报都将被拒绝,而被接受的发送者列表可以通过调用AddToAcceptList(),DeleteFromAcceptList和ClearAcceptList()方法来进行设置。
四、设计结果及分析
1、网络实时传输协议的测试程序rtpclient.cpp
rtpclient.pp的功能是在同一个端口收发数据包,所以它不仅能把数据包发送出去,还能收到发送的数据包并解析出数据包中的内容。
程序如下:
//rtpclient.pp
#pragmacomment(lib,"jrtplib.lib")
#pragmacomment(lib,"jthread.lib")
#pragmacomment(lib,"WS2_32.lib")
#include"header/rtpsession.h"
#include"header/rtppacket.h"
#include"header/rtpudpv4transmitter.h"
#include"header/rtpipv4address.h"
#include"header/rtpsessionparams.h"
#include"header/rtperrors.h"
#ifndefWIN32
#include
#include
#else
#include
#endif//WIN32
#include
#include
#include
#include
voidcheckerror(intrtperr)
{
if(rtperr<0)
{
std:
:
cout<<"ERROR:
"< : endl; exit(-1); } } intmain(void) { #ifdefWIN32 WSADATAdat; WSAStartup(MAKEWORD(2,2),&dat); #endif//WIN32 RTPSessionsess; uint16_tportbase,destport; uint32_tdestip; std: : stringipstr; intstatus,i,num; BYTE*pBuffer; BYTE*pfBuffer; std: : cout<<"Enterlocalportbase: "< : endl; std: : cin>>portbase; std: : cout< : endl; std: : cout<<"EnterthedestinationIPaddress"< : endl; std: : cin>>ipstr; destip=inet_addr(ipstr.c_str()); if(destip==INADDR_NONE) { std: : cerr<<"BadIPaddressspecified"< : endl; return-1; } destip=ntohl(destip); std: : cout<<"Enterthedestinationport"< : endl; std: : cin>>destport; std: : cout< : endl; std: : cout<<"Numberofpacketsyouwishtobesent: "< : endl; std: : cin>>num; RTPUDPv4TransmissionParamstransparams; RTPSessionParamssessparams; sessparams.SetOwnTimestampUnit(1.0/10.0); sessparams.SetAcceptOwnPackets(true); transparams.SetPortbase(portbase); status=sess.Create(sessparams,&transparams); checkerror(status); RTPIPv4Addressaddr(destip,destport); status=sess.AddDestination(addr); checkerror(status); for(i=1;i<=num;i++) { printf("\nSendingpacket%d/%d\n",i,num); //发送数据1234567890 status=sess.SendPacket((void*)"1234567890",10,0,false,10); checkerror(status); sess.BeginDataAccess(); //检查发送过来的数据包 if(sess.GotoFirstSourceWithData()) { do { RTPPacket*pack; while((pack=sess.GetNextPacket())! =NULL) { printf("Gotpacket! \n"); std: : cout<<"Gotpacketwith" <<"extendedsequencenumber" < <<"fromSSRC"< < : endl; intdataLength=pack->GetPayloadLength(); pfBuffer=(unsignedchar*)pack->GetPayloadData(); pBuffer=newBYTE[dataLength+1]; memcpy(pBuffer,pfBuffer,dataLength); pBuffer[dataLength]=0; std: : cout< : endl; sess.DeletePacket(pack); } }while(sess.GotoNextSourceWithData()); } sess.EndDataAccess(); #ifndefRTP_SUPPORT_THREAD status=sess.Poll(); checkerror(status); #endif//RTP_SUPPORT_THREAD RTPTime: : Wait(RTPTime(1,0)); } sess.BYEDestroy(RTPTime(10,0),0,0); #ifdefWIN32 WSACleanup(); #endif//WIN32 return0; } 执行测试程序的效果如下: Enterlocalportbase: 8000 EnterthedestinationIPaddress 127.0.0.1 Enterthedestinationport 8000 Numberofpacketsyouwishtobesent: 4 Sendingpacket1/4 Gotpacket! Gotpacketwithextendedsequencenumber36214fromSSRC2242452064 1234567890 Sendingpacket2/4 Gotpacket! Gotpacketwithextendedsequencenumber36215fromSSR
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- RTPRTCP 实时 传输 协议 实现 课程设计