void checkerror(int rtperr)
{
if (rtperr < 0)
{
std::cout << "ERROR: " << RTPGetErrorString(rtperr) << std::endl;
exit(-1);
}
}
//
// The main routine
//
int main(void)
{
#ifdef RTP_SOCKETTYPE_WINSOCK
WSADATA dat;
WSAStartup(MAKEWORD(2,2),&dat);
#endif // RTP_SOCKETTYPE_WINSOCK
RTPSession sess;
uint16_t portbase,destport;
uint32_t destip;
std::string ipstr;
int status,i,num;
std::cout << "Using version " << RTPLibraryVersion::GetVersion().GetVersionString() << std::endl;
// First, we'll ask for the necessary information
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;
}
// The inet_addr function returns a value in network byte order, but
// we need the IP address in host byte order, so we use a call to
// ntohl
destip = ntohl(destip);//转换为主机地址序
std::cout << "Enter the destination port" << std::endl;
std::cin >> destport;//设置目的地址的端口,如果测试自己给自己发送的包,请和portbase设置一致
std::cout << std::endl;
std::cout << "Number of packets you wish to be sent:" << std::endl;
std::cin >> num;
// Now, we'll create a RTP session, set the destination, send some
// packets and poll for incoming data.
RTPUDPv4TransmissionParams 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)
//在其他应用中,必须设置这个参数,比如使用RTP协议传输H264,这里必须设置为1/90000,关于如何使用RTP传输H264,请参考RFC3984协议规范
sessparams.SetOwnTimestampUnit(1.0/10.0);
sessparams.SetAcceptOwnPackets(true);//注意,如果想测试自己调用自己发送的包,需要设置为true
transparams.SetPortbase(portbase);
status = sess.Create(sessparams,&transparams);
checkerror(status);
RTPIPv4Address addr(destip,destport);
status = sess.AddDestination(addr);
checkerror(status);
for(int i = 0; i < num; ++i)
{
// send the packet
status = sess.SendPacket((void *)"1234567890",10,0,false,10);
checkerror(status);
//由于可能使用多线程,需要保证数据源数据在多线程下是安全的
//用户在获取其他数据源发送数据之前需要调用这个接口
//在调用完成之后需要调用EndDataAccess()接口
sess.BeginDataAccess();
// check incoming packets
if (sess.GotoFirstSourceWithData()) //判断是否有其他数据源发送的数据
{
do
{
RTPPacket *pack;
while ((pack = sess.GetNextPacket()) != NULL)
{
// You can examine the data here
printf("Got packet !\n");
// we don't longer need the packet, so
// we'll delete it
sess.DeletePacket(pack);
}
} while (sess.GotoNextSourceWithData());
}
sess.EndDataAccess();//由于可能使用多线程,需要保证数据源数据在多线程下是安全的
#ifndef RTP_SUPPORT_THREAD
status = sess.Poll();
checkerror(status);
#endif // RTP_SUPPORT_THREAD
RTPTime::Wait(RTPTime(1,0));
}
sess.BYEDestroy(RTPTime(10,0),0,0);
#ifdef RTP_SOCKETTYPE_WINSOCK
WSACleanup();
#endif // RTP_SOCKETTYPE_WINSOCK
return 0;
}
这个官方example还是比较简单的,主要是测试发一个数据包,然后自己接收发出的包,注意,这里需要注意将目的地址的端口和基端口(portbase)设置为相同,同时需要将这个参数设置为真sessparams.SetAcceptOwnPackets(true);