首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >RTP Header C编程

RTP Header C编程
EN

Stack Overflow用户
提问于 2014-07-10 21:34:36
回答 1查看 3.2K关注 0票数 0

我创建UDP数据包(插入IP和UDP报头)并通过UDP套接字发送。我想将虚拟RTP报头添加到我创建的数据包中。我创建了RTP结构并插入了RTP报头,如下所示:

代码语言:javascript
复制
rtph->cc = 4
rtph->x = 1
rtph->p = 1
rtph->version = 2
rtph->pt = 7
rtph->m = 1
rtph->seq = 0
rtph->ts = random()
rtph->ssrc = 0

当我在wireshasrk中捕获时,我得到未知的RTP版本3。

任何帮助我们都将不胜感激

EN

回答 1

Stack Overflow用户

发布于 2016-04-23 16:43:01

如果您在C中为RTP定义了自己的结构,则必须考虑字节顺序。

代码语言:javascript
复制
typedef struct _RTPHeader
{
  //first byte
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
  unsigned int         CC:4;        /* CC field */
  unsigned int         X:1;         /* X field */
  unsigned int         P:1;         /* padding flag */
  unsigned int         version:2;
#elif G_BYTE_ORDER == G_BIG_ENDIAN
  unsigned int         version:2;
  unsigned int         P:1;         /* padding flag */
  unsigned int         X:1;         /* X field */
  unsigned int         CC:4;        /* CC field*/
#else
#error "G_BYTE_ORDER should be big or little endian."
#endif
  //second byte
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
  unsigned int         PT:7;     /* PT field */
  unsigned int         M:1;       /* M field */
#elif G_BYTE_ORDER == G_BIG_ENDIAN
  unsigned int         M:1;         /* M field */
  unsigned int         PT:7;       /* PT field */
#else
#error "G_BYTE_ORDER should be big or little endian."
#endif
  guint16              seq_num;      /* length of the recovery */
  guint32              TS;                   /* Timestamp */
  guint32              ssrc;
} RTPHeader; //12 bytes

结构必须是12字节长,所以您需要强制编译器将其打包为12字节长的结构,而不是填充它。此外,我还会添加一个静态断言,以便在编译时检查结构是否真的有12个字节长,所以:

代码语言:javascript
复制
#ifdef __WIN32__

#define PACKED
#pragma pack(push,1)

#else
#define PACKED __attribute__ ((__packed__))
#endif

//---------------------- STATIC ASSERT ----------------------------------
//Source: http://www.pixelbeat.org/programming/gcc/static_assert.html
#define ASSERT_CONCAT_(a, b) a##b
#define ASSERT_CONCAT(a, b) ASSERT_CONCAT_(a, b)
/* These can't be used after statements in c89. */
#ifdef __COUNTER__
#define STATIC_ASSERT(e,m) \
    ;enum { ASSERT_CONCAT(static_assert_, __COUNTER__) = 1/(!!(e)) }
#else
  /* This can't be used twice on the same line so ensure if using in headers
   * that the headers are not included twice (by wrapping in #ifndef...#endif)
   * Note it doesn't cause an issue when used on same line of separate modules
   * compiled with gcc -combine -fwhole-program.  */
#define STATIC_ASSERT(e,m) \
    ;enum { ASSERT_CONCAT(assert_line_, __LINE__) = 1/(!!(e)) }
#endif

typedef struct _RTPHeader
    {
      //first byte
    #if G_BYTE_ORDER == G_LITTLE_ENDIAN
      unsigned int         CC:4;        /* CC field */
      unsigned int         X:1;         /* X field */
      unsigned int         P:1;         /* padding flag */
      unsigned int         version:2;
    #elif G_BYTE_ORDER == G_BIG_ENDIAN
      unsigned int         version:2;
      unsigned int         P:1;         /* padding flag */
      unsigned int         X:1;         /* X field */
      unsigned int         CC:4;        /* CC field*/
    #else
    #error "G_BYTE_ORDER should be big or little endian."
    #endif
      //second byte
    #if G_BYTE_ORDER == G_LITTLE_ENDIAN
      unsigned int         PT:7;     /* PT field */
      unsigned int         M:1;       /* M field */
    #elif G_BYTE_ORDER == G_BIG_ENDIAN
      unsigned int         M:1;         /* M field */
      unsigned int         PT:7;       /* PT field */
    #else
    #error "G_BYTE_ORDER should be big or little endian."
    #endif
      guint16              seq_num;      /* length of the recovery */
      guint32              TS;                   /* Timestamp */
      guint32              ssrc;
    } RTPHeader; //12 bytes

STATIC_ASSERT (sizeof (RTPHeader) == 12, "RTPHeader size doesn't seem to be cool.");

#ifdef __WIN32__
#pragma pack(pop)
#undef PACKED

#else
#undef PACKED
#endif

版本号必须为2,如果您使用此结构写入字节,则如下所示:

代码语言:javascript
复制
char buffer[1400];
RTPHeader *rtph = (RTPHeader*) buffer;
rtph->version = 2;

那么从理论上讲,这是可以的。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24677965

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档