VC+6+RTP流媒体传输协议编程实例(jrtplib)
- 格式:doc
- 大小:48.00 KB
- 文档页数:6
⾃⼰动⼿写RTP服务器——⽤RTP协议传输TS流上⼀篇⽂章我们介绍了关于RTP协议的知识,那么我们现在就⾃⼰写⼀个简单的传输TS流媒体的RTP服务器吧。
预备知识关于TS流的格式:TS流封装的具体格式请参考⽂档ISO/IEC 13818-1。
这⾥我们只需要了解⼀些简单的信息就好。
⾸先TS流是有许多的TS Packet组成的,每个TS Packet的长度固定为188 bytes,每个packet都是以sync_byte:0x47开头。
MTU(Maximum Transmission Unit):最⼤传输单元。
是指⼀种通信协议的某⼀层上⾯所能通过的最⼤数据包⼤⼩(以字节为单位)。
最⼤传输单元这个参数通常与通信接⼝有关(⽹络接⼝卡、串⼝等)。
例如:以太⽹⽆法接收⼤于1500 字节的数据包。
参考代码下⾯我会把⾃⼰写的简单的代码贴出来,并且⼀步步地说明。
新建main.c⽂件,内容如下:[cpp]1. #include <stdio.h>2. #include <string.h>3. #include <sys/types.h>4. #include <sys/socket.h>5. #include <netinet/in.h>6.7. #define TS_PACKET_SIZE 1888. #define MTU 1500说明:包含⼀些必要的头⽂件,并且定义了TS Packet的长度(188 bytes),MTU的限制(1500 bytes)。
[cpp]1. struct rtp_header{2. unsigned char cc:4;3. unsigned char x:1;4. unsigned char p:1;5. unsigned char v:2;6.7. unsigned char pt:7;8. unsigned char m:1;9.10. unsigned short sequence_number;11. unsigned int timestamp;12. unsigned int ssrc;13. };14.15. void init_rtp_header(struct rtp_header *h){16. h->v = 2;17. h->p = 0;18. h->x = 0;19. h->cc = 0;20. h->m = 0;21. h->pt = 33;22. h->sequence_number = 123;23. h->timestamp = 123;24. h->ssrc = 123;25. }说明:这⾥定义了RTP Header的结构体,以及初始化的⽅法。
基于JRTPLIB库的rtp包的传输和接收学习2009-09-09 21:21转载:/blog/static/665146212008824112748499/基于JRTPLIB库的RTP数据传输设计文档RTP即实时传输协议,用于Internet上针对多媒体数据流的传输。
它通常使用UDP协议来传送数据,起初是为了“multicast”传输情况而设计的,目的是提供时间信息和保证流同步,不过现在也用于一对一的传输情况。
RTP协议主要完成对数据包进行编号,加盖时戳,丢包检查,安全与内容认证等工作。
通过这些工作,应用程序会利用RTP协议的数据信息保证流数据的同步和实时传输。
windows下vc6.0编译rtp库,过程如下:压缩包可以从这里获得:/upimg/soft/jrtplib-3.7.1.rar下载jrtplib-3.7.1.rar后,首先将其解压到一个临时文件夹中,然后开始后续工作。
首先需要强调的是,jrtplib是一个库而不是应用程序,编译后我们获得的是.lib文件。
这个文件是用来实现RTP协议的,意义和我们在写WIN32程序时用到的kernel.lib一样。
解压后的文件夹中包含两个目录,jrtplib-3.7.1和jthread-1.2.1,打开这两个目录后我们可以看到下面又有两个同名的目录,为了后面能顺利编译,我们把同名目录下的文件全部考到上一级目录中,就是说把f:\jrtplib-3.7.1\jrtplib-3.7.1\*.* 复制到f:\jrtplib-3.7.1\。
同理,把f:\jthread-1.2.1\jthread-1.2.1\*.* 复制到f:\jthread-1.2.1\完成上述步骤后我们就可以开始编译库文件了。
Windows平台下建议使用Visual C++6.0。
首先编译多线程库jthread,在vc6中直接打开工作区文件jthread.dsw,改变工程设置,选中source file下的文件,点右键选择setting,确保code generation下Use run-time library 为debug mulitithreaded DLL或debug mulitithreaded。
RTP协议详解实时传输协议的音视频数据传输机制实时传输协议(RTP)是一种专门用于音视频数据传输的协议。
它通过提供时间戳、序列号和同步源等机制,以确保音视频数据能够实时、有序、可靠地传输。
本文将详细讲解RTP协议的音视频数据传输机制。
一、RTP协议概述RTP协议是由IETF(Internet Engineering Task Force)制定的,在音视频通信领域得到了广泛应用。
它通过在音视频数据上附加头信息的方式,实现对数据的分组、传输和重组。
二、RTP报文结构RTP报文采用二进制的格式进行传输,一般由固定长度的头部和可变长度的有效载荷组成。
头部包含了报文的一些关键信息,如版本号、序列号、时间戳等,而有效载荷部分则存放着音视频数据。
三、RTP序列号与时间戳1. 序列号:RTP序列号是一个16位的无符号整数,用于标识RTP报文的顺序。
发送者在每发送一个RTP报文时,将序列号递增1并附加在报文头部,接收者通过对序列号进行排序,可以还原出音视频数据的正确顺序。
2. 时间戳:RTP时间戳用于标识音视频数据的播放时间,以毫秒为单位。
发送者在每发送一个RTP报文时,会将当前时间戳附加在报文头部,接收者可以根据时间戳信息对音视频数据进行同步。
四、RTP同步源(SSRC)RTP同步源标识了一路音视频数据的来源,它是一个32位的无符号整数。
通过SSRC,接收者可以确定音视频数据所属的流,并将不同流的数据进行分离与重组。
五、RTP报文传输流程RTP协议的音视频数据传输可以简要分为以下几个步骤:1. 数据封装:发送端将音视频数据打包成RTP报文,包括头部和有效载荷两部分。
2. 报文传输:发送端通过UDP(User Datagram Protocol)将RTP报文传输给接收端。
3. 报文接收:接收端通过UDP接收RTP报文,并对数据进行解析,提取出音视频数据和报文头部的各项信息。
4. 数据解封:接收端根据解析得到的信息,将收到的RTP报文解封得到音视频数据。
rtp 组播编程实例RTP组播编程实例标题:使用RTP实现音频组播引言:音频组播是一种使用RTP(Real-time Transport Protocol)实现的技术,能够在网络中同时传输音频流到多个接收器。
本文将介绍如何使用RTP来实现音频组播,并展示其在实际场景中的应用。
1. RTP简介RTP是一种实时传输协议,常用于音频和视频的传输。
它提供了数据包分组、时间戳、序列号等功能,以确保音频和视频能够按顺序、实时地传输到接收端。
2. 音频组播原理音频组播通过将音频流分成若干个数据包,并使用RTP协议进行传输。
发送方将音频数据打包成RTP数据包,并添加相应的时间戳和序列号。
接收方通过解析RTP数据包,按照时间戳和序列号来还原音频数据,并播放出来。
3. 使用RTP实现音频组播的步骤步骤一:创建RTP会话我们需要创建一个RTP会话,用于发送和接收音频数据。
在创建会话时,需要指定发送端口和接收端口。
步骤二:音频编码与解码在发送端,我们需要对音频进行编码,将其转换为RTP数据包。
常用的音频编码算法包括G.711、G.729等。
在接收端,需要对接收到的RTP数据包进行解码,还原音频数据。
步骤三:数据分组和传输在发送端,我们将音频数据按照一定的大小进行分组,并打包成RTP数据包。
然后,通过UDP协议将RTP数据包发送到指定的组播地址和端口。
在接收端,通过监听指定的组播地址和端口,收到RTP数据包后进行解析和还原。
步骤四:播放音频在接收端,我们将解析和还原后的音频数据进行播放。
4. 音频组播的应用音频组播广泛应用于多媒体会议、音频广播、实时语音通信等领域。
它可以实现多个用户同时收听同一音频源,提高资源利用率,并减少网络带宽的占用。
结论:通过使用RTP实现音频组播,我们可以在网络中实现高质量、实时的音频传输。
它是一种非常有效的技术,广泛应用于各种实时音频通信场景。
希望本文对读者理解RTP组播编程有所帮助,并能够在实际项目中应用起来。
rtp 组播编程实例RTP组播是一种常用于实时传输协议(Real-time Transport Protocol)的技术,它可以在网络中同时向多个接收方发送数据。
这种技术常被用于音频和视频的传输,以实现同步播放效果。
在RTP组播编程实例中,我们可以以音频传输为例进行描述。
假设我们有一个音频流,需要将其同时传输给多个接收方。
首先,我们需要创建一个RTP会话,这个会话可以用来管理和控制音频流的传输。
接下来,我们需要设置音频流的源地址和目的地址。
源地址指的是音频流的发送方地址,而目的地址则是接收方的地址。
在RTP组播中,我们可以使用多播地址作为目的地址,这样就可以实现将音频流同时发送给多个接收方。
然后,我们需要将音频流进行分片,并将每个分片封装成RTP数据包。
每个RTP数据包都包含了音频数据以及一些描述信息,比如时间戳和序列号,以便接收方能够正确地接收和播放音频。
接着,我们可以使用IP多播协议来进行数据包的传输。
这样,我们就可以将RTP数据包发送给多个接收方,而无需为每个接收方都单独发送数据包。
在接收方,我们首先需要创建一个RTP会话,用来接收和解析RTP 数据包。
然后,我们可以根据RTP数据包中的描述信息,比如时间戳和序列号,来正确地重组音频流,并进行播放。
通过使用RTP组播编程实例,我们可以实现高效的音频传输,同时满足多个接收方的需求。
这种技术可以广泛应用于在线会议、音视频直播等场景,为用户提供良好的使用体验。
总结起来,RTP组播编程实例可以通过创建RTP会话、设置源地址和目的地址、分片音频流、封装RTP数据包、使用IP多播协议传输数据包以及接收和解析RTP数据包等步骤来实现。
这种技术可以实现高效的音频传输,并满足多个接收方的需求。
希望以上内容能够对您有所帮助。
jrtplib 收发用例JRTPLIB是一个用于实现实时传输协议(RTP)和实时控制协议(RTCP)的C++库。
它提供了一组用于发送和接收RTP和RTCP数据包的类和函数。
本文将介绍JRTPLIB的收发用例。
一、发送RTP数据包发送RTP数据包的过程可以分为以下几个步骤:1. 创建RTPSession对象RTPSession是JRTPLIB中用于发送和接收RTP数据包的主要类。
创建RTPSession对象时需要指定RTP和RTCP的本地端口号。
2. 设置RTPSession参数在创建RTPSession对象后,需要设置一些参数,如远程IP地址和端口号、负载类型等。
可以使用RTPSession的SetDefaultPayloadType()、SetDestination()、SetDefaultMark()等函数设置这些参数。
3. 创建RTPPacket对象RTPPacket是JRTPLIB中用于表示RTP数据包的类。
创建RTPPacket对象时需要指定负载数据、负载数据长度、负载类型等。
4. 发送RTP数据包使用RTPSession的SendPacket()函数发送RTP数据包。
二、接收RTP数据包接收RTP数据包的过程可以分为以下几个步骤:1. 创建RTPSession对象同样需要创建RTPSession对象,但此时需要指定RTP和RTCP的本地端口号以及远程IP地址和端口号。
2. 设置RTPSession参数同样需要设置一些参数,如负载类型等。
可以使用RTPSession的SetDefaultPayloadType()、SetDefaultMark()等函数设置这些参数。
3. 设置RTPSession回调函数使用RTPSession的SetReceiveMode()函数设置RTPSession的接收模式,并指定回调函数。
回调函数将在接收到RTP数据包时被调用。
4. 接收RTP数据包使用RTPSession的Poll()函数接收RTP数据包。
rtp实时传输协议书甲方(以下简称“甲方”):地址:法定代表人:联系方式:乙方(以下简称“乙方”):地址:法定代表人:联系方式:鉴于甲方拥有实时传输技术及相关知识产权,乙方需要使用该技术进行数据传输,双方本着平等互利的原则,经协商一致,就实时传输技术的使用达成如下协议:第一条定义1.1 “实时传输协议”(以下简称“RTP”)是指甲方拥有的用于数据实时传输的技术。
1.2 “知识产权”是指与RTP相关的所有专利权、著作权、商标权及其他相关权利。
第二条授权范围2.1 甲方同意授权乙方使用RTP进行数据传输。
2.2 授权使用的范围仅限于乙方自身的业务需要,不得转授权或用于其他任何第三方。
第三条授权期限3.1 本协议自双方签字盖章之日起生效,有效期为____年,除非提前终止。
第四条使用费用及支付方式4.1 乙方应向甲方支付使用RTP的技术使用费,具体金额为____元人民币。
4.2 支付方式为____(一次性支付/分期支付等),支付时间为每____(月/季/年)的第____日前。
第五条技术支持与维护5.1 甲方应向乙方提供必要的技术支持,确保RTP的正常运行。
5.2 甲方负责RTP的定期维护和升级,确保技术的先进性和稳定性。
第六条保密条款6.1 双方应对本协议内容及在履行协议过程中获知的对方商业秘密予以保密。
6.2 未经对方书面同意,任何一方不得向第三方披露、泄露或允许第三方使用上述信息。
第七条违约责任7.1 如一方违反本协议约定,应承担违约责任,并赔偿对方因此遭受的一切损失。
第八条协议的变更与解除8.1 本协议的任何变更或补充,应经双方协商一致,并以书面形式确认。
8.2 如一方严重违约,另一方有权解除本协议,并要求违约方承担相应的违约责任。
第九条争议解决9.1 因本协议引起的或与本协议有关的任何争议,双方应首先通过友好协商解决。
9.2 如协商不成,任何一方均可向甲方所在地人民法院提起诉讼。
第十条其他10.1 本协议未尽事宜,双方可另行协商解决。
RTP实时传输协议(来自: 小龙文档网:rtp-实时传输协议)篇一:RTPRTCP实时传输协议实现课程设计RTP-RTCP实时传输协议实现课程设计RTP-RTCP实时传输协议实现一、设计目的和意义了解实时传输协议RTP和实时传输控制协议RTCP的基本原理;学习使用RTP数据报发送实时数据,并接收重组;学习实时数据传输控制基本方法;了解媒体内同步和媒体间同步的基本概念。
二、设计原理1、基本概念RTP全名是Real-time Transport Protocol(实时传输协议)。
RTCP全名是Real-time Transport Control Protocol,即实时传输控制协议。
RTP定义在RFC 1889中,是一种提供端对端传输服务的实时传输协议,用来支持网络服务中传输实时数据。
RTCP用来监视服务质量和传送有关与会者的信息,主要功能是为应用程序提供会话质量或者广播性能质量的信息。
多媒体网络通常把RTCP和RTP一起使用。
RTP 用来为IP网上的语音、图像、传真等多种需要实时传输的多媒体数据提供端到端的实时传输服务。
RTP的典型应用建立在UDP上,但也可以在TCP或ATM等其他协议之上工作。
RTP为Internet上端到端的实时传输提供时间信息和流同步,但并不保证服务质量,服务质量由RTCP来提供。
RTCP负责管理传输质量在当前应用进程之间交换控制信息。
在RTP会话期间,各参与者周期性地传送RTCP包,包中含有已发送的数据包的数量、丢失的数据包的数量等统计资料,因此,服务器可以利用这些信息动态地改变传输速率,甚至改变有效载荷类型。
RTP和RTCP配合使用,能以有效的反馈和最小的开销使传输效率最佳化,故特别适合传送网上的实时数据。
2、RTP工作机制威胁多媒体数据传输的一个尖锐的问题就是不可预料数据到达时间。
但是流媒体的传输是需要数据的适时的到达用以播放和回放。
RTP协议就是提供了时间标签,序列号以及其它的结构用于控制适时数据的流放。
#include "rtpsession.h"#include "rtpsessionparams.h"#include "rtpudpv4transmitter.h"#include "rtpipv4address.h"#include "rtptimeutilities.h"#include "rtppacket.h"#include <stdlib.h>#include <iostream>#pragma comment(lib, "jrtplib.lib")#pragma comment(lib,"jthread.lib")#pragma comment(lib,"WS2_32.lib")using namespace jrtplib;using namespace std;void checkerror( int errorcode ){if( errorcode < 0 ){std::cout<< "ERROR:" << RTPGetErrorString( errorcode ) << std::endl;exit( -1 );}}void usage( void ){std::cout << "Usage: ./bf537_send DestinationIPAddress DestinationPort FilePath" << std::endl;}long getfilelen( FILE *fp ){long cur_pos;long len;if( NULL == fp ){printf( "FILE fp is NULL\n" );exit(-1);}cur_pos = ftell( fp );fseek( fp, 0, SEEK_END );len = ftell( fp );fseek( fp, cur_pos, SEEK_SET );return len;}int main(void){#ifdef WIN32WSADATA dat;WSAStartup(MAKEWORD(1,1),&dat);#endif // WIN32RTPSession session;RTPSessionParams sessionparams;sessionparams.SetOwnTimestampUnit(1.0/90000.0);RTPUDPv4TransmissionParams transparams;transparams.SetPortbase(8000);int status = session.Create(sessionparams,&transparams);if (status < 0){std::cerr << RTPGetErrorString(status) << std::endl;exit(-1);}uint8_t localip[]={192,168,0,149};RTPIPv4Address addr(localip,9000);status = session.AddDestination(addr);if (status < 0){std::cerr << RTPGetErrorString(status) << std::endl;exit(-1);}session.SetDefaultPayloadType(96);session.SetDefaultMark(false);session.SetDefaultTimestampIncrement(160);uint8_t silencebuffer[160];for (int i = 0 ; i < 160 ; i++)silencebuffer[i] = 128;RTPTime delay(0.020);RTPTime starttime = RTPTime::CurrentTime();char *filepath;FILE *fp;long filelength, templength, maxpacket, sendsize;//打开文件fp = fopen( "test22.264", "rb" );if( NULL == fp ){cout<<"打开文件失败"<<endl;exit(-1);}//获取文件大小filelength = getfilelen( fp );//获取所允许的最大包的大小maxpacket = sessionparams.GetMaximumPacketSize();maxpacket -= 12;//分配内存空间,存放整个文件unsigned char *mem;mem = (unsigned char *)malloc( filelength );//读取文件内容到内存templength = fread( mem, 1, filelength, fp );if( templength != filelength ){printf( "fread error: templength=%ld, filelength=%ld\n", templength, filelength );exit(-1);}//关闭文件fclose( fp );sendsize = filelength;//发送文件if( filelength <= maxpacket ){#ifdef DEBUGprintf( "we will send data in a single packet\n" );#endifstatus = session.SendPacket( mem, filelength );checkerror( status );printf( "Sent %s...[%ldKB/%ldKB]", filepath, (filelength / 1024), (filelength / 1024) );}/////////////////////////////////////////////////else//filelength > maxpacket文件大于最大包大小,须分包发送{#ifdef DEBUGprintf( "we will divide data into serval packets to send\n" );#endifwhile(1){if( sendsize <= maxpacket ){status = session.SendPacket( mem, sendsize );checkerror( status );printf( "Sent %s...[%ldKB/%ldKB]\n", filepath,(filelength / 1024), (filelength / 1024) );break;}status = session.SendPacket( (void *)mem, maxpacket);checkerror( status );sendsize -= maxpacket;//printf( "Sent ...[%ldKB/%ldKB]\n", filepath,((filelength - sendsize) / 1024), (filelength / 1024) );cout<<sendsize<<endl;Sleep(1000);mem += maxpacket;RTPTime::Wait( RTPTime( 0, 200 ) );}}//离开会话session.BYEDestroy( RTPTime( 10, 0 ), 0, 0 );#ifdef DEBUGcout << "GoodBye RTP Session" << endl;#endif///////////////////////////////////////////////////bool done = false;//while (!done)//{// status = session.SendPacket(silencebuffer,160);// if (status < 0)// {// std::cerr << RTPGetErrorString(status) << std::endl;// exit(-1);// }// session.BeginDataAccess();// if (session.GotoFirstSource())// {// do// {// RTPPacket *packet;// while ((packet = session.GetNextPacket()) != 0)// {// std::cout << "Got packet with "// << "extended sequence number "// << packet->GetExtendedSequenceNumber() // << " from SSRC " << packet->GetSSRC() // << std::endl;// session.DeletePacket(packet);// }// } while (session.GotoNextSource());// }// session.EndDataAccess();//// RTPTime::Wait(delay);//// RTPTime t = RTPTime::CurrentTime();// t -= starttime;// if (t > RTPTime(60.0))// done = true;//}////delay = RTPTime(10.0);//session.BYEDestroy(delay,"Time's up",9);#ifdef WIN32WSACleanup();#endif // WIN32return 0;}。
资源下载:/source/444512实时流协议RTSP(RealTimeStreamingProtocol)是由RealNetworks和Netscape共同提出的,该协议定义了一对多应用程序如何有效地通过IP网络传送多媒体数据。
RTSP在体系结构上位于RTP(实时传输)和RTCP(实时控制)之上,它使用TCP或RTP完成数据传输。
HTTP与RTSP相比,HTTP传送HTML,而RTP传送的是多媒体数据。
HTTP请求由客户机发出,服务器作出响应;使用RTSP时,客户机和服务器都可以发出请求,即RTSP可以是双向的。
实时流协议(RTSP)是应用级协议,控制实时数据的发送。
RTSP提供了一个可扩展框架,使实时数据,如音频与视频,的受控、点播成为可能。
RTSP是应用级的协议,完成多媒体服务器的远程控制,控制信息的传输可以使用TCP,控制指令包括如:Setup、Play、Record、Pause、Teardwon等等。
对于流媒体应用,用户和服务器都可以发出请求,请求包括几种连接方法:持久、每个请求/响应传输一个连接、无连接。
常见的URL流媒体地址如:rtsp://:554RTP 数据报组成:Header + PayloadRTCP:应用程序启动RTP会话时将同时占用两个端口,供RTP和RTCP使用。
如果有必要,RTP使用时可以有两个伴随文档:1)配置文档,定义负载的编码类型和格式。
2)负载格式的规范文档。
在流传输过程中,有两类服务完成对流的转发处理:1)译流服务器Translator,进入的流在流出时发生变化,作用之一是更好地穿越防火墙。
2)混流服务器Mixer,多个流进入,合并后变成一个流流出。
由于进入的流可能有多个源,比如视频会议,会有多个话筒和视频头等等情况,对于RTP来说,就有一个同步化源的问题,因此,RTP协议中用SSRC(Synchronization Source)字段来供Mixer实现同步功能。
Translator的一个作用是多播变成多个单播。
为了提供播放和回放功能,RTP提供时间标签+序列号,在流动的概念中,时间标签是最重要的信息。
RTP报文不提供长度和报文边界的描述。
RTP虽然是传输层协议,但没有在OSI体系中作为单独的层来使用。
RTP是目前解决流媒体实时传输问题的最好办法,如果要开发,可以选择JRTPLIB库。
JRTPLIB是一个面向对象的RTP库,它完全遵循RFC 1889设计。
JRTPLIB是一个用C++语言实现的RTP库,目前已经可以运行在Windows、Linux、FreeBSD、Solaris、Unix和VxWorks等多种操作系统上。
了解更多RTP参考:/zouzheng/archive/2008/01/04/38449.html下面的例子参考jrtplib的example1,加了解析负载的部分。
// RTPClient.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include "rtpsession.h"#include "rtppacket.h"#include "rtpudpv4transmitter.h"#include "rtpipv4address.h"#include "rtpsessionparams.h"#include "rtperrors.h"#include <winsock2.h>#include <stdlib.h>#include <stdio.h>#include "windows.h"#include <iostream>#include <string>using namespace std;#pragma comment(lib,"jrtplib.lib")#pragma comment(lib,"jthread.lib")#pragma comment(lib,"WS2_32.lib")void checkerror(int rtperr)...{if (rtperr < 0)...{std::cout << "ERROR: " << RTPGetErrorString(rtperr) << std::endl;exit(-1);}}int main(int argc, char* argv[])...{#ifdef WIN32WSADATA dat;WSAStartup(MAKEWORD(2,2),&dat);#endif // WIN32RTPSession sess;uint16_t portbase,destport;uint32_t destip;std::string ipstr;int status,i,num;BYTE *pBuffer;BYTE *pfBuffer;//输入一些必要信息std::cout << "Enter local portbase:" << std::endl;std::cin >> portbase;std::cout << std::endl;std::cout << "Enter the destination IP address" << std::endl;std::cin >> ipstr;destip = inet_addr(ipstr.c_str());if (destip == INADDR_NONE)...{std::cerr << "Bad IP address specified" << std::endl;return -1;}destip = ntohl(destip);std::cout << "Enter the destination port" << std::endl;std::cin >> destport;std::cout << std::endl;std::cout << "Number of packets you wish to be sent:" << std::endl;std::cin >> num;// 创建RTP sessionRTPUDPv4TransmissionParams transparams;RTPSessionParams sessparams;// IMPORTANT: The local timestamp unit MUST be set, otherwise // RTCP Sender Report info will be calculated wrong// In this case, we'll be sending 10 samples each second, so we'll // put the timestamp unit to (1.0/10.0)sessparams.SetOwnTimestampUnit(1.0/10.0);sessparams.SetAcceptOwnPackets(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(" Sending packet %d/%d ",i,num);// 发送数据“1234567890”status = sess.SendPacket((void *)"1234567890",10,0,false,10);checkerror(status);sess.BeginDataAccess();// check incoming packetsif (sess.GotoFirstSourceWithData())...{do...{RTPPacket *pack;while ((pack = sess.GetNextPacket()) != NULL)...{// You can examine the data hereprintf("Got packet ! ");std::cout << "Got packet with "<< "extended sequence number "<< pack->GetExtendedSequenceNumber()<< " from SSRC " << pack->GetSSRC()<< std::endl;int dataLength = pack->GetPayloadLength();pfBuffer =(unsigned char*)pack->GetPayloadData();pBuffer = new BYTE[dataLength + 1];memcpy(pBuffer, pfBuffer, dataLength);pBuffer[dataLength] = 0;std::cout << pBuffer << std::endl;// we don't longer need the packet, so// we'll delete itsess.DeletePacket(pack);}} while (sess.GotoNextSourceWithData());}sess.EndDataAccess();#ifndef RTP_SUPPORT_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;}编译注意修改每个Source File的code generation下的Use run-time library为Debug Multithreaded DLL。