2012-06-08 11 views
5

私はクライアントとサーバがgoogle proto-buffersを使ってシリアル化されたメッセージを交換するBoost asioを使ってアプリケーションを書いています。ネットワーク経由で送信されるシリアライズされたメッセージのサイズは何か分かりません。 proto-bufオブジェクトにはデリミタがないようです。boost :: asio :: read_asyncを使ってProtobufオブジェクトを読む

ここには、.protoファイルの内容があります。私はブースト:: ASIO :: async_readを使用して、上記送信されたメッセージを読んでいたクライアントでは、サーバ

 tutorial::Person p; 
     p.set_name("abcd pqrs"); 
     p.set_id(123456); 
     p.set_email("[email protected]"); 
     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)); 

から書いていますどのようにここで

package tutorial; 

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

です。下のコードで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が返されるようにするにはどうすればよいですか?

+0

私は答えは分かりませんが、私も興味がありますので、+1してください。 –

+0

問題を解決しましたか?私は非常に興味があり、鉄にはprotobuf + boost :: asioを一緒に置くことについての明確な欲望はない。 –

答えて

5

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

一般的な解決策は、フレームに長さ(通常はVarIntとしてエンコードされます)をプレフィックスに付けることです。 LevelDBSzlは両方ともこのアプローチを使用します。 VarIntは、一意にバイトごとにデコードすることができます。その後、完全なメッセージを解析する前に、読み取るバイト数を知ることができます。

+2

も参照http://stackoverflow.com/questions/2340730/are-there-c-equivalents-for-the-protocol -buffers-delimited-io-functions-in-jaいくつかのAPIは、答えに記述されているようにあなた自身で簡単に実装することができる区切りの書き込み/読み取り機能を備えています。 – Andreas

関連する問題