自定義應用層通信協議

 

標籤:通信協議 要素 

1.通信協議的概念及其要素

在OSI開放互聯參考模型中,對等實體之間數據單元在發送方逐層封裝,在接收方的逐層解析。發送方N層實體從N+1層實體得到的數據包稱爲服務數據單元(Service Data Unit,SDU)。N層實體只將其視爲需要本實體提供服務的數據,將服務數據單元進行封裝,使其成爲一個對方能夠理解的數據單元(Protocol Data Unit,PDU),封裝過程實際上是爲SDU增加對等實體間約定的控制信息(Protocol Control Information,PCI)的過程。

爲了保證網絡的各個功能的相對獨立性,以及便於實現和維護,通常將協議劃分爲多個子協議,並且讓這些協議保持一種層次結構,子協議的集合通常稱爲協議簇。

網絡協議的分層有利於將複雜的問題分解成多個簡單的問題,從而分而治之。各層的協議由各層的實體實現,通信雙方對等層中完成相同協議功能的實體稱爲對等實體。對等實體按協議進行通信,所以協議反映的是對等層的對等實體之間的一種橫向關係,嚴格地說,協議是對等實體共同遵守的規則和約定的集合。

通信協議精確地定義了雙方通信控制信息和解釋信息:發送方能將特定信息(文本、圖片、音頻、視頻)按協議封裝成指定格式的數據包,最終以串行化比特流在網絡上傳輸;接收方接收到數據包後,根據協議將比特流解析爲本地化數據,從而獲取對方發送過來的原始信息。

通信協議包括三個要素:

(1)語法:規定了信息的結構和格式;

(2)語義:表明信息要表達的內容;

(3)同步:規則涉及雙方的交互關係和事件順序。

整個計算機網絡的實現體現爲協議的實現,TCP/IP協議是Internet互聯網的核心協議。

2.通信協議開發步驟

(1) 協議的開發主要包括協議設計、協議形式描述、協議實現和協議一致性測試。協議的開發過程與步驟如圖1所示。

    圖1 協議開發過程與步驟

(2) 協議設計過程中的分組發送接收模型如圖2所示。

圖2協議設計過程中的分組發送接收模型

(3)協議的一致性測試

協議的一致性測試是指測試協議能否按照預想的控制策略實現正確的通信,主要體現在數據包通過信道從信源傳送到信宿後,信宿能夠根據協議正確的解析出原始信息。

協議的一致性測試如圖3所示。

圖3 協議一致性測試環境

根據測試環境的可以分爲局部測試和分佈式測試,如圖4所示。

圖4局部測試法、分佈式測試法

3.數據包和數據報

爲方便描述自定義協議,還是借用數據包和數據報來描述封裝數據單元和傳輸數據單元,但這裏的數據包和數據報完全不同於TCP/IP架構中的Packet和Datagram概念。

下文所述的數據包指封裝的基本單位,以TLV(Type-Length-Value)格式封裝基本消息單位;數據報Package是傳輸的基本單位,頭部包含序列號和命令信息。接收端根據命令信息分辨事件類型,做出不同的解析。報文實體是多個TLV數據包組成的鏈表。

 

 

 

4.數據包TLV的設計

從應用層HTTP協議,到超文本置標語言HTML(HyperText Mark-up Language),再到可擴展置標語言XML(Extensible Markup Language),它們提供了數據的格式化存儲、傳輸和格式化顯示的規範,是網絡通信的基石。然而HTTP協議以及HTML/XML置標語言的本質就是定義一堆標籤(Tag)對數據進行串行化序列化,然後接收方再根據標籤解析、還原數據。

自定義通信協議的關鍵是對數據包的合理構造(construct)和正確解析(parse),即制定編解碼規則。

抽象語法標記ASN(Abstract Syntax Notation) BER的長度確定的編碼方式,由3部分組成Identifier octets、Length octets和Contents octets,實際上這就是一中TLV(Type-Length-Value)模型:類型字段(Type或Tag)是關於標籤和編碼格式的信息;長度字段(Length)定義數值的長度; 內容字段(Value)表示實際的數值。

因此,一個編碼值又稱TLV三元組。編碼可以是基本型或結構型,如果它表示一個簡單類型的、完整的顯式值,那麼編碼就是基本型(primitive);如果它表示的值具有嵌套結構,那麼編碼就是結構型 (constructed)。

TLV編碼就是指對Type(Tag)、Length和Value進行編碼,形成比特流數據包;解碼是編碼的逆過程,是從比特流緩衝區中解析還原出原始數據。

採用C++編程語言設計TLV協議類,其類視圖如圖5所示。

圖5 CTLV類視圖

目前只提供設置整形值(int型)的setValue_Int和設置字符串值(C_String型)的SetValue_Cstring兩個接口。

TLV將數據封裝成包的格式如表1所示。

表1 TLV包格式

TLV包

頭部

包實體

m_dwTag

m_nLen

m_pValue

     

TLV的接口說明:

(1)值類型標籤m_vtTag是內部輔助枚舉變量,它根據構造TLV時傳遞的服務類型標籤m_dwTag來確定。

(2)TLV::m_nLen在爲TLV設置具體值時確定。

(3)TLV包的封裝:

1)使用Tag參數創建一個TLV對象後,調用TLV::setValue_*方法爲TLV填充具體值;

2)調用TLV::toBuffer方法打包到緩衝區streamBuffer。

(4)TLV包的解析:創建一個TLV對象後,調用TLV::fromBuffer方法從緩衝區streamBuffer解析出TLV。

(5)封裝和解析涉及到本機字節順序和網絡字節順序的轉換問題。

(6)調用TLV::setValue_*方法填充TLV時,統一字節邊界數爲4。

5.數據報Package的設計

不同於底層的數據包/數據報只是對數據層次的封裝解析,實際應用程序是以事件驅動的,因此必須註冊不同的信令(事件類型標籤),然後填充到數據報中。接收端根據信令做出相應的事件處理。

例如在C/S通信系統中,客戶端往往要先登錄,通過服務器端的校驗才能進行後續通信。因此客戶端運行後,需要構造並向服務器端發送含有LOGIN信令的包含用戶名字符串strUserName和密碼字符串strPassWord的數據報;服務器端解析LOGIN信令後做校驗處理,然後發送含有LOGIN_RESPONSE信令和校驗結果的回執數據報給客戶端。

採用C++編程語言設計Package類,其類視圖如圖6所示。

圖6 CPackage類視圖

Package類將TLV封裝成包的格式如表2所示。

表2 Package包格式

Package包

頭部

序列號

包實體

m_nCmdLen

m_dwCmdID

m_dwCmdState

m_nSeqNo

Count*Tlv

         

Package的接口說明:

(1)Package::m_nCmdLen是整個Package包的長度,將其作爲首個字段的好處在於當傳送大數據包時,接收方可以根據數據長度來控制讀狀態,從而將一個大數據包分批接收。

(2)Package::m_nCmdLen在構造函數中初始化爲16,在調用Package::addTLV方法填充包實體時增長。

(3)Package包的封裝:

1)創建Package對象後,調用Package::setHeader方法填充頭部信令;

2)創建TLV對象並填充數據,再調用Package::addTLV方法填充包實體;

3)調用Package::toBuffer方法將Package打包到緩衝區streamBuffer。

(4)Package包的解析:

1)先創建一個Package對象,調用Package::fromBuffer方法從緩衝區streamBuffer先解析出Package的頭部和序列號,再從剩餘緩衝區中解析出TLV並將其串行化到鏈表。

2)調用Package::getTLV方法根據Tag從鏈表中查找具體TLV包,再調用TLV::getValue方法取得具體值。

(5)Package::toBuffer方法和Package::fromBuffer方法主要遍歷Package::m_TLV_List列表,然後調用TLV::toBuffer方法和TLV::fromBuffer方法解析出TLV數據單元。

TLV數據包的功能測試(主要是本地測試)

鑑於實際通信數據最後都要轉換成比特流,故只測試發送字符串類型的變量,僅測試協議能否正確打包、解析。其他類型的普通數據都可以轉換成字符串傳輸,最後,接收方根據m_dwTag確定值類型m_vtTag,解析出具體值。

對TLV::setValue_C_String方法填充TLV的測試,需要考慮字節對齊問題。對於長度爲4字節倍數的C狀態字符串,打包時省去末尾的‘/0’結束標誌符。需要測試長度非4倍數的字符串和長度爲4倍數的字符串。

經本地測試,調用TLV::setValue_Int方法和TLV::setValue_C_String方法構造整形和字符串時,能夠正確封裝、正確解析。

Package數據報的功能測試,主要是將TLV組合成包,然後添加信令,完成特定的通信。對登陸LOGIN和發送消息SUBMIT_SM的測試表明Package協議能正確封裝、正確解析。

在實際項目中使用Package通信協議,對於稍大一點的數據塊需要控制好讀的步驟,以便能接收整包完整的信息。

參考:

《計算機網絡協議和實現技術》 魯士文

轉載自http://blog.csdn.net/zhanghefu/article/details/5163963
發佈了31 篇原創文章 · 獲贊 2 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章