源代码
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);