1

HTTP接続を介してGoogleProtocolBufferのシリアル化された文字列を送信し、それを(変更せずに)受信して、逆シリアル化しようとしています。私の問題は、私の文字列を受け取り、シリアル化された文字列に改行文字(およびおそらく他の空白)を追加するように見える'serializeToString'メソッドにあるようです。以下の例では、文字列「camera_stuff」を取得しており、シリアル化した後、先頭に改行が付いたQStringを取得します。異なる空白と改行を追加しただけで同じ結果になる他の文字列を試しました。これにより、HTTPリクエストで空白がキャプチャされず、サーバーからのシリアル化された文字列を含む応答を正常にデコードできないため、逆シリアル化操作で問題が発生します。シリアル化された文字列の空白を推測すれば、部分的にデコードできます。どうすればこれを解決できますか?次のコードを参照してください-ありがとう。

次のようなプロトコルバッファ.protoファイルがあります。

message myInfo {
  required string data = 1;
  required int32 number = 2;
}

protocコンパイラを実行した後、次のようにQtを構築します。

// Now Construct our Protocol Buffer Data to Send
myInfo testData;
testData.set_data("camera_stuff");
testData.set_number(123456789);

データを次のような文字列にシリアル化します。

// Serialize the protocol buffer to a string
std::string serializedProtocolData; // Create a standard string to serialize the protocol buffer contents to
myInfo.SerializeToString(&serializedProtocolData); // Serialize the contents to the string
QString serializedProtocolDataAsQString = QString::fromStdString(serializedProtocolData);

そして、私はそれを次のように印刷します:

// Print what we are sending
qDebug() << "Sending Serialized String: " << serializedProtocolDataAsQString;
qDebug() << "Sending Serialized String (ASCII): " << serializedProtocolDataAsQString.toAscii();
qDebug() << "Sending Serialized String (UTF8): " << serializedProtocolDataAsQString.toUtf8();
qDebug() << "Sending Serialized Protocol Buffer";
qDebug() << "Data Number: " << QString::fromStdString(myInfo.data());
qDebug() << "Number: " << (int)myInfo.number();

HTTPマルチパートメッセージの一部としてデータを送信すると、次のような印刷ステートメントが表示されます(印刷出力の改行に注意してください!):

Composing multipart message...
Sending Serialized String:  "

camera_stuffï:" 
Sending Serialized String (ASCII):  "

camera_stuffï:" 
Sending Serialized String (UTF8):  "

camera_stuffÂÂï:" 
Sending Serialized Protocol Buffer 
Data:  "camera_stuff" 
Number:  123456789 
Length of Protocol Buffer serialized message:  22 
Loading complete...

クライアントは、次のようにメッセージを逆シリアル化します。

// Now deserialize the protocol buffer
string = "\n\n" + string; // Notice that if I don't add the newlines I get nothing!
myInfo protocolBuffer;
protocolBuffer.ParseFromString(string.toStdString().c_str());
std::cout << "DATA: " << protocolBuffer.model() << std::endl;
std::cout << "NUMBER: " << protocolBuffer.serial() << std::endl;
qDebug() << "Received Serialized String: " << string;
qDebug() << "Received Deserialized Protocol Buffer";
qDebug() << "Data: " << QString::fromStdString(protocolBuffer.data());
qDebug() << "Number: " << (int)protocolBuffer.number();

サーバーはシリアル化された文字列に対して何もせずにそれを返し、クライアントは次のように出力します。

RESPONSE:  "camera_stuffï:"  
DATA: camera_stu
NUMBER: 0
Received Serialized String:  "

camera_stuffï:" 
Received Deserialized Protocol Buffer 
Number:  "camera_stu"

Number:  0

したがって、問題は空白を推測できないため、文字列を確実に逆シリアル化できないように見えることです。何かご意見は?

4

1 に答える 1

2

Cシリアル化されたprotobufは、おそらくNULが埋め込まれているため、文字列として扱うことはできません。これは、可能なすべてのオクテット値を使用するバイナリプロトコルであり、8ビットクリーン接続を介してのみ送信できます。また、これは有効なUTF-8シーケンスではなく、Unicodeとしてシリアル化および逆シリアル化することはできません。したがってQString、シリアル化されたprotobufを格納する有効な方法でもありません。また、それが問題の原因になっている可能性もあります。

std::stringとを使用できますQByteArray。他のものは避けることを強くお勧めします。特に、これは間違っています:

protocolBuffer.ParseFromString(string.toStdString().c_str());

最初にprotobufを切り捨てるためNULです。(テストメッセージには何もありませんが、遅かれ早かれこれはあなたを噛みます。)

HTTP経由でメッセージを送信する場合は、メッセージ内のすべてのバイトがそのまま送信されるようにする必要があります。つまり、長さを明示的に送信する必要もあります。あなたは実際にメッセージを送受信するコードを含めていなかったので、私はそれについてコメントすることはできません(そして私はQt HTTPライブラリを十分に知りません)が0x0A、メッセージの前に、何かが足りないことが示されています。メッセージ部分のコンテンツタイプを正しく設定していることを確認してください(たとえば、テキストではありません)。

于 2012-10-25T15:21:33.810 に答える