我正在为 c# 使用 protobuf google 实现。
到目前为止的故事..我有一个 c++ 中的服务器和 c# 中的客户端,并通过 protobuf 消息与 TCP 进行交谈。
在客户端,我通过提供的回调检索从 tcpClient.BeginReceive 返回的缓冲区并附加它们(所以我猜它已从 netstream 垃圾中清除)。然后在工作线程上,我尝试反序列化消息。
在服务器端,序列化代码是:
google::protobuf::uint32 msgSize = msg->ByteSize();
int prefix_length = sizeof(msgSize);
int buffer_length = msgSize + prefix_length;
google::protobuf::uint8 buffer[buffer_length];
google::protobuf::io::ArrayoutputStream array_output(buffer, buffer_length, msgSize);
google::protobuf::io::CodedOutputStream coded_output(&array_output);
coded_output.WriteVarint32(msgSize);
msg->SerializeToCodedStream(&coded_output);
//Send to socket
mSendBuffer.Write(buffer, buffer_length);
在客户端上,我使用 CodedInputStream 读取每个块,读取第一个数字并发送前缀+它包含的 msg 以进行反序列化
计算长度:
using (var input = new CodedInputStream(chunk))
{
int len = input.ReadInt32();
int requiredLength = len + input.Position; //(we re sure each time the codedInput starts from the beginning)
byte[] read = await AccumulateResources(requiredLength, chunk);
byte[] msg = new byte[requiredLength];
Buffer.BlockCopy(read, 0, msg , 0 , requiredLength);
Dispatch(msg);
}
反序列化:
using (var ms = new MemoryStream(buff))
{
ServerMessageFrame msg = null;
try
{
msg = ServerMessageFrame.Parser.ParseDelimitedFrom(ms);
}
catch(Exception e)
{
Logger.Write(conn.clntPrefx + " " + e.ToString());
}
//Use the message
}
我收到的错误消息是:
1)System.InvalidOperationExeption:线型无效
2) 协议消息包含无效标签(零)。
通信在开始时是正确的,它在某个点不同步,从那里中断(直到我读到另一个以前缀值开头的消息,也就是不是部分消息)我的问题是反序列化声音或者我错过了完全标记为有一些我根本不考虑的事情。