8

私はBoostasioを使用してアプリケーションを作成しています。このアプリケーションでは、クライアントとサーバーがgoogleproto-buffersを使用してシリアル化されたメッセージを交換します。ネットワーク経由で送信されるシリアル化されたメッセージのサイズがわかりません。proto-bufオブジェクトには区切り文字がないようです。

.protoファイルの内容は次のとおりです。

 package tutorial;

message Person {
        required string name = 1;
        required int32 id = 2;
        optional string email = 3;
}

これが私がサーバーから書いている方法です

        tutorial::Person p;
        p.set_name("abcd pqrs");
        p.set_id(123456);
        p.set_email("abcdpqrs@gmail.com");
        write(p);

        boost::asio::streambuf b;
        std::ostream os(&b);
        p.SerializeToOstream(&os);
        boost::asio::async_write(socket_, b,
                        boost::bind(&Server::handle_write, this,
                                boost::asio::placeholders::error));

クライアントで、boost :: asio::async_readを使用して上記で送信されたメッセージを読んでいます。以下のコードで、argの引数として設定されている値を確認するにはどうすればよいですか?boost::asio::transfer_at_least

 boost::asio::async_read(socket_, response_,
                            boost::asio::transfer_at_least(arg),
                            boost::bind(&Client::handle_read_header, this,
                                    boost::asio::placeholders::error));

または、オブジェクト全体を読み取った後にboost :: async_readが返されるようにするにはどうすればよいですか?

4

1 に答える 1

7

正解です。protobufsは区切られていません。メッセージがバイトストリームだけでどこで終了するかはわかりません。知っているすべてのフィールドを見たとしても、要素が繰り返されているか、誰かが知らないフィールドでプロトを拡張している可能性があります。

一般的な解決策は、フレームに長さのプレフィックスを付けることです(通常はsとしてエンコードされVarIntます)。 たとえば、 LevelDBSzlはどちらもこのアプローチを使用します。AVarIntはバイトごとに明確にデコードでき、メッセージ全体を解析する前に読み取るバイト数がわかります。

于 2012-06-08T19:44:56.867 に答える