Protocol Buffers在數據採集與傳輸系統建設方式論文
隨着通信技術和傳感器技術的不斷髮展,數據採集與傳輸系統得到了越來越廣泛的應用。而Google Protocol Buffers是Google公司開發是一款非常優秀的庫,其定義了緊湊的、可擴展的二進制消息格式,特別適合用於數據傳輸。本文着重介紹了使用Protocol Buffers的對數據的封裝和其反射機制來實現數據採集與傳輸系統的快速擴展采集數據類型。
1 Protocol Buffers概述
1.1 簡介
Protocol Buffers(以下簡稱ProtoBuf)是由Google開發的一種數據描述語言。ProtoBuf定義了一種緊湊的可擴展二進制消息格式,能對結構化的數據進行靈活的、高效的、自動的機制來進行序列化。ProtoBuf可擴展方式的序列化結構數據被廣泛應用在通信協議、數據存儲等領域。
1.2 ProtoBuf的性能
一條消息數據,用ProtoBuf序列化後的大小是JSON的十分之一,是XML格式的二十分之一,是二進制序列化的十分之一。總體看來ProtoBuf的優勢還是非常明顯的。
2 應用在數據採集與傳輸系統中
這裏所設計的數據採集與傳輸系統採用Slave-Master結構。其中Slave負責採集數據並將數據發送給Master;Master接收所採集的數據並做進一步處理。Slave可以支援多種數據類型(如GPS、圖像等)的採集。
2.1 根據不同的採集數據類型,編寫proto檔案
在ProtoBuf中,所有的對象都被視爲消息。消息的每個屬性描述都可以使用required、optional、repeated來進行描述。ProtoBuf數據描述語言中也支援一些基本的數據類型如string、int32、double等等。
設Slave的採集數據類型有Type1、Type2。這兩種類型的Proto描述命名爲MsgType1和MsgType2(圖1所示)。
經proto編譯後,生成的消息類爲MsgType1和MsgType2,它們均繼承自google::protobuf::Message類。
2.2 設計支援不同採集數據類型的數據傳輸格式
在數據傳輸中使用ProtoBuf需要解決兩個問題,一是數據的.長度:ProtoBuf打包的數據沒有自帶長度資訊或終結符,這就需要由應用程序自己在發生和接收的時候做正確的分割;二是消息類型:ProtoBuf打包的數據沒有自帶的類型資訊,在消息傳輸過程中,發送方需要將消息類型告訴接收方,接收方根據消息類型再做反序列化。對於長度問題,可以將長度資訊作爲消息的一個段來解決。而對於消息類型問題,可以使用ProtoBuf根據消息的類型名反射自動創建對應的消息對象的機制來解決。因此,可以設計基本傳輸格式的格式如圖2所示:
ProtoBuf Message的序列化數據封裝在message_data中,且稱這種數據格式爲Message Package(消息包)。
2.3 消息打包器的設計
消息包格式設計完後,首先要對不同的採集數據類型編寫封裝函數,以便將相應類型的數據封裝到對應的ProtoBuf Message中。然後使用消息打包器將Slave所採集的某種類型的數據資訊打包成上圖的消息包。消息打包器先透過ProtoBuf將特定類型的採集數據進行序列化,並生填充Message Data。最後再填充Message Package中的Length 、Message Name等字段,完成消息的打包操作。消息打包器代碼如下:
std::string CreateMsgPackage( const google::protobuf::Message& msg )
{
std::string msg_pack;
msg_ze( sizeof( int32_t ) );
string& msg_name = ypeName();
int32_t name_len = msg_()+1;
msg_nd((char*)&name_len,sizeof(name_len));
msg_nd(msg_name.c_str(),name_len);
ndToString(&msg_pack);
char* begin = msg_pack.c_str()+sizeof( int32_t );
int32_t length = msg_()-sizeof(int32_t);
std::copy( (char*)( &length ), (char*)( Length ) +
sizeof( Length ), msg_n );
return msg_pack;
}
2.4 消息解包器的設計
接收到消息包之後要進行解封裝,分解出消息包中的各個字段,這裏不再詳述。ProtoBuf本身具有很強的反射機制,ProtoBuf可以能根據Message Name創建一個該類型的消息,然後使用Message Data來反序列化該消息,從而在Message Package中恢復出相應類型的Message,由此完成對消息的識別。由消息包來還原相應的消息的代碼如下:
Message* CreateMsg( std::string& msg_pack )
{
// 從msg_pack中分離msg_name、msg_data等的代碼從略
Message* msg = NULL;
Descriptor* desc = DescriptorPool::generated_pool()->FindMessageTypeByName(msg_name);
Message* prototype = MessageFactory::generated_factory()->GetPrototype(desc);
msg = prototype->New();
msg->ParseFromArray(msg_data, msg_data_len);
return msg;
}
2.5 消息分發器的設計
Master在得到相應類型的採集數據消息後,需要傳遞給相應的消息處理方法,這就涉及到消息的分發。消息分發器可以使用map來實現,由於每個具體消息類型都有一個全局的Descriptor對象,其地址是唯一的,可作爲key;value爲針對特定採集數據類型消息的處理函數,即std::map,其中MessageCallBack爲 boost::function。由於消息分發器傳給處理函數的參數是Message*類型,處理函數需要對其進行向下轉型後才能使用。消息分發器在接收到某一消息後,在map中查找對應的處理函數,並執行該函數。
2.6 整體結構
在Slave端,用戶需要使用proto數據描述語言描述該類型的數據,併產生相應的Message類型,此外用戶還要編寫相應數據類型消息封裝方法。在Master端,由於與Slave使用相同的proto檔案,消息解包器可以分辨出相應類型的Message。用戶在Master端需要編寫針對某具體類型採集數據的處理方法,並向消息分發器註冊。消息分發器將消息解包器解出的消息作爲參數調用對應的處理方法。
3 結束語
在Slave-Master結構的系統中透過編寫proto檔案來描述各種類型的採集數據;在Slav e端進行採集數據的序列化和封裝;在Master端編寫對應的採集數據處理方法,並將該方法註冊到Master的消息分發器中,完成對採集數據類型的快速擴展。
Protocol Buffers s://
陳碩x多線程服務端編程——使用muduo C++網絡庫.北京:電子工業出版社.2013:220-236.
李紀欣,王康,周立法,章軍le Protobuf在Linux Socket通訊中的應用.電腦開發與應用.2013,26(4).
田源,潘晨光,丁傑ocol Buffers在即時通訊系統中的應用研究 .現代電子技術.2013,37(5)
-
小學低年級語文自主學習能力的培養論文
摘要:語文是學生在學習階段的重要課程之一,而僅僅依靠教師在課堂上的講解,往往不能爲學生語文綜合素養的提升提供充足的動力,因此,如何從小培養學生在語文學科的自主學習能力,已經成爲衆多語文教育工作者共同關注的問題。小學低年級是學生對語文形成認知的初級階段,同...
-
研究針對雲服務的混合防火牆技術論文
摘要:對於網絡服務以及應用,防火牆是第一道防線.儘管透過現有的方法能夠顯著增強系統的安全性,但很多研究也證明了傳統防火牆的侷限性.隨着虛擬化和雲計算的出現,基於網絡的服務呈現爆炸式的增長.面向雲服務,利用無固有邊界的虛擬化的雲來構建虛擬防火牆,存在安...
-
基於茶文化的空間環境設計分析論文
摘要:作爲傳統文化絢麗的瑰寶,茶文化依靠着自身內涵茶文化在空間環境設計中佔據重要地位。長久以來,茶文化對空間環境設計有巨大而深遠的影響,在其設計應用過程中,不僅能豐富空間環境設計的形式,還能給其設計帶來獨特性,賦予空間環境特殊的人文價值。本文以傳統茶文化...
-
分析英語教學中文化教學的實施和作用論文
當下世界各國之間的經濟文化交流越來越頻繁,英語所起作用也越來越大,各高校也普遍重視英語教學水平的提升。要想幫助英語學習和提高教學的質量,最有效的方法就是將文化教學融入到英語教學當中,讓學生透過文化感受到英語的魅力,培養學生對英語學習的興趣,提高英語的綜...