我的学校项目有问题,我使用Protobuf库,但我有以下错误:
Google.Protobuf.InvalidProtocolBufferException"协议消息包含无效标记(零)。
我的协议消息包装器是:
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;
}
我用它来发送消息:
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);
}
我的服务器处理程序:
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时,异常弹出。
我做坏事吗?
答案 0 :(得分:3)
问题可能是您在不使用已知长度的情况下使用GetBuffer
。 GetBuffer
返回超大支持数组。流.Length
之后的数据是垃圾,不应该被消耗 - 它通常(但不总是)是零,这就是你所看到的。
使用ToArray()
代替GetBuffer()
,或者跟踪流的.Length
,只消耗那么大的超大缓冲区。
另一种可能性是&#34;框架&#34; - 看起来您正在处理数据包,但如果这是TCP,则无法保证您收到的数据块与您发送的数据块大小相同。如果您通过TCP发送多条消息,则需要实现自己的成帧(通常通过长度前缀,因为您正在谈论二进制数据)。
顺便说一句,这不是protobuf-net。
如果这两个都不是问题:检查您收到的数据是否正确(字节为字节)您发送的数据(包括长度)。数据很容易被IO代码破坏或错误分块。