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

Jea*_*ave 5 c# protobuf-net

I have a problem with my school project, i use Protobuf library but i have the following error:

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

My protocol message wrapper is:

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;
}
Run Code Online (Sandbox Code Playgroud)

我用它来发送消息:

    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);
    }
Run Code Online (Sandbox Code Playgroud)

和我的服务器处理程序:

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;
        }
    }
Run Code Online (Sandbox Code Playgroud)

包装消息完全未序列化,并且类型正确匹配,但是在处理我的有效负载时,会弹出异常。

我做不好的事吗?

编辑:消息有效负载的小屏幕 有效载荷

Mar*_*ell 5

问题可能是您在GetBuffer没有使用已知长度的情况下使用。GetBuffer 返回超大的支持数组。流之后的数据.Length是垃圾,不应该被消耗——它通常(但不总是)为零,这就是你所看到的。

要么使用ToArray()代替GetBuffer(),要么跟踪.Length流的 ,并且只消耗大量超大缓冲区。


另一种可能性是“成帧” - 看起来您正在处理数据包,但如果这是 TCP,则无法保证您收到的数据块与您发送的数据块大小相同。如果您通过 TCP 发送多条消息,您需要实现自己的成帧(通常通过长度前缀,因为您在谈论二进制数据)。


顺便说一句,这不是protobuf-net。


如果这些都不是问题:检查您收到的数据是否与您发送的数据(包括长度)完全一致(逐字节)。数据很容易被 IO 代码损坏或误分块。