青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

每天早晨叫醒你的不是鬧鐘,而是夢想

  C++博客 :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
  62 Posts :: 0 Stories :: 5 Comments :: 0 Trackbacks

常用鏈接

留言簿(1)

我參與的團(tuán)隊

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

protobuf簡介

protobuf是google提供的一個開源序列化框架,類似于XML,JSON這樣的數(shù)據(jù)表示語言,其最大的特點是基于二進(jìn)制,因此比傳統(tǒng)的XML表示高效短小得多。雖然是二進(jìn)制數(shù)據(jù)格式,但并沒有因此變得復(fù)雜,開發(fā)人員通過按照一定的語法定義結(jié)構(gòu)化的消息格式,然后送給命令行工具,工具將自動生成相關(guān)的類,可以支持java、c++、python等語言環(huán)境。通過將這些類包含在項目中,可以很輕松的調(diào)用相關(guān)方法來完成業(yè)務(wù)消息的序列化與反序列化工作。

protobuf在google中是一個比較核心的基礎(chǔ)庫,作為分布式運算涉及到大量的不同業(yè)務(wù)消息的傳遞,如何高效簡潔的表示、操作這些業(yè)務(wù)消息在google這樣的大規(guī)模應(yīng)用中是至關(guān)重要的。而protobuf這樣的庫正好是在效率、數(shù)據(jù)大小、易用性之間取得了很好的平衡。

更多信息可參考官方文檔

例子介紹

下載protobuf-2.3.0.zip源代碼庫,下載后解壓,選擇vsprojects目錄下的protobuf.sln解決方案打開,編譯整個方案順利成功。其中有一些測試工程,庫相關(guān)的工程是libprotobuf、libprotobuf-lite、libprotoc和protoc。其中protoc是命令行工具。在example目錄下有一個地址薄消息的例子,業(yè)務(wù)消息的定義文件后綴為.proto,其中的addressbook.proto內(nèi)容為:

package tutorial;

option java_package = "com.example.tutorial";
option java_outer_classname = "AddressBookProtos";

message Person {
  required string name = 1;
  required int32 id = 2;        // Unique ID number for this person.
  optional string email = 3;

  enum PhoneType {
    MOBILE = 0;
    HOME = 1;
    WORK = 2;
  }

  message PhoneNumber {
    required string number = 1;
    optional PhoneType type = 2 [default = HOME];
  }

  repeated PhoneNumber phone = 4;
}

// Our address book file is just one of these.
message AddressBook {
  repeated Person person = 1;
}

該定義文件,定義了地址薄消息的結(jié)構(gòu),頂層消息為AddressBook,其中包含多個Person消息,Person消息中又包含多個PhoneNumber消息。里面還定義了一個PhoneType的枚舉類型。

類型前面有required表示必須,optional表示可選,repeated表示重復(fù),這些定義都是一目了然的,無須多說。關(guān)于消息定義的詳細(xì)語法可參考官方文檔。

現(xiàn)在用命令行工具來生成業(yè)務(wù)消息類,切換到protoc.exe所在的debug目錄,在命令行敲入:

protoc.exe --proto_path=..\..\examples --cpp_out=..\..\examples ..\..\examples\addressbook.proto

該命令中--proto_path參數(shù)表示.proto消息定義文件路徑,--cpp_out表示輸出c++類的路徑,后面接著是addressbook.proto消息定義文件。該命令會讀取addressbook.proto文件并生成對應(yīng)的c++類頭文件和實現(xiàn)文件。執(zhí)行完后在examples目錄生存了addressbook.pb.h和addressbook.pb.cpp。

現(xiàn)在新建兩個空控制臺工程,第一個不妨叫AddPerson,然后把examples目錄下的add_person.cc、addressbook.pb.h和addressbook.pb.cpp加入到該工程,另一個工程不妨叫ListPerson,將examples目錄下的list_people.cc、addressbook.pb.h和addressbook.pb.cpp加入到該工程,在兩個工程的項目屬性中附加頭文件路徑../src。兩個工程的項目依賴都選擇libprotobuf工程(庫)。

給AddPerson工程添加一個命令行參數(shù)比如叫addressbook.dat用于將地址薄信息序列化寫入該文件,然后編譯運行AddPerson工程,根據(jù)提示輸入地址薄信息:


輸入完成后,將序列化到addressbook.dat文件中。

在ListPerson工程的命令行參數(shù)中加讀取文件參數(shù)..\AddPerson\addressbook.dat,然后在運行ListPerson工程,可在 list_people.cc的最后設(shè)個斷點,避免命令行窗口運行完后關(guān)閉看不到結(jié)果:


寫入地址薄的操作,關(guān)鍵操作就是調(diào)用address_book.SerializeToOstream進(jìn)行序列化到文件流。

而讀取操作中就是address_book.ParseFromIstream從文件流反序列化,這都是框架自動生成的類中的方法。

其他操作都是業(yè)務(wù)消息的字段set/get之類的對象級操作,很明了。更詳細(xì)的API參考官方文檔有詳細(xì)說明。

在TCP網(wǎng)絡(luò)編程中的考慮

從上面的例子可以看出protobuf這樣的庫是很方便高效的,那么自然的想到在網(wǎng)絡(luò)編程中用來做業(yè)務(wù)消息的序列化、反序列化支持。在基于UDP協(xié)議的網(wǎng)絡(luò)應(yīng)用中,由于UDP本身是有邊界,那么用protobuf來處理業(yè)務(wù)消息就很方便。但在TCP應(yīng)用中,由于TCP協(xié)議沒有消息邊界,這就需要有一種機(jī)制來確定業(yè)務(wù)消息邊界。在TCP網(wǎng)絡(luò)編程中這是必須面對的問題。

注意上面的address_book.ParseFromIstream調(diào)用,如果流參數(shù)的內(nèi)容多一個字節(jié)或者少一個字節(jié),該方法都會返回失敗(雖然某些字段可能正確得到結(jié)果了),也就是說送給反序列化的數(shù)據(jù)參數(shù)除了格式正確還必須有正確的大小。因此在tcp網(wǎng)絡(luò)編程中,要反序列化業(yè)務(wù)消息,就要先知道業(yè)務(wù)數(shù)據(jù)的大小。而且在實際應(yīng)用中可能在一個發(fā)送操作中,發(fā)送多個業(yè)務(wù)消息,而且每個業(yè)務(wù)消息的大小、類型都不一樣。而且可能發(fā)送很大的數(shù)據(jù)流,比如文件。

顯然消息邊界的確認(rèn)問題和protobuf庫無關(guān),還得自己搞定。在官方文檔中也提到,protobuf并不太適合來作大數(shù)據(jù)的處理,當(dāng)業(yè)務(wù)消息超過1M時,就應(yīng)該考慮是否應(yīng)該用另外的替代方案。當(dāng)然對于大數(shù)據(jù),你也可以分割為多個小塊用protobuf做小塊消息封裝進(jìn)行傳遞。但對很多應(yīng)用這樣的作法顯得比較多余,比如發(fā)送一個大的文件,一般是在接收方從協(xié)議棧收到多少數(shù)據(jù)就寫多少數(shù)據(jù)到磁盤,這是一種邊接收邊處理的流模式,這種模式基本上和每次收到的數(shù)據(jù)量沒有關(guān)系。這種模式下再采用分割成小消息進(jìn)行反序列化就顯得多此一舉了。

由于每個業(yè)務(wù)消息的大小和處理方式都可能不一樣,那么就需要獨立抽象出一個邊界消息來區(qū)分不同的業(yè)務(wù)消息,而且這個邊界消息的格式和大小必須固定。對于網(wǎng)絡(luò)編程熟手,可能早已經(jīng)想到了這樣的消息,我們可以結(jié)合protobuf庫來定義一個邊界消息,不妨叫BoundMsg:

message BoundMsg
{
  required int32 msg_type = 1;
  required int32 msg_size = 2;
}

可以根據(jù)需要擴(kuò)充一些字段,但最基本的這兩個字段就夠用了。我們只需要知道業(yè)務(wù)消息的類型和大小即可。這個消息大小是固定的8字節(jié),專門用來確定數(shù)據(jù)流的邊界。有了這樣的邊界消息,在接收端處理任何業(yè)務(wù)消息就很靈活方便了,下面是接收端處理的簡單偽代碼示例:

if(net_read(buf,8))
{
  boundMsg.ParseFromIstream(buf);
  switch(boundMsg.msg_type)
  {
    case BO_1:
      if(net_read(bo1Buf,boundMsg.msg_size))
      {
        bo1.ParseFromIstream(bo1Buf);
        ....
      }
     break;
    case BO_2:
      if(net_read(bo2Buf,boundMsg.msg_size))
      {
        bo2.ParseFromIstream(bo2Buf);
        ....
      }
     break;

    case FILE_DATA:
      count = 0;
      while(count < boundMsg.msg_size)
      {
        piece_size = net_read(fileBuf,1024);
        write_file(filename,fileBuf,piece_size);
        count = count + piece_size;
      }
      break;
  }
}

注意上面如果FILE_DATA消息后,還緊接其他業(yè)務(wù)消息的話,需要小心,即count累計出的值可能大于

boundMsg.msg_size的值,那么多出來的實際上應(yīng)該是下一個邊界消息數(shù)據(jù)了。為了避免處理的復(fù)雜性,上面所有的循環(huán)網(wǎng)絡(luò)讀取操作(上面BO_1,BO_2都可能需要循環(huán)讀取,為了簡化沒有寫成循環(huán))的緩沖區(qū)位置和大小參數(shù)應(yīng)該動態(tài)調(diào)整,即每次讀取時傳遞的都是還期望讀取的數(shù)據(jù)大小,對于文件的話,可能特殊點,因為邊讀取邊寫入,就沒有必要事先要分配一個文件大小的緩沖區(qū)來存放數(shù)據(jù)了。對于文件分配一個小緩沖區(qū)來讀,注意確認(rèn)下邊界即可。

上面是我的一點考慮,不妥之處還請大家討論交流。想想借助于ACE、MINA這樣的網(wǎng)絡(luò)編程框架,然后結(jié)合protobuf這樣的序列化框架,網(wǎng)絡(luò)編程中技術(shù)基礎(chǔ)設(shè)施層面的東西就給我們解決得差不多了,我們可以真正只關(guān)注于業(yè)務(wù)的實現(xiàn)。


 

posted on 2011-04-05 18:40 沛沛 閱讀(1214) 評論(0)  編輯 收藏 引用 所屬分類: 開源庫
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美一区二区三区免费视频| 在线免费观看日本欧美| 欧美成人亚洲成人| 国产精品久久国产三级国电话系列 | 久久精品视频99| 欧美另类变人与禽xxxxx| 久久婷婷国产综合精品青草| 欧美看片网站| 91久久久久久久久| 精品动漫一区| 香蕉久久精品日日躁夜夜躁| 亚洲天堂av在线免费| 欧美91精品| 欧美国产视频日韩| 激情成人av在线| 欧美影院一区| 久久久久久97三级| 国产美女精品一区二区三区| 正在播放日韩| 午夜久久久久久久久久一区二区| 欧美激情视频一区二区三区免费 | 欧美在线你懂的| 国产精品草莓在线免费观看| 亚洲九九爱视频| 这里只有精品在线播放| 欧美精品一区在线观看| 亚洲国内欧美| 亚洲视频 欧洲视频| 欧美日韩一区二区视频在线观看| 亚洲福利在线看| 日韩视频不卡中文| 欧美日本精品| 亚洲视频精品| 欧美一区二区三区在线视频| 国产精品你懂的| 亚洲欧美日韩国产精品| 久久久久久久久蜜桃| 国产综合久久久久影院| 久久精品视频在线看| 蜜乳av另类精品一区二区| 亚洲人成欧美中文字幕| 欧美日韩国产综合视频在线| 在线亚洲精品| 久久午夜精品| 亚洲三级视频| 国产精品久久久久久妇女6080| 亚洲午夜影视影院在线观看| 久久精品综合一区| 亚洲精品久久久蜜桃| 欧美日韩视频一区二区| 亚洲综合色在线| 欧美大片专区| 亚洲午夜av在线| 国内自拍视频一区二区三区| 美女视频网站黄色亚洲| 日韩视频―中文字幕| 欧美伊人久久| 亚洲激情成人| 国产精品国产三级国产普通话蜜臀 | 性欧美1819性猛交| 亚洲国产成人精品久久| 香港久久久电影| 亚洲国产精品久久91精品| 欧美日韩精品综合| 久久精品国产69国产精品亚洲| 亚洲成人在线视频播放| 亚洲欧美在线网| 亚洲国产美女精品久久久久∴| 欧美视频精品一区| 美女露胸一区二区三区| 午夜精品久久久久影视| 91久久国产综合久久蜜月精品 | 美日韩丰满少妇在线观看| 一本色道久久综合一区| 狠狠爱综合网| 欧美色欧美亚洲另类七区| 久久网站免费| 香蕉乱码成人久久天堂爱免费 | 久久爱www.| 一本久久综合| 亚洲欧洲日本mm| 久久综合五月天婷婷伊人| 亚洲欧美激情一区| 日韩手机在线导航| 在线成人性视频| 国产日韩欧美综合一区| 欧美日韩国产一级片| 久久亚洲精品伦理| 久久精品视频在线播放| 亚洲婷婷在线| 9人人澡人人爽人人精品| 亚洲第一区色| 免费不卡欧美自拍视频| 久久久99免费视频| 亚洲欧美日韩一区二区| 在线视频精品| 一区二区高清视频在线观看| 亚洲国产精品久久91精品| 极品尤物av久久免费看| 国产日韩欧美91| 国产一区二区三区免费在线观看 | 久久久久免费视频| 久久精品一区二区三区不卡牛牛| 亚洲欧美综合网| 新片速递亚洲合集欧美合集 | 亚洲精品影视| 日韩一级免费观看| 日韩视频在线一区二区三区| 亚洲经典自拍| 91久久亚洲| 亚洲精品日韩精品| 亚洲精品一区二区三区99| 亚洲精品少妇30p| 99精品福利视频| 一区二区av| 亚洲综合色丁香婷婷六月图片| 亚洲在线免费观看| 欧美一区二区观看视频| 久久精品人人做人人综合| 久久久久久国产精品一区| 久久偷窥视频| 亚洲国产成人午夜在线一区| 91久久国产综合久久91精品网站| 亚洲理论在线| 亚洲女同在线| 久久精品国产在热久久 | 在线日韩av永久免费观看| 亚洲国产另类精品专区| 日韩视频中午一区| 午夜精品福利视频| 久久深夜福利免费观看| 欧美成人国产va精品日本一级| 亚洲国产日本| 亚洲一区二区三区四区在线观看| 欧美亚洲专区| 欧美福利视频| 国产精品久久夜| 欲香欲色天天天综合和网| 亚洲美女av网站| 香蕉成人啪国产精品视频综合网| 久久久久久尹人网香蕉| 最新69国产成人精品视频免费| 夜夜嗨av一区二区三区网页| 欧美一区二区三区男人的天堂 | 久久午夜激情| 亚洲精品久久| 欧美在线欧美在线| 欧美精品 日韩| 国产一区二区在线观看免费播放 | 亚洲电影下载| 亚洲永久免费| 欧美成人dvd在线视频| 亚洲一区二区av电影| 老司机67194精品线观看| 国产精品初高中精品久久| 伊人影院久久| 欧美一区二区在线免费播放| 欧美激情视频给我| 亚洲欧美中文日韩v在线观看| 欧美不卡高清| 国产亚洲免费的视频看| 亚洲网址在线| 欧美韩日一区二区| 欧美一区观看| 国产精品久久久久9999高清| 亚洲欧洲一区二区三区| 久久久伊人欧美| 亚洲影视在线| 欧美日韩另类一区| 亚洲国内自拍| 浪潮色综合久久天堂| 午夜精品久久99蜜桃的功能介绍| 欧美日韩日日骚| 亚洲欧洲精品一区二区| 麻豆精品91| 久久国产婷婷国产香蕉| 国产精品毛片a∨一区二区三区| 亚洲肉体裸体xxxx137| 免费久久99精品国产自在现线| 欧美一级精品大片| 国产精品美腿一区在线看| 一区二区三区国产在线| 欧美成在线视频| 久久美女性网| 精品999网站| 美女网站久久| 久久午夜av| 亚洲福利在线看| 欧美国产一区在线| 麻豆av福利av久久av| 亚洲成人在线| 欧美国产欧美亚州国产日韩mv天天看完整| 午夜亚洲性色视频| 国产亚洲欧美另类中文 | 亚洲欧美影音先锋| 亚洲一区二区欧美日韩| 国产欧美精品日韩区二区麻豆天美 | 亚洲国产日本| 亚洲国产精品久久久久秋霞蜜臀| 欧美不卡三区|