我之前编译了jrtplib 3.9.1,并且在项目中使用,结果发现在用这个库时,程序体积有增加了300多K,感觉实在是有点笨重,我无法就是用来发送rtp包而已。想想还是自己重新实现一个简单的类用用拉倒了,所以有了下面的代码。
头文件:
 
- #ifndef _EASY_RTP_H  
- #define _EASY_RTP_H  
-   
- #include <string>  
-   
- #include <stdint.h>  
-   
- #ifdef _WIN32  
- #include <winsock2.h>  
- #else  
- #include <netinet/in.h>  
- #include <sys/types.h>  
- #include <sys/socket.h>  
- #include <arpa/inet.h>  
- #include <errno.h>  
- #ifndef INVALID_SOCKET  
- #define INVALID_SOCKET  (SOCKET)(~0)  
- #endif  
- #ifndef SOCKET_ERROR  
- #define SOCKET_ERROR    (-1)  
- #endif  
- #ifndef closesocket  
- #define closesocket(x)  close(x)  
- #endif  
- typedef int SOCKET;  
- #endif  
-   
- #define DEFAULT_MAX_PACKET_SIZE 1472  
-   
- class EasyRtp  
- {  
- public:  
-     
-     EasyRtp(const std::string& destIp, uint16_t port, uint16_t localPort = 0, int16_t maxpacketsize = DEFAULT_MAX_PACKET_SIZE);  
-     
-     EasyRtp(uint32_t destIp, uint16_t port, uint16_t localPort = 0, int16_t maxpacketsize = DEFAULT_MAX_PACKET_SIZE);  
-     ~EasyRtp();  
- public:  
-     
-     int32_t sendPacket(const char* buf, int32_t len, int8_t pt, bool mark, int32_t timestampInc);  
- private:  
-     
-     typedef struct  
-     {  
-         uint8_t ver;                
-         bool p;                     
-         bool x;                     
-         uint8_t cc;                 
-         bool mark;                  
-         int8_t pt;                  
-         uint16_t sn;                
-         uint32_t ts;                
-         uint32_t ssrc;              
-     }RtpHeader;  
-   
-     
-     int16_t _maxPacketSize;  
-     
-     char* _sbuf;  
-     
-     uint16_t _sn;  
-     
-     uint32_t _ts;  
-     
-     uint32_t _ssrc;  
-     
-     SOCKET _socket;  
-     
-     struct sockaddr_in _destTo;  
- };  
-   
- #endif  // _EASY_RTP_H  
 
cpp源码:
 
 
- #include <stdio.h>  
- #include <string.h>  
-   
- #include <stdexcept>  
-   
- #include "easy_rtp.h"  
- #include "byte_write.h"  
- #include "utils.h"  
-   
- #define RTP_VERSION         2  
- #define RTP_HEADER_SIZE     12  
-   
- EasyRtp::EasyRtp( const std::string& destIp, uint16_t port, uint16_t localPort 
-     :_maxPacketSize(maxpacketsize),  
-     _sbuf(NULL),  
-     _sn(Utils::createRandam32()),  
-     _ts(Utils::createRandam32()),  
-     _ssrc(Utils::createRandam32())  
- {  
-     if (maxpacketsize >= RTP_HEADER_SIZE)  
-         _sbuf = new char[maxpacketsize];  
-     else  
-         throw std::runtime_error("[EasyRtp] too small packet size, must more than 12 Byte");  
-   
-     _socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);  
-     if (_socket == INVALID_SOCKET)  
-         throw std::runtime_error("[EasyRtp] invalid socket");  
-   
-     _destTo.sin_family = AF_INET;  
-     _destTo.sin_port = htons(port);  
-     _destTo.sin_addr.s_addr = inet_addr(destIp.c_str());  
-   
-     if (localPort != 0)  
-     {  
-         struct sockaddr_in sockAddr;  
-         sockAddr.sin_family = AF_INET;  
-         sockAddr.sin_port = htons(localPort);  
-         sockAddr.sin_addr.s_addr = INADDR_ANY;  
-   
-         if (bind(_socket, (const sockaddr*)&sockAddr, sizeof(sockAddr)) == SOCKET_ERROR)  
-         {  
- #ifndef NPRINT  
- #ifdef _WIN32  
-             printf("[EasyRtp] bind error: %d\n", WSAGetLastError());  
- #else  
-             printf("[EasyRtp] bind error: %d\n", errno);  
- #endif  
- #endif  
-             closesocket(_socket);  
-             throw std::runtime_error("[EasyRtp] bind error");  
-         }  
-     }  
- }  
-   
- EasyRtp::EasyRtp( uint32_t destIp, uint16_t port, uint16_t localPort 
-     :_maxPacketSize(maxpacketsize),  
-     _sbuf(NULL),  
-     _sn(Utils::createRandam32()),  
-     _ts(Utils::createRandam32()),  
-     _ssrc(Utils::createRandam32())  
- {  
-     if (maxpacketsize >= RTP_HEADER_SIZE)  
-         _sbuf = new char[maxpacketsize];  
-     else  
-         throw std::runtime_error("[EasyRtp] too small packet size, must more than 12 Byte");  
-   
-     _socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);  
-     if (_socket == INVALID_SOCKET)  
-         throw std::runtime_error("[EasyRtp] invalid socket");  
-   
-     _destTo.sin_family = AF_INET;  
-     _destTo.sin_port = htons(port);  
-     _destTo.sin_addr.s_addr = htonl(destIp);  
-   
-     if (localPort != 0)  
-     {  
-         struct sockaddr_in sockAddr;  
-         sockAddr.sin_family = AF_INET;  
-         sockAddr.sin_port = htons(localPort);  
-         sockAddr.sin_addr.s_addr = INADDR_ANY;  
-   
-         if (bind(_socket, (const sockaddr*)&sockAddr, sizeof(sockAddr)) == SOCKET_ERROR)  
-         {  
- #ifndef NPRINT  
- #ifdef _WIN32  
-             printf("[EasyRtp] bind error: %d\n", WSAGetLastError());  
- #else  
-             printf("[EasyRtp] bind error: %d\n", errno);  
- #endif  
- #endif  
-             closesocket(_socket);  
-             throw std::runtime_error("[EasyRtp] bind error");  
-         }  
-     }  
- }  
-   
- EasyRtp::~EasyRtp()  
- {  
-     if (_socket != INVALID_SOCKET)  
-         closesocket(_socket);  
-     if (_sbuf != NULL)  
-         delete [] _sbuf;  
- }  
-   
- int32_t EasyRtp::sendPacket( const char* buf, int32_t len, int8_t pt, bool mark, int32_t timestampInc )  
- {  
-     if ((len + RTP_HEADER_SIZE) > _maxPacketSize)  
-         return -1;  
-   
-     ++_sn;  
-     _ts += timestampInc;  
-   
-     
-     _sbuf[0] = 0;  
-     _sbuf[0] |= RTP_VERSION << 6;  
-     _sbuf[1] = 0;  
-     _sbuf[1] |= mark << 7;  
-     _sbuf[1] |= pt;  
-     write_be_w(_sbuf + 2, _sn);  
-     write_be_dw(_sbuf + 4, _ts);  
-     write_be_dw(_sbuf + 8, _ssrc);  
-     
-     memcpy(_sbuf + RTP_HEADER_SIZE, buf, len);  
-     int32_t ret = sendto(_socket, (const char*)_sbuf, len + RTP_HEADER_SIZE, 0, (const sockaddr*)&_destTo, sizeof(_destTo));  
- #ifndef NPRINT  
-     if (ret < 0)  
-     {  
- #ifdef _WIN32  
-         printf("[EasyRtp] sendto error: %d\n", WSAGetLastError());  
- #else  
-         printf("[EasyRtp] sendto error: %d\n", errno);  
- #endif  
-     }  
- #endif  
-     return ret;  
- }  
 
注:
 
stdint.h是新c++标准中的头文件,定义了int32_t int8_t等typedef 类型。
简单RTP发送类c++实现
原文:http://www.cnblogs.com/lidabo/p/4245447.html