<menu id="w8yyk"><menu id="w8yyk"></menu></menu>
  • <dd id="w8yyk"><nav id="w8yyk"></nav></dd>
    <menu id="w8yyk"></menu>
    <menu id="w8yyk"><code id="w8yyk"></code></menu>
    <menu id="w8yyk"></menu>
    <xmp id="w8yyk">
    <xmp id="w8yyk"><nav id="w8yyk"></nav>
  • 網站首頁 > 物聯資訊 > 技術分享

    簡單RTP發送類c++實現

    2016-09-28 00:00:00 廣州睿豐德信息科技有限公司 閱讀
    睿豐德科技 專注RFID識別技術和條碼識別技術與管理軟件的集成項目。質量追溯系統、MES系統、金蝶與條碼系統對接、用友與條碼系統對接

    我之前編譯了jrtplib 3.9.1,并且在項目中使用,結果發現在用這個庫時,程序體積有增加了300多K,感覺實在是有點笨重,我無法就是用來發送rtp包而已。想想還是自己重新實現一個簡單的類用用拉倒了,所以有了下面的代碼。

    頭文件:

     

    [cpp] view plaincopy  
    1. /*! 
    2. @brief 簡單rtp庫 
    3. @file easy_rtp.h 
    4. */  
    5. #ifndef _EASY_RTP_H  
    6. #define _EASY_RTP_H  
    7.   
    8. #include <string>  
    9.   
    10. #include <stdint.h>  
    11.   
    12. #ifdef _WIN32  
    13. #include <winsock2.h>  
    14. #else  
    15. #include <netinet/in.h>  
    16. #include <sys/types.h>  
    17. #include <sys/socket.h>  
    18. #include <arpa/inet.h>  
    19. #include <errno.h>  
    20. #ifndef INVALID_SOCKET  
    21. #define INVALID_SOCKET  (SOCKET)(~0)  
    22. #endif  
    23. #ifndef SOCKET_ERROR  
    24. #define SOCKET_ERROR    (-1)  
    25. #endif  
    26. #ifndef closesocket  
    27. #define closesocket(x)  close(x)  
    28. #endif  
    29. typedef int SOCKET;  
    30. #endif  
    31.   
    32. // 默認最大包大小(MTU 1500 - IP頭 20 - UDP頭 8)  
    33. #define DEFAULT_MAX_PACKET_SIZE 1472  
    34.   
    35. /*! 
    36. @brief 簡單rtp數據包裝發送庫 
    37. */  
    38. class EasyRtp  
    39. {  
    40. public:  
    41.     /*! 
    42.     @brief 構造 
    43.     @param destIp 目標ip地址 
    44.     @param port 目標端口 
    45.     @param localport 本地幫定端口,默認端口采用隨機值 
    46.     */  
    47.     EasyRtp(const std::string& destIp, uint16_t port, uint16_t localPort = 0, int16_t maxpacketsize = DEFAULT_MAX_PACKET_SIZE);  
    48.     /*! 
    49.     @brief 構造 
    50.     @param destIp 目標ip地址 
    51.     @param port 目標端口 
    52.     @param localport 本地幫定端口,默認端口采用隨機值 
    53.     */  
    54.     EasyRtp(uint32_t destIp, uint16_t port, uint16_t localPort = 0, int16_t maxpacketsize = DEFAULT_MAX_PACKET_SIZE);  
    55.     ~EasyRtp();  
    56. public:  
    57.     /*! 
    58.     @brief 發送rtp包給目標 
    59.     @param buf 發送的緩沖 
    60.     @param len 發送的緩沖大小 
    61.     @param pt 負載類型 
    62.     @param mark 標記位 
    63.     @param timestampInc 時間戳增量 
    64.     @param 錯誤為-1 
    65.     */  
    66.     int32_t sendPacket(const char* buf, int32_t len, int8_t pt, bool mark, int32_t timestampInc);  
    67. private:  
    68.     /// 簡單rtp頭12字節,不含擴展頭,csrc列表等信息  
    69.     typedef struct  
    70.     {  
    71.         uint8_t ver;                /// 版本號(2bit)  
    72.         bool p;                     /// 填充位,一直置0(1bit)  
    73.         bool x;                     /// 擴充頭位,一直置0(1bit)  
    74.         uint8_t cc;                 /// csrc列表數量,一直置0(4bit)  
    75.         bool mark;                  /// 標記位(1bit)  
    76.         int8_t pt;                  /// 負載類型(7bit)  
    77.         uint16_t sn;                /// 序列號(16bit)  
    78.         uint32_t ts;                /// 時間戳(32bit)  
    79.         uint32_t ssrc;              /// 來源標示(32bit)  
    80.     }RtpHeader;  
    81.   
    82.     // 最大包大小  
    83.     int16_t _maxPacketSize;  
    84.     // 發送的緩沖  
    85.     char* _sbuf;  
    86.     // 序列號  
    87.     uint16_t _sn;  
    88.     // 時間戳  
    89.     uint32_t _ts;  
    90.     // 源標示  
    91.     uint32_t _ssrc;  
    92.     // 句柄  
    93.     SOCKET _socket;  
    94.     // 目標地址  
    95.     struct sockaddr_in _destTo;  
    96. };  
    97.   
    98. #endif  // _EASY_RTP_H  


    cpp源碼:

     

     

    [cpp] view plaincopy  
    1. #include <stdio.h>  
    2. #include <string.h>  
    3.   
    4. #include <stdexcept>  
    5.   
    6. #include "easy_rtp.h"  
    7. #include "byte_write.h"  
    8. #include "utils.h"  
    9.   
    10. // 默認的rtp版本  
    11. #define RTP_VERSION         2  
    12. // rtp頭大小  
    13. #define RTP_HEADER_SIZE     12  
    14.   
    15. EasyRtp::EasyRtp( const std::string& destIp, uint16_t port, uint16_t localPort /*= 0*/, int16_t maxpacketsize /*= 1500*/ )  
    16.     :_maxPacketSize(maxpacketsize),  
    17.     _sbuf(NULL),  
    18.     _sn(Utils::createRandam32()),  
    19.     _ts(Utils::createRandam32()),  
    20.     _ssrc(Utils::createRandam32())  
    21. {  
    22.     if (maxpacketsize >= RTP_HEADER_SIZE)  
    23.         _sbuf = new char[maxpacketsize];  
    24.     else  
    25.         throw std::runtime_error("[EasyRtp] too small packet size, must more than 12 Byte");  
    26.   
    27.     _socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);  
    28.     if (_socket == INVALID_SOCKET)  
    29.         throw std::runtime_error("[EasyRtp] invalid socket");  
    30.   
    31.     _destTo.sin_family = AF_INET;  
    32.     _destTo.sin_port = htons(port);  
    33.     _destTo.sin_addr.s_addr = inet_addr(destIp.c_str());  
    34.   
    35.     if (localPort != 0)  
    36.     {  
    37.         struct sockaddr_in sockAddr;  
    38.         sockAddr.sin_family = AF_INET;  
    39.         sockAddr.sin_port = htons(localPort);  
    40.         sockAddr.sin_addr.s_addr = INADDR_ANY;  
    41.   
    42.         if (bind(_socket, (const sockaddr*)&sockAddr, sizeof(sockAddr)) == SOCKET_ERROR)  
    43.         {  
    44. #ifndef NPRINT  
    45. #ifdef _WIN32  
    46.             printf("[EasyRtp] bind error: %d\n", WSAGetLastError());  
    47. #else  
    48.             printf("[EasyRtp] bind error: %d\n", errno);  
    49. #endif  
    50. #endif  
    51.             closesocket(_socket);  
    52.             throw std::runtime_error("[EasyRtp] bind error");  
    53.         }  
    54.     }  
    55. }  
    56.   
    57. EasyRtp::EasyRtp( uint32_t destIp, uint16_t port, uint16_t localPort /*= 0*/, int16_t maxpacketsize /*= DEFAULT_MAX_PACKET_SIZE*/ )  
    58.     :_maxPacketSize(maxpacketsize),  
    59.     _sbuf(NULL),  
    60.     _sn(Utils::createRandam32()),  
    61.     _ts(Utils::createRandam32()),  
    62.     _ssrc(Utils::createRandam32())  
    63. {  
    64.     if (maxpacketsize >= RTP_HEADER_SIZE)  
    65.         _sbuf = new char[maxpacketsize];  
    66.     else  
    67.         throw std::runtime_error("[EasyRtp] too small packet size, must more than 12 Byte");  
    68.   
    69.     _socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);  
    70.     if (_socket == INVALID_SOCKET)  
    71.         throw std::runtime_error("[EasyRtp] invalid socket");  
    72.   
    73.     _destTo.sin_family = AF_INET;  
    74.     _destTo.sin_port = htons(port);  
    75.     _destTo.sin_addr.s_addr = htonl(destIp);  
    76.   
    77.     if (localPort != 0)  
    78.     {  
    79.         struct sockaddr_in sockAddr;  
    80.         sockAddr.sin_family = AF_INET;  
    81.         sockAddr.sin_port = htons(localPort);  
    82.         sockAddr.sin_addr.s_addr = INADDR_ANY;  
    83.   
    84.         if (bind(_socket, (const sockaddr*)&sockAddr, sizeof(sockAddr)) == SOCKET_ERROR)  
    85.         {  
    86. #ifndef NPRINT  
    87. #ifdef _WIN32  
    88.             printf("[EasyRtp] bind error: %d\n", WSAGetLastError());  
    89. #else  
    90.             printf("[EasyRtp] bind error: %d\n", errno);  
    91. #endif  
    92. #endif  
    93.             closesocket(_socket);  
    94.             throw std::runtime_error("[EasyRtp] bind error");  
    95.         }  
    96.     }  
    97. }  
    98.   
    99. EasyRtp::~EasyRtp()  
    100. {  
    101.     if (_socket != INVALID_SOCKET)  
    102.         closesocket(_socket);  
    103.     if (_sbuf != NULL)  
    104.         delete [] _sbuf;  
    105. }  
    106.   
    107. int32_t EasyRtp::sendPacket( const char* buf, int32_t len, int8_t pt, bool mark, int32_t timestampInc )  
    108. {  
    109.     if ((len + RTP_HEADER_SIZE) > _maxPacketSize)  
    110.         return -1;  
    111.   
    112.     ++_sn;  
    113.     _ts += timestampInc;  
    114.   
    115.     // 只設置版本號,其它的全是默認0  
    116.     _sbuf[0] = 0;  
    117.     _sbuf[0] |= RTP_VERSION << 6;  
    118.     _sbuf[1] = 0;  
    119.     _sbuf[1] |= mark << 7;  
    120.     _sbuf[1] |= pt;  
    121.     write_be_w(_sbuf + 2, _sn);  
    122.     write_be_dw(_sbuf + 4, _ts);  
    123.     write_be_dw(_sbuf + 8, _ssrc);  
    124.     // 保存數據  
    125.     memcpy(_sbuf + RTP_HEADER_SIZE, buf, len);  
    126.     int32_t ret = sendto(_socket, (const char*)_sbuf, len + RTP_HEADER_SIZE, 0, (const sockaddr*)&_destTo, sizeof(_destTo));  
    127. #ifndef NPRINT  
    128.     if (ret < 0)  
    129.     {  
    130. #ifdef _WIN32  
    131.         printf("[EasyRtp] sendto error: %d\n", WSAGetLastError());  
    132. #else  
    133.         printf("[EasyRtp] sendto error: %d\n", errno);  
    134. #endif  
    135.     }  
    136. #endif  
    137.     return ret;  
    138. }  


    注:

     

    stdint.h是新c++標準中的頭文件,定義了int32_t int8_t等typedef 類型。

    RFID管理系統集成商 RFID中間件 條碼系統中間層 物聯網軟件集成
    最近免费观看高清韩国日本大全