[英]RTP Header C Programming
我創建UDP數據包(插入IP和UDP標頭)並通過UDP套接字發送。 我想向我創建的數據包中添加一個虛擬RTP標頭。 我創建了RTP結構並按如下所示插入RTP標頭:
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。
任何幫助表示贊賞
如果在C中為RTP定義自己的結構,則必須考慮字節順序。
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個字節,因此:
#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,然后使用此結構寫入字節,如下所示:
char buffer[1400];
RTPHeader *rtph = (RTPHeader*) buffer;
rtph->version = 2;
從理論上講就可以了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.