通过C/C++结构体解析RTP/RTCP的包头的方法

RTP包的头构成为:

0                  1                  2                  3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |V=2|P|X|  CC  |M|    PT      |      sequence number        |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |                          timestamp                          |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |          synchronization source (SSRC) identifier            |
  +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
  |            contributing source (CSRC) identifiers            |
  |                            ....                              |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

通过wireshark解析的形式:

通过C/C++结构体解析RTP/RTCP的包头的方法

在C/C++中,对包的头信息解析的方法为,定义一个结构体:

struct RTP_Header
{
 unsigned __int16 csrc_count:4;
 unsigned __int16 extension:1;
 unsigned __int16 padding:1;
 unsigned __int16 version:2;
 unsigned __int16 payloadtype:7; 
 unsigned __int16 marker:1; 

unsigned __int16 seq;
 unsigned __int32 timestamp;
 unsigned __int32 ssrc;
};

结构体中,冒号后面数字为实际占的位数,注意8位字节的内部,网络序与本地序是相反的,csrc_count在第1字节的后4位,而在结构体声明中,csrc_count需要在前4位,应用的方法,以序列号的获取为例:

int RTPProcessor::getSequenceNumber(PacketBuffer* packet)
{
 RTP_Header* pHeader =  (RTP_Header*)packet->data;
 return ntohs(pHeader->seq);
}

其中packet->data为recv的udp的原始包,通过RTP_Header的强制类型转换,即可直接通过pHeader->seq获取,这里需要网络序转换成字节序,调用ntohs的函数,同理,对序列号的修改如下:

void RTPProcessor::setSequenceNumber(PacketBuffer* packet)
{
 RTP_Header* pHeader =  (RTP_Header*)packet->data;
 pHeader->seq=  htons(m_sequenceNumer);
}

对于RTCP,方法与RTP相似,RTCP的包的头信息为:

0                  1                  2                  3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |V=2|P|  CC    |      PT      |          length              |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |          synchronization source (SSRC) identifier            |
  +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
  |                    source or chunk                            |
  |                            ....                              |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

RTCP的包的头信息与RTP有点不同,wireshark的解析为:

通过C/C++结构体解析RTP/RTCP的包头的方法

在C/C++中,对包的头信息解析的方法为,定义一个结构体:

struct RTCP_Header
{
 unsigned __int16 csrc_count:5;
 unsigned __int16 padding:1;
 unsigned __int16 version:2; //1 char
 unsigned __int16 payloadtype:8; //2 char
 unsigned __int16 length; //3,4 char

unsigned __int32 ssrc; //5,6,7,8 char
};

应用的方法,也是获取原始数据包的首地址,再通过RTCP_Header进行强制类型转换。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/b4419ad6675cbbc83e3637993483f58e.html