2017-11-09 7 views
2

私は私の学校のプロジェクトに問題がある、私がいるProtobufライブラリを使用しますが、私は次のエラーを持っている:Google.Protobuf.InvalidProtocolBufferException:プロトコルは、メッセージが無効なタグ(ゼロ)を含有していた

Google.Protobuf.InvalidProtocolBufferException" Protocol message contained an invalid tag (zero).

マイプロトコルメッセージラッパーであります

public void SendObject<T>(Protocol.Message.WrapperMessage.Types.MessageType type, T messageObject) 
    { 
     byte[] message; 

     // Serialize message 
     using (var stream = new MemoryStream()) 
     { 
      ((IMessage)messageObject).WriteTo(stream); 

      message = stream.GetBuffer(); 
     } 

     byte[] wrapper = new Protocol.Message.WrapperMessage{Type = type, Payload = Google.Protobuf.ByteString.CopyFrom(message)}.ToByteArray(); 

     Connection.SendObject<byte[]>("ByteMessage", wrapper); 
    } 

そして、私のS:私は、メッセージを送信するためにこれを使用

syntax = "proto3"; 
package CardGameGUI.Network.Protocol.Message; 

message WrapperMessage { 
enum MessageType { 
    HELLO_MESSAGE = 0; 
    JOIN_ROOM_MESSAGE = 1; 
    JOIN_ROOM_RESPONSE_MESSAGE = 2; 
} 

MessageType type = 1; 
bytes  payload = 2; 
} 

ERVERハンドラ:

private void IncommingMessageHandler(PacketHeader header, Connection connection, byte[] message) 
    { 
     Protocol.Message.WrapperMessage wrapper = Protocol.Message.WrapperMessage.Parser.ParseFrom(message); 

     switch (wrapper.Type) 
     { 
      case Protocol.Message.WrapperMessage.Types.MessageType.HelloMessage: 
       GetClient(connection.ConnectionInfo.NetworkIdentifier).MessageHandler(Protocol.Message.HelloMessage.Parser.ParseFrom(wrapper.Payload.ToByteArray())); 

       break; 
     } 
    } 

ラッパーメッセージは完全にアンシリアライズされ、そしてタイプが正しく一致しているが、私のペイロードの治療では、例外がポップします。

私は何か悪いですか?

編集:メッセージペイロード Payload

答えて

2

問題の小さな画面では、既知の長さを使用せずにGetBufferを使用したことはおそらくです。 GetBufferは、の大きめのバッキングアレイを返します。ストリームの.Lengthの後のデータはガベージであり、消費されるべきではありません。通常は常にゼロになるとは限りませんが、これはあなたが見ているものです。

GetBuffer()の代わりにToArray()を使用するか、ストリームの.Lengthを追跡して、その大量のバッファーの多くを消費してください。


もう一つの可能​​性は、「フレーミング」である - あなたがパケットを処理しているように見えますが、これはTCPである場合に受け取るチャンクはあなたが送っチャンクと同じ大きさであることを保証するものではありません。 TCPを介して複数のメッセージを送信する場合は、独自のフレーミングを実装する必要があります(通常、バイナリデータを扱っているので、長さ接頭辞を使用します)。


なお、これはprotobuf-netではありません。


これらのいずれも問題がない場合は、送信するデータ(長さを含む)が正確に(バイト単位のバイト数)であることを確認してください。データが壊れたり、IOコードによって誤ってチャンクされたりするのは簡単です。

+0

ありがとう、ToArrayは解決策でした! :D –

関連する問題