std::string strName = "[email protected]";
  int nLength = 2 + 2 + 8 + 20 + 4 + 6 + strName.size();
  std::string strRTCPBuffer;

//之所以需要增加长度是为了能够在CNAME字符串结尾添加0x0,保证wireshark能够解析出Type :0 (End)标志,%4是为了4个字节对齐
  int nRet = (strName.length() + 2) % 4;
  if (0 != nRet)
  {
   nLength = nLength + 4 - nRet;
  }
  else
  {
   nLength = nLength + 4;
  }
  strRTCPBuffer.resize(nLength);
  strRTCPBuffer[0] = 0x24;
  strRTCPBuffer[1] = 0x01;
  //RTCP报文长度,一段是RTCP统计数据内容,一段是RTCP源描述
  *(unsigned short*)&strRTCPBuffer[3] = htons(nLength - 4);
  //Sender Report
  strRTCPBuffer[4] = (char)(2 << 6);                              //  V=2,  P=RC=0
  strRTCPBuffer[5] = (char)200;                                 // PT=SR=200
  *(unsigned short*)&strRTCPBuffer[6] = htons(6);     // 7个32比特减一                            
  *(unsigned int*)&strRTCPBuffer[8] = htonl(0x23456);
  *(unsigned int*)&strRTCPBuffer[12] = htonl(m_video.sendtime >> 32);        // High 32-bits
  *(unsigned int*)&strRTCPBuffer[16] = htonl(m_video.sendtime & 0xFFFFFFFF); // Low 32-bits
  *(unsigned int*)&strRTCPBuffer[20] = htonl(m_nRtpTime);
  *(unsigned int*)&strRTCPBuffer[24] = htonl(m_nSendPacketCount);
  *(unsigned int*)&strRTCPBuffer[28] = htonl(m_nSendLength);
  //Source description
  strRTCPBuffer[32] = (char)(2 << 6) + 1;                          //  V=2, P=0, SC=1
  strRTCPBuffer[33] = 202;
  //RTCP源描述长度,减去4个字节($+channel+2个字节长度)减去Sender Report报文长度
  *(unsigned short*)&strRTCPBuffer[34] = htons((nLength - 4 - 7 * 4) / 4 - 1);
  *(unsigned int*)&strRTCPBuffer[39] = htonl(0x23456);
  strRTCPBuffer[40] = 1;                                         // CNAME=1
  strRTCPBuffer[41] = (char)strName.size();
  memcpy(&strRTCPBuffer[42], strName.c_str(), strName.size());


注意:通过htons,htonl等函数转换为网络字节序,否则接收端无法正常解析,这一点可以通过wireshark的分析可以看出来


注意:类似于RTP信息包,每个RTCP信息包以固定部分开始,紧接着的是可变长结构单元,最后以一个32位边界结束

是否意味着应该进行32位字节对齐,如何理解边界结束