RTPRTCP实时传输协议实现课程设计_第1页
RTPRTCP实时传输协议实现课程设计_第2页
RTPRTCP实时传输协议实现课程设计_第3页
RTPRTCP实时传输协议实现课程设计_第4页
RTPRTCP实时传输协议实现课程设计_第5页
已阅读5页,还剩8页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、RTP-RTCP实时传输协议实现课程设计 RTP-RTCP实时传输协议实现一、 设计目的和意义了解实时传输协议RTP和实时传输控制协议RTCP的基本原理;学习使用RTP数据报发送实时数据,并接收重组;学习实时数据传输控制基本方法;了解媒体内同步和媒体间同步的基本概念。二、 设计原理1、基本概念RTP全名是Real-time Transport Protocol(实时传输协议)。RTCP全名是Real-time Transport Control Protocol,即实时传输控制协议。RTP定义在RFC 1889中,是一种提供端对端传输服务的实时传输协议,用来支持网络服务中传输实时数据。RTCP

2、用来监视服务质量和传送有关与会者的信息,主要功能是为应用程序提供会话质量或者广播性能质量的信息。多媒体网络通常把RTCP和RTP一起使用。RTP用来为IP网上的语音、图像、传真等多种需要实时传输的多媒体数据提供端到端的实时传输服务。RTP的典型应用建立在UDP上,但也可以在TCP或ATM等其他协议之上工作。RTP为Internet上端到端的实时传输提供时间信息和流同步,但并不保证服务质量,服务质量由RTCP来提供。RTCP负责管理传输质量在当前应用进程之间交换控制信息。在RTP会话期间,各参与者周期性地传送RTCP包,包中含有已发送的数据包的数量、丢失的数据包的数量等统计资料,因此,服务器可以

3、利用这些信息动态地改变传输速率,甚至改变有效载荷类型。RTP和RTCP配合使用,能以有效的反馈和最小的开销使传输效率最佳化,故特别适合传送网上的实时数据。2、RTP工作机制威胁多媒体数据传输的一个尖锐的问题就是不可预料数据到达时间。但是流媒体的传输是需要数据的适时的到达用以播放和回放。RTP协议就是提供了时间标签,序列号以及其它的结构用于控制适时数据的流放。在流的概念中”时间标签”是最重要的信息。发送端依照即时的采样在数据包里隐蔽的设置了时间标签。在接受端收到数据包后,就依照时间标签按照正确的速率恢复成原始的适时的数据。不同的媒体格式调时属性是不一样的。但是RTP本身并不负责同步,RTP只是传

4、输层协议,为了简化运输层处理,提高该层的效率。将部分运输层协议功能(比如流量控制)上移到应用层完成。同步就是属于应用层协议完成的。它没有运输层协议的完整功能,不提供任何机制来保证实时地传输数据,不支持资源预留,也不保证服务质量。RTP报文甚至不包括长度和报文边界的描述。同时RTP协议的数据报文和控制报文的使用相邻的不同端口,这样大大提高了协议的灵活性和处理的简单性。RTP协议和UDP二者共同完成运输层协议功能。UDP协议只是传 输数据包,不管数据包传输的时间顺序。RTP的协议数据单元是用UDP分组来承载的。在承载RTP数据包的时候,有时候一帧数据被分割成几个包具有相同的时间标签,则可以知道时间

5、标签并不是必须的。而UDP的多路复用让RTP协议利用支持显式的多点投递,可以满足多媒体会话的需求。RTP协议虽然是传输层协议但是它没有作为OSI体系结构中单独的一层来实现。RTP协议通常根据一个具体的应用来提供服务,RTP只提供协议框架,开发者可以根据应用的具体要求对协议进行充分的扩展。3、RTCP工作机制当应用程序开始一个RTP会话时将使用两个端口:一个给RTP,一个给RTCP。RTP本身并不能为按顺序传送数据包提供可靠的传送机制,也不提供流量控制或拥塞控制,它依靠RTCP提供这些服务。在RTP的会话之间周期的发放一些RTCP包以用来传监听服务质量和交换会话用户信息等功能。RTCP包中含有已

6、发送的数据包的数量、丢失的数据包的数量等统计资料。因此,服务器可以利用这些信息动态地改变传输速率,甚至改变有效载荷类型。RTP和RTCP配合使用,它们能以有效的反馈和最小的开销使传输效率最佳化,因而特别适合传送网上的实时数据。根据用户间的数据传输反馈信息,可以制定流量控制的策略,而会话用户信息的交互,可以制定会话控制的策略。RTCP主要有4个功能:用反馈信息的方法来提供分配数据的传送质量,这种反馈可以用来进行流量的拥塞控制,也可以用来监视网络和用来诊断网络中的问题;为RTP源提供一个永久性的CNAME(规范性名字)的传送层标志,因为在发现冲突或者程序更新重启时SSRC(同步源标识)会变,需要一

7、个运作痕迹,在一组相关的会话中接收方也要用CNAME来从一个指定的与会者得到相联系的数据流(如音频和视频);根据与会者的数量来调整RTCP包的发送率;传送会话控制信息,如可在用户接口显示与会者的标识,这是可选功能。4、RTP的协议层次RTP(实时传输协议),顾名思义它是用来提供实时传输的,因而可以看成是传输层的一个子层。RTP被划分在传输层,它建立在UDP上。同UDP协议一样,为了实现其实时传输功能,RTP也有固定的封装形式。RTP用来为端到端的实时传输提供时间信息和流同步,但并不保证服务质量。服务质量由RTCP来提供。不少人也把RTP归为应用层的一部分,这是从应用开发者的角度来说的。操作系统

8、中的TCP/IP等协议栈所提供的是我们最常用的服务,而RTP的实现还是要靠开发者自己。因此从开发的角度来说,RTP的实现和应用层协议的实现没不同 ,所以可将RTP看成应用层协议。5、RTP的会话过程当应用程序建立一个RTP会话时,应用程序将确定一对目的传输地址。目的传输地址由一个网络地址和一对端口组成,有两个端口:一个给RTP包,一个给RTCP包,使得RTP/RTCP数据能够正确发送。RTP数据发向偶数的UDP端口,而对应的控制信号RTCP数据发向相邻的奇数UDP端口(偶数的UDP端口1),这样就构成一个UDP端口对。 RTP的发送过程如下,接收过程则相反。1)RTP协议从上层接收流媒体信息码

9、流(如H.263),封装成RTP数据包;RTCP从上层接收控制信息,封装成RTCP控制包。2)RTP将RTP 数据包发往UDP端口对中偶数端口;RTCP将RTCP控制包发往UDP端口对中的接收端口。6、RTP的封装一个协议的封装是为了满足协议的功能需求的。从前面提出的功能需求,可以推测出RTP封装中应该有同步源和时戳等字段,但更为完整的封装是什么样子呢?请看图1。VPXCCMPT序列号时戳同步信源(SSRC)标识符特约信源(CSRC)标识符图 1 RTP的头部格式版本号(V):2比特,用来标志使用的RTP版本。填充位(P):1比特,如果该位置位,则该RTP包的尾部就包含附加的填充字节。扩展位(

10、X):1比特,如果该位置位的话,RTP固定头部后面就跟有一个扩展头部。CSRC计数器(CC):4比特,含有固定头部后面跟着的CSRC的数目。标记位(M):1比特,该位的解释由配置文档(Profile)来承担. 载荷类型(PT):7比特,标识了RTP载荷的类型。序列号(SN):16比特,发送方在每发送完一个RTP包后就将该域的值增加1,接收方可以由该域检测包的丢失及恢复包序列。序列号的初始值是随机的。时间戳:32比特,记录了该包中数据的第一个字节的采样时刻。在一次会话开始时,时间戳初始化成一个初始值。即使在没有信号发送时,时间戳的数值也要随时间而不断地增加(时间在流逝嘛)。时间戳是去除抖动和实现

11、同步不可缺少的。同步源标识符(SSRC):32比特,同步源就是指RTP包流的来源。在同一个RTP会话中不能有两个相同的SSRC值。该标识符是随机选取的 RFC1889推荐了MD5随机算法。贡献源列表(CSRC List):015项,每项32比特,用来标志对一个RTP混合器产生的新包有贡献的所有RTP包的源。由混合器将这些有贡献的SSRC标识符插入表中。SSRC标识符都被列出来,以便接收端能正确指出交谈双方的身份。7、 RTCP的封装RTCP的主要功能是:服务质量的监视与反馈、媒体间的同步,以及多播组中成员的标识。在RTP会话期 间,各 参与者周期性地传送RTCP包。RTCP包中含有已发送的数据

12、包的数量、丢失的数据包的数量等统计资料,因此,各参与者可以利用这些信息动态地改变传输速率,甚至改变有效载荷类型。RTP和RTCP配合使用,它们能以有效的反馈和最小的开销使传输效率最佳化,因而特别适合传送网上的实时数据。RTCP也是用UDP来传送的,但RTCP封装的仅仅是一些控制信息,因而分组很短,所以可以将多个RTCP分组封装在一个UDP包中。RTCP有如下五种分组。表 1 RTCP的5种分组类型类型缩写表示用途200SR(Sender Report)发送端报告201RR(Receiver Report)接收端报告202SDES(Source Description Items)源点描述203

13、BYE结束传输204APP特定应用8、RTP协议传输数据流的收发程序流程图发送 接收获得接收端的 IP 地址和端口号 获得用户指定的端口号创建 RTP 会话 创建RTP会话指定 RTP 数据接收端 设置接收模式设置 RTP 会话 默认参数 接受RTP数据发送流媒体数据 检索RTP数据源获取RTP数据报删除RTP数据报图3 RTP协议传输数据流的收发程序流程图三、 详细设计步骤1、 环境搭建通过RTP协议传输数据流的收发程序,进行实时流媒体数据传输,需要使用 JRTPLIB。JRTPLIB是一个用C+语言实现的RTP库,目前已经可以运行在Windows、Linux、FreeBSD、Solaris

14、、Unix和 VxWorks等多种操作系统上。先要将JRTPLIB库在windows系统下进行编译,之后编译的RTP协议传输数据流的收发源程序,就可运行了。2、 初始化在使用JRTPLIB进行实时流媒体数据传输之前,首先应该生成RTPSession类的一个实例来表示此次RTP会话,然后调用Create()方法来对其进行初始化操作。RTPSession类的Create()方法只有一个参数,用来指明此次RTP会话所采用的端口号。3、 数据发送当RTP会话成功建立起来之后,接下来就可以开始进行流媒体数据的实时传输了。首先需要设置好数据发送的目标地址,RTP协议允许同一会话存在多个目标地址,这可以通过

15、调用RTPSession类的AddDestination()、DeleteDestination()和ClearDestinations()方法来完成。目标地址全部指定之后,接着就可以调用RTPSession类的SendPacket()方法,向所有的目标地址发送流媒体数据。SendPacket()最典型的用法是类似于下面的语句,其中第一个参数是要被发送的数据,而第二个参数则指明将要发送数据的长度,再往后依次是RTP负载类型、标识和时戳增量。例如:sess.SendPacket(buffer, 5, 0, false, 10); 对于同一个RTP会话来讲,负载类型、标识和时戳增量通常来讲都是相同

16、的,JRTPLIB允许将它们设置为会话的默认参数,这是通过调用 RTPSession类的SetDefaultPayloadType()、SetDefaultMark()等方法来完成的。为RTP会话设置这些默认参数的好处是可以简化数据的发送。例如,如果为 RTP会话设置了默认参数:sess.SetDefaultPayloadType(0);sess.SetDefaultMark(false);sess.SetDefaultTimeStampIncrement(10);之后在进行数据发送时只需指明要发送的数据及其长度就可以了。例如:sess.SendPacket(buffer, 5);4、 数据接

17、收对于流媒体数据的接收端,首先需要调用PollData()方法来接收发送过来的RTP或者RTCP数据报。由于同一个RTP会话中允许有多个参与者(源),因此既可以通过调用GotoFirstSource()和GotoNextSource()方法来遍历所有的源,也可以通过调用GotoFisstSourceWithDat()和GotoNextSourceWithData()方法来遍历那些携带有数据的源。在从RTP会话中检测出有效的数据源之后,接下去就可以调用RTPSession类的GetNextPacket()方法从中抽取RTP数据报,当接收到的RTP数据报处理完之后,要及时释放。下面的代码示范了该如

18、何对接收到的RTP数据报进行处理:dosess.BeginDataAccess();if (sess.GotoFirstSourceWithData()doRTPPacket *pack;uint8_t *data;size_t length;if(outfile=open(/mnt/hgfs/download/temp1.YUV,O_WRONLY | O_CREAT | O_APPEND)GetPayloadData();length=pack-GetPayloadLength();if(write(outfile,data,length)0)/将接收到的图片信息写入文中。perror(wr

19、ite outfile error;);return -1;sess.DeletePacket(pack); while (sess.GotoNextSourceWithData();sess.EndDataAccess();close(outfile);JRTPLIB为RTP数据报定义了3种接收模块,通过调用RTPSession类的SetReceiveMode()方法可以设置下列这些接收模式: RECEIVEMODE_ALL:缺省的接收模式,所有到达的RTP数据报都将被接受;RECEIVEMODE_IGNORESOME:除了某些特定的发送者之外,所有到达的RTP数据报都将被接受,而被拒绝的发

20、送者列表可以通过调用AddToIgnoreList(),DeleteFromIgnoreList()和ClearIgnoreList()方法来进行设置; RECEIVEMODE_ACCEPTSOME:除了某些特定的发送者之外,所有到达的RTP数据报都将被拒绝,而被接受的发送者列表可以通过调用AddToAcceptList(),DeleteFromAcceptList和ClearAcceptList()方法来进行设置。四、 设计结果及分析1、 网络实时传输协议的测试程序rtpclient.cpprtpclient.pp的功能是在同一个端口收发数据包,所以它不仅能把数据包发送出去,还能收到发送的数

21、据包 并解析出数据包中的内容。程序如下:/ rtpclient.pp#pragma comment(lib, jrtplib.lib)#pragma comment(lib, jthread.lib)#pragma comment(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 h

22、eader/rtperrors.h#ifndef WIN32#include #include #else#include #endif / WIN32#include #include #include #include void checkerror(int rtperr)if (rtperr 0)std:cout ERROR: RTPGetErrorString(rtperr) std:endl;exit(-1);int main(void)#ifdef WIN32WSADATA dat;WSAStartup(MAKEWORD(2,2),&dat);#endif / WIN32RTPSe

23、ssion sess;uint16_t portbase,destport;uint32_t destip;std:string ipstr;int status,i,num;BYTE *pBuffer;BYTE *pfBuffer;std:cout Enter local portbase: portbase;std:cout std:endl;std:cout Enter the destination IP address ipstr;destip = inet_addr(ipstr.c_str();if (destip = INADDR_NONE)std:cerr Bad IP add

24、ress specified std:endl;return -1;destip = ntohl(destip);std:cout Enter the destination port destport;std:cout std:endl;std:cout Number of packets you wish to be sent: num;RTPUDPv4TransmissionParams transparams;RTPSessionParams sessparams;sessparams.SetOwnTimestampUnit(1.0/10.0);sessparams.SetAccept

25、OwnPackets(true);transparams.SetPortbase(portbase);status = sess.Create(sessparams,&transparams);checkerror(status);RTPIPv4Address addr(destip,destport);status = sess.AddDestination(addr);checkerror(status);for (i = 1 ; i = num ; i+)printf(nSending packet %d/%dn,i,num);/ 发送数据1234567890status = sess.

26、SendPacket(void *)1234567890,10,0,false,10);checkerror(status);sess.BeginDataAccess();/ 检查发送过来的数据包if (sess.GotoFirstSourceWithData()doRTPPacket *pack;while (pack = sess.GetNextPacket() != NULL)printf(Got packet !n);std:cout Got packet with extended sequence number GetExtendedSequenceNumber() from SS

27、RC GetSSRC() GetPayloadLength();pfBuffer =(unsigned char*)pack-GetPayloadData();pBuffer = new BYTEdataLength + 1;memcpy(pBuffer, pfBuffer, dataLength);pBufferdataLength = 0;std:cout pBuffer std:endl;sess.DeletePacket(pack); while (sess.GotoNextSourceWithData();sess.EndDataAccess();#ifndef RTP_SUPPOR

28、T_THREADstatus = sess.Poll();checkerror(status);#endif / RTP_SUPPORT_THREADRTPTime:Wait(RTPTime(1,0);sess.BYEDestroy(RTPTime(10,0),0,0);#ifdef WIN32WSACleanup();#endif / WIN32return 0;执行测试程序的效果如下:Enter local portbase:8000Enter the destination IP addressEnter the destination port8000Number of packets

29、 you wish to be sent:4Sending packet 1/4Got packet !Got packet with extended sequence number 36214 from SSRC 22424520641234567890Sending packet 2/4Got packet !Got packet with extended sequence number 36215 from SSRC 22424520641234567890Sending packet 3/4Got packet !Got packet with extended sequence

30、number 36216 from SSRC 22424520641234567890Sending packet 4/4Press any key to continue上面执行的意思是程序自己开了8000端口,然后往自己的8000发送,所以不仅发送出去,还收到并解析出了内容。如果要往另外机器上发,另一个机器上也运行这个程序就可以了。2、通过RTP协议传输数据流的收发程序,以字符串模拟数据流。发送程序如下:/sender.cpp#include #include #include rtpsession.h/ 错误处理函数void checkerror(int err)if (err 0) c

31、har* errstr = RTPGetErrorString(err);printf(Error:%sn, errstr);exit(-1);int main(int argc, char* argv)RTPSession sess;unsigned long destip;int destport;int portbase = 6000;int status, index;char buffer128;if (argc != 3) printf(Usage: ./sender destip destportn);return -1;/ 获得接收端的IP地址和端口号destip = inet

32、_addr(argv1);if (destip = INADDR_NONE) printf(Bad IP address specified.n);return -1;destip = ntohl(destip);destport = atoi(argv2);/ 创建RTP会话status = sess.Create(portbase);checkerror(status);/ 指定RTP数据接收端status = sess.AddDestination(destip, destport);checkerror(status);/ 设置RTP会话默认参数sess.SetDefaultPaylo

33、adType(0);sess.SetDefaultMark(false);sess.SetDefaultTimeStampIncrement(10);/ 发送流媒体数据index = 1;do sprintf(buffer, %d: RTP packet, index +);sess.SendPacket(buffer, strlen(buffer);printf(Send packet !n); while(1);return 0;接收程序如下:/receiver.cpp#include #include rtpsession.h#include &q uot;rtppacket.h/ 错误

34、处理函数void checkerror(int err)if (err 0) char* errstr = RTPGetErrorString(err);printf(Error:%sn, errstr);exit(-1);int main(int argc, char* argv)RTPSession sess;int localport;int status;if (argc != 2) printf(Usage: ./sender localportn);return -1;/ 获得用户指定的端口号localport = atoi(argv1);/ 创建RTP会话status = ses

35、s.Create(localport);checkerror(status);do / 接受RTP数据status = sess.PollData();/ 检索RTP数据源if (sess.GotoFirstSourceWithData() do RTPPacket* packet;/ 获取RTP数据报while (packet = sess.GetNextPacket() != NULL) printf(Got packet !n);/ 删除RTP数据报delete packet; while (sess.GotoNextSourceWithData(); while(1);return 0

36、;发送程序sender.cpp,它负责向用户指定的IP地址和端口,不断地发送RTP数据包。接收程序receiver.cpp,它负责从指定的端口不断地读取RTP数据包。3、在调试程序中遇到的问题及出现问题的原因和解决办法(1)Cannot open include file: rtpsession.h: No such file ordirectory. 即找不到头文件 rtpsession.h。原因:是在VC+编译源程序的工作空间中没有包含rtpsession.h头文件。解决办法:我们把JRTPLIB中的所有头文件都放到headerrtpclient.cpp源码改一下#include rtpsession.h 改成#inclu文件夹中,再把header文件夹放到rtpclient.cpp所在的工作空间中。再把rtpclient.cpp源码改一下,#include rtpsession.h 改成#include header/rtpsession.h,同样的,把其它头文件包含的都改过来。(2)fd_set redefinition winsock2.h.原因:是因为winsock.h和winsock2.h中有重定义的部分。解决办法:在引用之前,加上预处理

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论