2012-12-18 1 views
8

TCPを介してプロトコルバッファメッセージを送信しようとしていますが、受信側では、たとえ明らかにすべてのフィールドがあるとしても、解析します。私は、メッセージの長さを含むメッセージの前に4バイトのヘッダーを送ります。私は、ヘッダをコードするベクターにメッセージをシリアル化していクライアント側Googleプロトコルバッファ - すべてのフィールドが明らかに存在するにもかかわらず必須フィールドがありません

message ReplayRequest { 
    required string channel = 1; 
    required uint32 start = 2; 
    required uint32 end = 3; 
} 

:ここ

は、メッセージ定義です。

ReplayRequest req; 
req.set_channel("channel") 
req.set_start(1); 
req.set_end(5); 
int byte_size = req.ByteSize(); 
std::vector<uint8_t> write_buffer(HEADER_SIZE + byte_size); 
encode_header(...); 
req.SerializeToArray(&write_buffer[HEADER_SIZE], byte_size); 

これは結果バッファの16進数で、最初の4バイトはエンコードされたメッセージの長さ(13バイト)です。

00 00 00 0d 0a 07 63 68 61 6e 6e 65 6c 10 01 18 05 

サーバー側では、ヘッダーを受信して​​デコードし、Nバイトを受信します。ここで、Nはヘッダーに記録されたメッセージサイズです。削除ヘッダーとサーバー内のバッファは、次のとおりです。

クライアント側マイナスヘッダをエンコード1と全く同じであるが、私はこのバッファをParseFromArrayしようとすると、私はエラーを取得する
0a 07 63 68 61 6e 6e 65 6c 10 01 18 05 

libprotobuf ERROR c:\umdf_runtime\protobuf-2.4.1\src\google\protobuf\message_lit 
e.cc:123] Can't parse message of type "ReplayRequest" because it is missing 
required fields: channel, start, end 

デバッグしながら私は、復号が失敗した点がいるProtobufのこの部分上でコードを生成していることに気づいた:

bool ReplayRequest::IsInitialized() const { 
    if ((_has_bits_[0] & 0x00000007) != 0x00000007) return false; 

    return true; 
} 

has_bits_は、サーバ側で0として読まれています何らかの理由で私は理由を理解できません。

アイデア?

重要な場合は、ネットワーク部分にboost :: asioを使用しています。

更新

私はparseFromArrayを呼び出すコードを掲示していたよう要求しました。

request_.ParseFromArray(&data_buffer_, data_buffer_.size()); 

request_は、この呼び出しが行われるまで、ReplayRequestメンバー変数です。

data_buffer_は、TCPデータが受信されるベクトル<uint8_t>です。

これは、13バイトで正しくサイズが確認されました。これは、16進ダンプです。これは、シリアライズ後にバッファクライアント側をダンプすると同じです。私はクライアント側でReplayRequestの別のインスタンスにバッファを解析することができる午前2

0a 07 63 68 61 6e 6e 65 6c 10 01 18 05 

更新、すなわち:

...snip... 
req.SerializeToArray(&write_buffer[HEADER_SIZE], byte_size); 
ReplayRequest test; 
test.ParseFromArray(&write_buffer[HEADER_SIZE], byte_size); 

テストが正常に正しいフィールドが移入されます。

+0

を試してみてくださいサーバー上のメッセージが間違っています。 ParseFromArrayを呼び出すコードを投稿してください。 –

+0

4バイトの符号化されたメッセージサイズヘッダーがビッグエンディアンのようです...受信側でビッグエンディアンとして正しくデコードしていますか? –

+0

@Jamesヘッダーが正しくデコードされていれば、印刷されたサーバーバッファーがエンコードされたとおりに正確に13バイトであることがわかります。 – indiosmo

答えて

5

問題は、ベクターデータへのポインタではなく、ベクターへのポインタを渡していることです。

代わりの
request_.ParseFromArray(&data_buffer_, data_buffer_.size());

サーバはそれが*必須フィールドのいずれかの*を持っていないと言う場合は、抽出して解析している場合、私は思ったんだけど、
request_.ParseFromArray(&data_buffer_[0], data_buffer_.size());

+0

それだけです。私は前にサーバ上の単一のバッファに入っていたので、&data_buffer_ [HEADER_SIZE]は正常に動作していました。バッファを分割した後、アクセサーを削除しました。ありがとうございました。 – indiosmo

+0

np、喜んで:) – g19fanatic

関連する問題