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);
テストが正常に正しいフィールドが移入されます。
を試してみてくださいサーバー上のメッセージが間違っています。 ParseFromArrayを呼び出すコードを投稿してください。 –
4バイトの符号化されたメッセージサイズヘッダーがビッグエンディアンのようです...受信側でビッグエンディアンとして正しくデコードしていますか? –
@Jamesヘッダーが正しくデコードされていれば、印刷されたサーバーバッファーがエンコードされたとおりに正確に13バイトであることがわかります。 – indiosmo