实时流协议RTSP(RealTimeStreamingProtocol)是由RealNetworks和 Netscape共同提出的,该协议定义了一对多应用程序如何有效地通过IP网络传送多媒体数据。RTSP在体系结构上位于RTP(实时传输)和RTCP(实时控制)之上,它使用 TCP或RTP完成数据传输。HTTP与RTSP相比,HTTP传送HTML,而RTP传送的是多媒体数据。HTTP请求由客户机发出,服务器作出响应;使用RTSP时,客户机和服务器都可以发出请求,即RTSP可以是双向的。 实时流协议(RTSP)是应用级协议,控制实时数据的发送。RTSP提供了一个可扩展框架,使实时数据,如音频与视频,的受控、点播成为可能。 RTP是目前解决流媒体实时传输问题的最好办法,如果要开发,可以选择JRTPLIB库。JRTPLIB是一个面向对象的RTP库,它完全遵循RFC 1889设计。JRTPLIB是一个用C++语言实现的RTP库,目前已经可以运行在Windows、Linux、FreeBSD、Solaris、Unix和 VxWorks等多种操作系统上。 了解更多RTP参考: http://www.cnitblog.com/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 WIN32 WSADATA dat; WSAStartup(MAKEWORD(2,2),&dat); #endif // WIN32 RTPSession 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 session 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) 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 packets if (sess.GotoFirstSourceWithData()) { do { RTPPacket *pack; while ((pack = sess.GetNextPacket()) != NULL) { // You can examine the data here printf("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 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 WIN32 WSACleanup(); #endif // WIN32 return 0; }
编译注意修改每个Source File的code generation下的Use run-time library为Debug Multithreaded DLL。 关于jrtplib的环境,可以参考网上很多的资料,也可以从我的资源里下载,我已经编译好了相关lib,只要加的VC环境里就可以了。 执行测试程序的效果如下: Enter local portbase: 8000 Enter the destination IP address 127.0.0.1 Enter the destination port 8000 Number of packets you wish to be sent: 5 Sending packet 1/5 Got packet ! Got packet with extended sequence number 59262 from SSRC 3029241192 1234567890 Sending packet 2/5 Got packet ! Got packet with extended sequence number 59263 from SSRC 3029241192 1234567890 Sending packet 3/5 Sending packet 4/5 Got packet ! Got packet with extended sequence number 59264 from SSRC 3029241192 1234567890 Got packet ! Got packet with extended sequence number 59265 from SSRC 3029241192 1234567890 Sending packet 5/5 上面执行的意思是程序自己开了8000端口,然后往自己的8000发送,所以不仅发送出去,还收到并解析出了内容。如果要往另外机器上发,另一个机器上也运行这个程序就可以了。当然可以专门再写一个接收端。 (佚名) |