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

牽著老婆滿街逛

嚴(yán)以律己,寬以待人. 三思而后行.
GMail/GTalk: yanglinbo#google.com;
MSN/Email: tx7do#yahoo.com.cn;
QQ: 3 0 3 3 9 6 9 2 0 .

Protobuf和FlatBuffers以及ByteBuffer的應(yīng)用

Protobuf版本號:3.1.0
FlatBuffers版本號:1.4.0



Protobuf

首先來一發(fā)pb3的IDL代碼Helloworld.proto
syntax = "proto2";

package proto.helloworld;

message HelloWorld
{
    required int32 id = 1;        // id
    required string str = 2;    // str
    optional int32 opt = 3;        // optional field
}

使用命令行或者編寫一個bat批處理文件
@set path=..\..\..\..\third_party\protobuf\bin\release;%path%
@cls

:: /////////////////////////////////////////////////////////////
::
:: 編譯Protobuf協(xié)議
::
:: /////////////////////////////////////////////////////////////
protoc --version

protoc --cpp_out=../ ./Helloworld.proto

pause
執(zhí)行以上的批處理文件,將會在其目錄的上一層目錄下生成兩個源碼文件:Helloworld.pb.h和Helloworld.pb.cc.
將生成的這倆文件拖進(jìn)工程里面去,至于vc的StdAfx,預(yù)編譯頭的問題,很好解決.在cc文件上點右鍵->屬性->C/C++->預(yù)編譯頭->預(yù)編譯頭(不使用預(yù)編譯頭),這事兒就妥妥的解決了.

以下列舉序列化到三種目標(biāo)里去的實例
1.std::string
void testString()
{
    //////////////////////////////////////////////////////////////////////////
    // 編碼
    //////////////////////////////////////////////////////////////////////////
    proto::helloworld::HelloWorld msg_encode;
    msg_encode.set_id(10086);
    msg_encode.set_str("hello world");
    msg_encode.set_opt(10000);

    std::string str_data;
    bool encode_ok = msg_encode.SerializeToString(&str_data);
    ASSERT(encode_ok);

    //////////////////////////////////////////////////////////////////////////
    // 解碼
    //////////////////////////////////////////////////////////////////////////
    proto::helloworld::HelloWorld msg_decode;
    bool decode_ok = msg_decode.ParseFromString(str_data);
    ASSERT(decode_ok);
    size_t n = str_data.length();

    ASSERT(msg_decode.id() == 10086);
    ASSERT(msg_decode.str().compare("hello world") == 0);
    ASSERT(msg_decode.opt() == 10000);
}

2.ByteArray(char [])
void testByteArray()
{
    //////////////////////////////////////////////////////////////////////////
    // 編碼
    //////////////////////////////////////////////////////////////////////////
    proto::helloworld::HelloWorld msg_encode;
    msg_encode.set_id(10086);
    msg_encode.set_str("hello world");
    msg_encode.set_opt(10000);

    char msg_buf[1024];
    ZeroMemory(msg_buf, sizeof(msg_buf));
    bool encode_ok = msg_encode.SerializeToArray(msg_buf, sizeof(msg_buf));
    ASSERT(encode_ok);
    int encode_size = msg_encode.ByteSize();

    //////////////////////////////////////////////////////////////////////////
    // 解碼
    //////////////////////////////////////////////////////////////////////////
    proto::helloworld::HelloWorld msg_decode;
    bool decode_ok = msg_decode.ParseFromArray(msg_buf, encode_size);
    ASSERT(decode_ok);

    ASSERT(msg_decode.id() == 10086);
    ASSERT(msg_decode.str().compare("hello world") == 0);
    ASSERT(msg_decode.opt() == 10000);
}

3.std::fstream
void testStream()
{
    //////////////////////////////////////////////////////////////////////////
    // 編碼
    //////////////////////////////////////////////////////////////////////////
    proto::helloworld::HelloWorld msg_encode;
    msg_encode.set_id(10086);
    msg_encode.set_str("hello world");
    msg_encode.set_opt(10000);

    std::fstream output("./msg_bin", std::ios::out | std::ios::trunc | std::ios::binary);
    bool encode_ok = msg_encode.SerializeToOstream(&output);
    ASSERT(encode_ok);
    output.close();

    //////////////////////////////////////////////////////////////////////////
    // 解碼
    //////////////////////////////////////////////////////////////////////////
    std::fstream input("./msg_bin", std::ios::in | std::ios::binary);
    proto::helloworld::HelloWorld msg_decode;
    bool decode_ok = msg_decode.ParseFromIstream(&input);
    ASSERT(decode_ok);

    ASSERT(msg_decode.id() == 10086);
    ASSERT(msg_decode.str().compare("hello world") == 0);
    ASSERT(msg_decode.opt() == 10000);
}
以上就是ProtoBuf的基本用法了.


FlatBuffers

FlatBuffers支持將ProtoBuf的IDL轉(zhuǎn)換為自己的IDL,只需要簡單的一行命令:
flatc.exe --proto Helloworld.proto
該命令將會生成一個FlatBuffers的IDL文件:Helloworld.fbs.

Helloworld.fbs它看起來像是這樣的:
// Generated from Helloworld.proto

namespace fbs.helloworld;

table HelloWorld {
  id:int = 0 (id: 0);
  str:string (required, id: 1);
  opt:int = 0 (id: 2);
}

// 定義之后將會提供GetHelloWorld,VerifyHelloWorldBuffer,FinishHelloWorldBuffer三個方法.
root_type HelloWorld;
這是我基于生成的IDL修改過的.

我們可以用下面這個bat去生成代碼:
flatc.exe --cpp -o ../ Helloworld.fbs
pause
執(zhí)行之后,它將在當(dāng)前目錄的上一層目錄下生成一個代碼文件:Helloworld_generated.h

使用方法大概是這樣的:
void testFlatBuffer()
{
    //////////////////////////////////////////////////////////////////////////
    // 編碼
    //////////////////////////////////////////////////////////////////////////

    flatbuffers::FlatBufferBuilder builder;

    int32_t id = 10086;
    const char *str = "hello world";
    int32_t opt = 10000;

#if 0
    auto strName = builder.CreateString(str);
    auto root = fbs::helloworld::CreateHelloWorld(builder, id, strName, opt);
#else
    auto root = fbs::helloworld::CreateHelloWorldDirect(builder, id, str, opt);
#endif

#if 0
    builder.Finish(root);
#else
    FinishHelloWorldBuffer(builder, root);
#endif

    auto p = builder.GetBufferPointer();
    auto sz = builder.GetSize();

    auto bufferpointer =
        reinterpret_cast<const char *>(builder.GetBufferPointer());
    std::string buffer;
    buffer.assign(bufferpointer, bufferpointer + builder.GetSize());
    size_t n = buffer.length();

    builder.ReleaseBufferPointer();

    //////////////////////////////////////////////////////////////////////////
    // 解碼
    //////////////////////////////////////////////////////////////////////////
#if 0
    auto decode = flatbuffers::GetRoot<proto::helloworld::HelloWorld>(buffer.c_str());
#else
    auto decode = fbs::helloworld::GetHelloWorld(buffer.c_str());
#endif
    assert(decode->id() == 10086);
    assert( strcmp(decode->str()->c_str(), "hello world") == 0);
    assert(decode->opt() == 10000);
}



ByteBuffer
關(guān)于這個嘛,看以前的文章:http://m.shnenglu.com/tx7do/archive/2015/06/12/145865.html
協(xié)議定義如下:
#include "ByteBuffer.h"

// 聲明序列化
#define NET_APPEND(STRUCT_TYPE)\
    static ByteBuffer& operator<<(ByteBuffer& lht, const STRUCT_TYPE& rht)

// 聲明解序列化
#define NET_READ(STRUCT_TYPE)\
    static const ByteBuffer& operator>>(const ByteBuffer& lht, STRUCT_TYPE& rht)

namespace bb
{
    namespace helloworld
    {

        struct CMD_HelloWorld
        {

            int32            id;        // id
            std::string        str;    // str
            int32            opt;    // optional field

            CMD_HelloWorld()
            {
                this->id = 0;
                this->opt = 0;
                this->str.clear();
            }
        };
        NET_APPEND(CMD_HelloWorld)
        {
            lht << rht.id
                << rht.str
                << rht.opt;
            return lht;
        };
        NET_READ(CMD_HelloWorld)
        {
            lht >> rht.id
                >> rht.str
                >> rht.opt;
            return lht;
        };


    }
}
使用的代碼是這樣的:
void testByteBuffer()
{
    //////////////////////////////////////////////////////////////////////////
    // 編碼
    //////////////////////////////////////////////////////////////////////////
    bb::helloworld::CMD_HelloWorld msg_encode;
    msg_encode.id = 10086;
    msg_encode.str = "hello world";
    msg_encode.opt = 10000;

    ByteBuffer sendBuffer;
    sendBuffer.clear();
    sendBuffer << msg_encode;
    
    auto p = sendBuffer.contents();
    auto sz = sendBuffer.size();
    
    //////////////////////////////////////////////////////////////////////////
    // 解碼
    //////////////////////////////////////////////////////////////////////////
    ByteBuffer recvBuffer;
    recvBuffer.clear();
    recvBuffer.append((uint8*)p, sz);
        bb::helloworld::CMD_HelloWorld msg_decode;
    recvBuffer >> msg_decode;

    assert(msg_decode.id == 10086);
    assert(strcmp(msg_decode.str.c_str(), "hello world") == 0);
    assert(msg_decode.opt == 10000);
}


總結(jié)
相比PB來說,FBS不需要額外的指定一個外部的緩存,它內(nèi)置了一個緩存,大概這就是它快的緣故吧.
序列化之后的空間占用結(jié)果是:protobuf:19 flatbuffers:48 bytebuffer:20.
從空間上看,FBS是并不占優(yōu)啊.
以前,一直使用的是ByteBuffer,因為簡單,而且無論是從空間上還是時間上都還算劃算.但是要手寫序列化的代碼,相對來說,比較煩人.所以還是PB,FBS這樣的利用IDL自動生成代碼的方式方便.
PB現(xiàn)在支持幾乎所有語言,是一個相當(dāng)成熟的解決方案了.
FBS就目前來說,支持的語言并不多,官方只支持:C++,Java,C#,Go,Python,JS,C,PHP,Ruby.
PB的IDL各大編輯器幾乎都支持它的語法染色,然而FBS卻并沒有,這個看起來也很讓人蛋疼.
PB相對慢,但是空間占用小,它更適合外網(wǎng)傳輸,并且對時間并不是那么要求高的應(yīng)用;
FBS相對快,但是空間占用較大,它在RPC,內(nèi)網(wǎng)傳輸,以及對時間要求很高的場景上會很適合,在手機(jī)登移動平臺下,計算性能不高的場景下也是適合的.
總的來說,我要做網(wǎng)游的通訊協(xié)議,還是PB更加的適合.
FBS更適合的是Android,iOS這樣的移動平臺,因為它們對性能要求比較高,使用FBS能夠有效的提高性能.

posted on 2016-11-20 15:22 楊粼波 閱讀(2829) 評論(0)  編輯 收藏 引用


只有注冊用戶登錄后才能發(fā)表評論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            免费成人毛片| 欧美性事免费在线观看| 欧美激情一区二区三区不卡| 性欧美18~19sex高清播放| 快射av在线播放一区| 欧美在线播放一区二区| 久久国产精品久久精品国产| 久久久噜噜噜| 欧美激情欧美狂野欧美精品| 欧美日韩日本视频| 国产麻豆精品视频| 在线精品国精品国产尤物884a| 娇妻被交换粗又大又硬视频欧美| 欧美成人精品在线播放| 欧美日韩国产经典色站一区二区三区| 欧美日韩精品综合| 亚洲人成网站777色婷婷| 亚洲三级毛片| 欧美高清视频在线 | 欧美高清视频| 亚洲综合电影一区二区三区| 午夜免费在线观看精品视频| 久久久91精品国产| 欧美激情视频在线免费观看 欧美视频免费一 | 亚洲精品永久免费| 一区二区三区**美女毛片| 中文一区字幕| 欧美a级在线| 亚洲女人天堂av| 欧美国产极速在线| 国产日韩成人精品| 亚洲特色特黄| 欧美成人激情在线| 亚洲欧美日韩精品久久奇米色影视| 老司机亚洲精品| 国产欧美精品xxxx另类| 一本久道综合久久精品| 欧美jjzz| 久久精品免视看| 国产精品老牛| 夜夜躁日日躁狠狠久久88av| 欧美成人激情视频免费观看| 亚洲私人影院在线观看| 欧美www视频| **网站欧美大片在线观看| 香蕉亚洲视频| 亚洲日本国产| 久久激情视频免费观看| 国产精品乱人伦中文| 羞羞色国产精品| 欧美激情综合色综合啪啪| 国产综合久久| 久久精品国产亚洲一区二区| 99国产精品久久久久老师| 欧美暴力喷水在线| 亚洲国产日韩欧美一区二区三区| 久久综合九色| 久久精品色图| 在线精品在线| 欧美不卡在线视频| 美女视频一区免费观看| 136国产福利精品导航网址| 久久综合色婷婷| 久久夜色精品亚洲噜噜国产mv | 韩国久久久久| 久久久久久国产精品mv| 欧美伊人久久大香线蕉综合69| 国产精品毛片一区二区三区| 亚洲欧美国产精品桃花| 亚洲一区二区三区涩| 国产精品爽爽ⅴa在线观看| 欧美一区二区三区精品 | 亚洲区欧美区| 欧美精品一区视频| 亚洲免费影视| 欧美一级片久久久久久久| 国产日韩欧美中文| 欧美成人免费全部| 欧美日韩一区二区视频在线观看 | 国产午夜精品一区二区三区视频| 久久精品一区蜜桃臀影院| 久久久久久久久蜜桃| 亚洲免费大片| 亚洲欧美日韩国产综合| 亚洲大胆女人| 日韩一级免费| 国模私拍视频一区| 免费黄网站欧美| 欧美日韩国产综合视频在线观看中文 | 欧美一级欧美一级在线播放| 欧美制服丝袜| 亚洲乱码国产乱码精品精98午夜| 夜夜嗨av一区二区三区四区| 国内精品美女av在线播放| 亚洲国产综合在线| 国产欧美日韩在线| 亚洲国产精品久久91精品| 国产精品久久久亚洲一区| 老色鬼久久亚洲一区二区 | 国产精品99久久久久久www| 国产精品久久福利| 免费黄网站欧美| 欧美午夜欧美| 欧美激情按摩| 国产欧亚日韩视频| 亚洲精品日韩精品| 国产在线乱码一区二区三区| 亚洲人成在线观看网站高清| 国产一区日韩欧美| 日韩亚洲精品电影| 亚洲日本成人网| 一区二区三区不卡视频在线观看| 欧美在线|欧美| 亚洲午夜羞羞片| 久久蜜桃精品| 久久精品欧洲| 国产精品一区二区久久| 亚洲精品之草原avav久久| 狠狠综合久久av一区二区老牛| 一本色道久久加勒比精品| 亚洲人成亚洲人成在线观看图片 | 国产一区日韩二区欧美三区| 国产精品99久久不卡二区| 亚洲精品综合精品自拍| 久久久久久久久综合| 欧美一级专区免费大片| 欧美日本一区二区三区| 亚洲国产精品成人一区二区| 亚洲电影免费观看高清| 久久精品国产77777蜜臀| 欧美一级久久久久久久大片| 国产精品jvid在线观看蜜臀| 亚洲另类视频| 一区二区三区免费看| 欧美精品18| 日韩视频精品在线| 中国成人黄色视屏| 欧美日本免费| 一区二区精品国产| 亚洲欧美综合精品久久成人| 国产精品大片| 亚洲激情一区| 亚洲人成亚洲人成在线观看图片| 亚洲精品中文字幕女同| 一区二区免费在线视频| 欧美另类久久久品| 亚洲精品美女在线观看播放| av成人免费观看| 欧美日韩视频一区二区三区| 99国产精品久久久久久久成人热 | 亚洲天堂av电影| 久久国产精品第一页| 黑人极品videos精品欧美裸| 久久婷婷丁香| 亚洲精品小视频| 性做久久久久久免费观看欧美| 国产手机视频精品| 久久午夜电影网| 亚洲人成毛片在线播放| 亚洲午夜一区二区| 久久久久久久精| 亚洲国产日韩欧美| 久久久蜜桃精品| 欧美黑人在线播放| 国产精品99久久久久久久vr| 国产精品久久久久高潮| 欧美一区永久视频免费观看| 欧美电影电视剧在线观看| 一本久道久久综合狠狠爱| 国产精品综合久久久| 久久综合网hezyo| 一区二区三区**美女毛片| 久久久久www| 一本色道久久88亚洲综合88| 国产精品亚洲一区二区三区在线| 久久福利电影| 一本色道久久综合亚洲精品婷婷| 久久久久国产精品www| 在线亚洲伦理| 在线观看三级视频欧美| 国产精品无码永久免费888| 麻豆精品精华液| 午夜影院日韩| 日韩一区二区福利| 欧美不卡视频一区发布| 欧美亚洲综合网| 9国产精品视频| 激情文学综合丁香| 国产精品系列在线播放| 欧美区亚洲区| 久久综合狠狠综合久久综合88 | 亚洲电影一级黄| 国产农村妇女毛片精品久久莱园子 | 亚洲狼人精品一区二区三区| 国产美女精品视频免费观看| 欧美日韩国产综合视频在线观看中文| 久久免费一区| 久久精品国产免费| 亚洲欧美综合v| 亚洲综合国产激情另类一区|