使用信元流(TLVStream)規範、簡化模組(C/C++)間互動

來源:互聯網
上載者:User
  使用信元流(TLVStream)規範、簡化模組(C/C++)間互動 收藏

問題描述:
在軟體開發過程中,一般會對複雜的現實世界進行抽象,並且採用分而治之的策略,將大系統分解為子系統,將子系統分解為一個個的模組。模組間的通訊一般採用函數調用的方式,這樣會產生一些問題:
   1. 模組間的介面增多會導致模組間緊密耦合,不利於模組的重用、調試、維護。
   2. 介面函數參數會很複雜,容易出現很龐大,功能面面俱到的結構體。
   3. 不利於擴充,新增功能要新增介面函數,或者修改介面參數。

信元流的定義
信元流是一種處理資料的方式。它對現實世界的資料進行抽象,形成一個一個的信元,然後由這些信元以一定的方式組合起來,形成信元流,來傳遞資料。下面信元流的實現。
信元的實現
信元由三部分組成,分別是信元標識(Tag),信元長度(Length),信元值(Value),即TLV格式。下面是一個信元的c定義:
typedef struct __ELEMENT_ST

     {

          ELE_TAG tag;

          ELE_LEN len;

          ELE_VALUE value;

     }ELEMENT_ST;

信元流的實現:
信元流分為兩部分,信元流頭部(head)和體部(body)。head部分用於記錄信元流的整體描述,比如,信元流的起始模組,目的模組,以及信元流的訊息類型等等。當然,也可以根據需要自己進行擴充。body部分包括信元流中信元的總大小,即ELE_MSG_BODY中body的長度。

        typedef struct __ELEMENT_STREAM_ST
        {
            MOD_ID src_mod;
            MOD_ID des_mod;
            ELE_MSG_TYPE type;
            ELE_MSG_BODY body;
        }ELEMENT_STREAM_ST;
        typedef struct __ELE_MSG_BODY
        {
            ELE_MSG_LEN len;
            char body[MAX_ELE_MSG_BODY_LEN];
        } ELE_MSG_BODY;

構造信元流
定義好結構體後,下面定義兩個函數,分別向信元體中添加信元和刪除信元。
   //pbody信元體的指標。這裡沒有使用信元流的指標是為了讓函數的重用性更好,使用者可以自己定義信元流。
        //tag:添加信元的TAG值,len:添加信元的長度。pvale:添加信元的值。
        int AddElementToStreamBody(ELE_MSG_BODY *pbody, ELE_TAG tag, ELE_LEN len, void *pvalue);
        //pbody信元體的指標。 //tag:擷取信元的TAG值,buf_len:pbuf的長度。pbuf:目標緩衝區,要把信元VALUE的值寫入吃緩衝區。
        int GetElementFromStreamBody(ELE_MSG_BODY *pbody, ELE_TAG tag, int buf_len, void *pbuf);
信元流的body是一個緩衝區,信元在裡面順序排列。信元在body中順序不影響它的擷取。添加和擷取的方法比較簡單,不再贅述。

一個信元流的執行個體
下面來舉一個具體的例子來介紹一下信元流的使用,以及它的優點。
假如由兩個模組A和B。A模組負責處理商務邏輯,B模組負責處理呼叫控制。A調用B的一個介面發起呼叫,介面如下。
        typedef struct __MAKE_CALL_ST
        {
            char caller_num[MAX_NUM_LEN];//主叫號碼
            char called_num[MAX_NUM_LEN];//被叫號碼
        }MAKE_CALL_ST;
        int MakeCall(MAKE_CALL_ST *pcall_info);

後面需求有更改,某些情況下藥攜帶主叫的callid資訊。結構體會變成:
    typedef struct __MAKE_CALL_ST
    {
        char caller_num[MAX_NUM_LEN];//主叫號碼
        char called_num[MAX_NUM_LEN];//被叫號碼
        CALL_ID caller_callid;
    }MAKE_CALL_ST;
某些情況下又需要攜帶主叫的SDP資訊,結構體會變成:
    typedef struct __MAKE_CALL_ST
    {
        char caller_num[MAX_NUM_LEN];//主叫號碼
        char called_num[MAX_NUM_LEN];//被叫號碼
        CALL_ID caller_callid;
        SDP_INFO call_sdp;
    }MAKE_CALL_ST;
隨著需求的增加,這個結構體會越來越大,並且,其中的成員在某些情況下要使用,某些情況下又不使用,造成模組間的冗餘資料。
當然,你也可以採用其他的方法,比如,再多定義幾個介面和結構體。但是這樣的話介面和結構體的數量會呈爆炸式的增長。
使用信元流可以很好的解決這個問題。把號碼,callid,sdp等全部定義成信元,需要的時候塞進去,不需要的話就不添加。另外還有一個好處就是,一個模組可以對外只公布一個介面,來收取信元流,然後在根據信元流的類型進行分別處理。這樣,一個模組對外就只有一個介面了,模組間的耦合性會降低。

一點改進
上面定義的信元流的格式在實際使用的過程中還是碰到了一些問題,最突出的就是,信元流的大小是固定死的。這種情況下,如果信元資訊很小,會導致空間浪費,效率降低;如果信元資訊很多,信元流的空間又不夠。

可以對上面的這種方案進行一下最佳化,把信元的定義更改為:

typedef struct __ELEMENT_ST

     {

          ELE_TAG tag;

          ELE_LEN len;

          ELE_VALUE value;

          ELEMENT_ST  *pnext_ele;//下一個信元流

     }ELEMENT_ST;

將信元流的定義更改為:

        typedef struct __ELEMENT_STREAM_ST
        {
            MOD_ID src_mod;
            MOD_ID des_mod;
            ELE_MSG_TYPE type;
            ELEMENT_ST  *pfirst_ele;//第一個信元流
        }ELEMENT_STREAM_ST;

將信元流和信元更改為動態申請的記憶體。這樣既可以提高效率,有沒有了大小的限制。

需要增加兩個介面,來申請和釋放信元流。

唯一不好的地方時,動態申請的記憶體需要程式員記得釋放,否則會記憶體泄露。不過還有一個方法,即增加一個申請信元流的函數,如下
        ELEMENT_STREAM_ST *GetEleStream()
        {
            static     ELEMENT_STREAM_ST *pstream = NULL;
            if (NULL != pstream)
            {
                FreeEleStream(pstream);   
                pstream = NULL;
            }
            pstream = AllocteEleStream();
            return pstream;
        }

這樣的話,通過函數GetEleStream擷取的信元流,只在函數範圍內有效,退出函數後,立即無效。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.