本文僅記錄研究rabbitmq-c用戶端源碼時,對rabbitmq幀資料構成進行總結。
先上一張圖:
上圖是rabbitmq-c用戶端與伺服器進行初始信令互動時的抓包,在此僅此作為示例使用。其中圖中所示為第一條connection.start信令的具體内容。請關注以下幾個值:
1.第一行顯示的length值為389
2.協定内部的length值為327
那麼389-327=62位元組的内容都包括了什麼?其包括了:14(ethernet頭)+20(ip頭)+20(tcp頭)=54位元組,以及amqp的幀資料 7(幀頭)+1(幀尾)=8位元組。
源碼中有如下結構:
<a href="http://my.oschina.net/moooofly/blog/104441#">?</a>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<code>struct</code> <code>amqp_connection_state_t_ {</code>
<code> </code><code>amqp_pool_t frame_pool;</code>
<code> </code><code>amqp_pool_t decoding_pool;</code>
<code> </code><code>amqp_connection_state_enum state;</code>
<code> </code><code>int</code> <code>channel_max;</code>
<code> </code><code>int</code> <code>frame_max;</code>
<code> </code><code>int</code> <code>heartbeat;</code>
<code> </code><code>amqp_bytes_t inbound_buffer;</code>
<code> </code><code>size_t</code> <code>inbound_offset;</code>
<code> </code><code>size_t</code> <code>target_size;</code>
<code> </code><code>amqp_bytes_t outbound_buffer;</code>
<code> </code><code>int</code> <code>sockfd;</code>
<code> </code><code>amqp_bytes_t sock_inbound_buffer;</code>
<code> </code><code>size_t</code> <code>sock_inbound_offset;</code>
<code> </code><code>size_t</code> <code>sock_inbound_limit;</code>
<code> </code><code>amqp_link_t *first_queued_frame;</code>
<code> </code><code>amqp_link_t *last_queued_frame;</code>
<code> </code><code>amqp_rpc_reply_t most_recent_api_result;</code>
<code>};</code>
其中 target_size 是指什麼呢?我們可以從另外三段代碼中找到答案:
在amqp_new_connection中
<code>state->target_size = 8;</code>
在return_to_idle中
<code>state->target_size = header_size;</code>
在amqp_handle_input中
<code>state->target_size = amqp_d32(raw_frame, 3) + header_size + footer_size;</code>
哈哈,原來該值正是amqp的實際要處理的幀的長度(在上例中其實就是327+7+1)。
有了上述說明,再看代碼時就不會被其中的各種幀解析代碼搞暈了!