一種基于樹(shù)狀結(jié)構(gòu)的新型解碼器
摘要:介紹了一種新型解碼器,能夠在數(shù)據(jù)包中解碼出期望KPI的值。在機(jī)站測(cè)試等過(guò)程中,需要查看一些KPI值,而所有KPI是服務(wù)器端以數(shù)據(jù)包的形式發(fā)送到客戶端的。解碼器首先把各個(gè)目標(biāo)KPI按位與,得到總的目標(biāo)值m,然后m與樹(shù)狀結(jié)構(gòu)中的非葉子結(jié)點(diǎn)以及葉子結(jié)點(diǎn)按位與,如果結(jié)果值不等于非葉子結(jié)點(diǎn),則跳過(guò)其子結(jié)點(diǎn),繼續(xù)和其兄弟結(jié)點(diǎn)按位與,直到找到期望KPI。這種方法不用解碼出數(shù)據(jù)包中的全部數(shù)據(jù),即可得到期望的KPI值,簡(jiǎn)便而又高效,大大提高了工作效率。
關(guān)鍵詞:解碼器;數(shù)據(jù)包;樹(shù)狀結(jié)構(gòu);C++;JAVA
0 引言
計(jì)算機(jī)網(wǎng)絡(luò)數(shù)據(jù)通常是以數(shù)據(jù)包進(jìn)行傳輸?shù)模瑪?shù)據(jù)包由報(bào)頭、負(fù)載、報(bào)尾等部分組成。在機(jī)站測(cè)試等過(guò)程中需要經(jīng)常得到大量KPI(Key parameterindicator)的值,而這些KPI是由服務(wù)器以數(shù)據(jù)包的形式發(fā)送到客戶端的,那么如何在以二進(jìn)制表示的數(shù)據(jù)包里面快速而準(zhǔn)確地得到期望的KPI的值呢?在此設(shè)計(jì)了一個(gè)高效而實(shí)用的解碼器,用以快速得到某一字段的KPI值。
1 解碼器簡(jiǎn)介
解碼器源代碼是一些C++代碼,用來(lái)解碼出數(shù)據(jù)包對(duì)應(yīng)的KPI的值。在基站、網(wǎng)絡(luò)等測(cè)試過(guò)程中經(jīng)常需要統(tǒng)計(jì)各種KPI的值,而相關(guān)KPI的值有時(shí)多達(dá)幾十甚至幾百個(gè),如果想要在這龐大的數(shù)據(jù)里面,快速有效地得到一個(gè)或者幾個(gè)KPI的值,普通的方法是把這段碼流進(jìn)行解碼得到全部對(duì)應(yīng)的值之后再查找期望的值。這種方法不僅費(fèi)時(shí)費(fèi)力而且容易出錯(cuò),在此利用一種樹(shù)狀結(jié)構(gòu)的數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)出了解碼特定值的解碼器,用以獲取期望KPI的值。這種解碼器不僅能夠幫助工作人員快速得到期望的KPI值,而且減少出錯(cuò)的幾率,提高了工作效率。
下面介紹一些名詞的含義,消息是指由基本數(shù)據(jù)類(lèi)型表示各種KPI及其組成形式的集合。消息定義文件是指用來(lái)定義諸如XSD、C頭文件、文本文件等消息格式的文件格式。邏輯表是XML格式文件,用來(lái)定義一些無(wú)法用C頭文件描述的邏輯條件。XSD即XML Schema Deftnition,用以規(guī)范和驗(yàn)證XML格式的文檔。
每條信息對(duì)應(yīng)一個(gè)解碼函數(shù),用以解碼數(shù)據(jù)包里面對(duì)應(yīng)的二進(jìn)制流數(shù)據(jù),各種解碼函數(shù)構(gòu)成了解碼器。它不是解碼整條消息,而是有選擇地解碼部分比特流以得到期望的KPI的值,因此它是非常高效的。
端模式(Endian)是指在計(jì)算機(jī)體系結(jié)構(gòu)中存儲(chǔ)信息的不同順序,分為大端(Big-endian)和小端(Little-endian)。大端指數(shù)據(jù)的高位存儲(chǔ)在內(nèi)存的低地址中,而數(shù)據(jù)的低位存儲(chǔ)在內(nèi)存的高地址中,小端則相反。
由于需要解碼不同的消息,而不同的消息具有不同的格式,因此和消息對(duì)應(yīng)的解碼函數(shù)也是不同的,那么就需要根據(jù)不同的消息格式生成相應(yīng)的解碼函數(shù)。在此每條消息用相應(yīng)C頭文件表示,然后根據(jù)C頭文件配置對(duì)應(yīng)的邏輯表。以C頭文件和邏輯表作為輸入,編寫(xiě)Java代碼利用Eclipse生成相應(yīng)的解碼函數(shù)(解碼器)。
軟件最終產(chǎn)品為解碼器,其為具有解碼功能的C++源代碼,能夠有選擇地解碼出想要查看的KPI的值。解碼器的輸入為配置參數(shù)、C頭文件、邏輯表。配置參數(shù)指出了消息的格式、C頭文件的路徑、邏輯表的路徑、生成的解碼器的輸出路徑以及是大端或小端解碼等。程序根據(jù)C頭文件所定義的消息生成XSD文件,其是與C頭文件中的結(jié)構(gòu)體一一對(duì)應(yīng)的,然后根據(jù)產(chǎn)生的XSD文件、邏輯表以及配置參數(shù)生成解碼器。其數(shù)據(jù)流程圖如圖1所示。
2 編碼方法
每條消息都可由相應(yīng)的結(jié)構(gòu)體表示,這些結(jié)構(gòu)體位于C頭文件中,可以寫(xiě)成樹(shù)狀結(jié)構(gòu)的形式。假設(shè)某條消息如圖2所示,由以下結(jié)構(gòu)體表示:其中A p、B p和C p處于同一層,root為根結(jié)構(gòu)體,包含了A p、B p和C p結(jié)構(gòu)體?;緮?shù)據(jù)類(lèi)型包括整形、字符型、位域等,為葉子結(jié)點(diǎn),非基本類(lèi)型數(shù)據(jù)包括結(jié)構(gòu)體數(shù)組、聯(lián)合等,為非葉子結(jié)點(diǎn)。在此,這條消息可由樹(shù)狀結(jié)構(gòu)來(lái)表示,如圖3所示,root根結(jié)點(diǎn)表示為0000 0000,A結(jié)點(diǎn)表示為0000 0001,a1表示為0001 0001;B結(jié)點(diǎn)表示為0000 0010,b1表示為0001 0010,b2表示為0010 0010;C[0]表示為00000 100,c1表示為0001 0100,c2表示為0010 0100,c3表示為0100 0100;C表示為0000 1000,c4表示為0001 1000,c5表示為0010 1000,c6表示為01001000??梢?jiàn)root、A、B、C[0]、C[1]為非葉子結(jié)點(diǎn),是非基本數(shù)據(jù)類(lèi)型,其余是葉子結(jié)點(diǎn),是基本數(shù)據(jù)類(lèi)型。我們稱(chēng)root為A、B、C[0]和C[1]的父結(jié)點(diǎn),A是a1的父結(jié)點(diǎn),B是b1和b2的父結(jié)點(diǎn),以此類(lèi)推。注意到,每個(gè)父結(jié)點(diǎn)和其子結(jié)點(diǎn)位與()的結(jié)果值都為父結(jié)點(diǎn),例如:root(0000 0000)A(0000 0001)=root(0000 0000),A(0000 0001)a1(0001 0001)=A(0000 0001),B(0000 0010)b2(0010 0010)=B(00 00 0010)。由此,若要取KPI b2和c4的值,那么傳入的目標(biāo)值為m=b2 |(位或)c4=0011 1010,讓目標(biāo)值依次與某結(jié)點(diǎn)位與(&),如果結(jié)果值等于某結(jié)點(diǎn),那么說(shuō)明某結(jié)點(diǎn)的子結(jié)點(diǎn)包含或者是目標(biāo)值,例如m(0011 1010)&B(0000 0010)=B(0000 0010),又已知B是非葉子結(jié)點(diǎn),故B的子結(jié)點(diǎn)中必定包含目標(biāo)結(jié)點(diǎn),然后m依次與b1和b2按位與,mb1 b1,又知b1是葉子結(jié)點(diǎn),故b1不是要解的目標(biāo)值,則跳過(guò)b1,繼續(xù)解b1的兄弟b2,顯然,mb2=b2,又知b2是葉子結(jié)點(diǎn),故b2是要解的目標(biāo)值,以此可得到c4也為目標(biāo)值。又mA A,又知A是非葉子結(jié)點(diǎn),故可把A結(jié)點(diǎn)以下的子結(jié)點(diǎn)跳過(guò)不解,以此類(lèi)推,C[1]及其子結(jié)點(diǎn)也可以跳過(guò)不解,那么這就大大提高了解碼的效率。
有時(shí)候存儲(chǔ)信息不需要一個(gè)完整的字節(jié),只需要占一個(gè)或幾個(gè)二進(jìn)制位,這種存儲(chǔ)信息的方式稱(chēng)為位域。當(dāng)消息里面包含位域的時(shí)候,由于不同的機(jī)器可能是大端或者小端。那么就需要定義是按照大端解碼還是按照小端解碼。
3 模塊設(shè)計(jì)
系統(tǒng)分為初始化、XSD轉(zhuǎn)換、XSD解析、XSD訪問(wèn)等四個(gè)模塊。
初始化模塊主要進(jìn)行參數(shù)配置,然后開(kāi)始運(yùn)行Eclipse生成解碼器。需要配置的參數(shù)有:消息名稱(chēng)、C頭文件路徑、邏輯表路徑、解碼器輸出路徑、端類(lèi)型等。
XSD轉(zhuǎn)換模塊主要進(jìn)行C頭文件定義的結(jié)構(gòu)體的解析,并生成XSD文件。
XSD解析模塊將XSD文件解析成XSD素對(duì)象。這里采用DOM方式進(jìn)行解析XSD文件,DOM(文檔對(duì)象模型)定義了層次化模型來(lái)表示XSD文檔,對(duì)應(yīng)XSD中的每一個(gè)元素定義一個(gè)相應(yīng)的類(lèi)與其一一映射。解析時(shí)讀入整個(gè)XSD文件,然后在內(nèi)存構(gòu)建一個(gè)樹(shù)狀結(jié)構(gòu),每遇到一個(gè)元素就實(shí)例化一個(gè)元素對(duì)象。XSD元素對(duì)象分為根元素、結(jié)構(gòu)體元素和葉子元素。根元素為整個(gè)XSD文件,如圖3中的root,結(jié)構(gòu)體元素為XSD文件的非葉子結(jié)點(diǎn),如圖3中的A、C[0]等,葉子元素為XSD文件的葉子結(jié)點(diǎn),其存儲(chǔ)了具體的KPI的值,如圖3中的a1等。
XSD訪問(wèn)模塊的功能是在XSD對(duì)象中查詢(xún)邏輯表中的數(shù)據(jù),并生成解碼器。
邏輯表主要是用來(lái)表示在C頭文件中不能表示的邏輯情況,在此有三類(lèi)常見(jiàn)的邏輯。通常在一個(gè)union里面有多個(gè)元素,在解碼原始數(shù)據(jù)流時(shí)要選擇正確的元素,那么,就必須有一個(gè)指引元素,其指明了哪一個(gè)元素是被選擇的。如果這個(gè)指引元素是在union外,那么就稱(chēng)其為key out union,相反則稱(chēng)其為key in union。如果我們要解碼的KPI是一個(gè)變長(zhǎng)數(shù)組,那么顯然在C頭文件中是沒(méi)有辦法描述的,在此我們定義一個(gè)變量專(zhuān)門(mén)用來(lái)定義變長(zhǎng)數(shù)組的長(zhǎng)度,稱(chēng)其為variable length array。在某種條件下在數(shù)據(jù)流中有的數(shù)據(jù)是沒(méi)有意義的,那么就需要我們定義一個(gè)變量來(lái)決定其是否有意義,我們稱(chēng)這樣的變量為optional。
4 結(jié)束語(yǔ)
針對(duì)數(shù)據(jù)包中的大量數(shù)據(jù),解碼器利用樹(shù)狀結(jié)構(gòu)的編碼規(guī)則可以快速找到期望的KPI的值,這種對(duì)信息提取的高效性,可以大大提高工作效率,增加效益。此解碼器不僅可以單獨(dú)用來(lái)對(duì)數(shù)據(jù)包里面的數(shù)據(jù)進(jìn)行提取,也可以和其它軟件一起構(gòu)成一個(gè)小型測(cè)試系統(tǒng)等。
評(píng)論