use*_*070 5 c# serialization protobuf-net
我有一个可以序列化和反序列化的对象,但在反序列化时它会抛出一个错误:
Invalid field in source data: 0
我不知道为什么会这样
反序列化和接收的代码:
public void listenUDP()
{
EndPoint ep = (EndPoint)groupEP;
//BinaryFormatter bf = new BinaryFormatter();
recieving_socket.Bind(ep);
while (true)
{
byte[] objData = new byte[65535];
recieving_socket.ReceiveFrom(objData, ref ep);
MemoryStream ms = new MemoryStream();
ms.Write(objData, 0, objData.Length);
ms.Seek(0, SeekOrigin.Begin);
messageHandle(ProtoBuf.Serializer.Deserialize<SimplePacket>(ms));
ms.Dispose();
}
}
Run Code Online (Sandbox Code Playgroud)
序列化代码:
public void sendDataUDP(Vec2f[] data)
{
SimplePacket packet = new SimplePacket(DateTime.UtcNow, data);
//IFormatter formatter = new BinaryFormatter();
MemoryStream stream = new MemoryStream();
System.Diagnostics.Stopwatch st = System.Diagnostics.Stopwatch.StartNew();
//formatter.Serialize(stream, data);
ProtoBuf.Serializer.Serialize<SimplePacket>(stream, packet);
//Console.WriteLine(st.ElapsedTicks);
stream.Close();
st.Restart();
sending_socket.SendTo(stream.ToArray(), sending_end_point);
//Console.WriteLine(st.ElapsedTicks);
st.Stop();
}
Run Code Online (Sandbox Code Playgroud)
根据谷歌规范定义的protobuf消息中的根对象不包括消息结束的任何概念.这是故意的,因此连接与合并两个片段相同.因此,消费代码需要将自己限制为单个消息.这在所有protobuf实现之间是相同的,并不是protobuf-net特有的.
发生了什么事情,你的缓冲区目前超大,最后有垃圾.目前(因为您正在阅读一条消息)垃圾很可能全部为零,而零不是字段的有效标记.但是,当重新使用缓冲区时,垃圾可能是......任何东西.
在您的情况下,最简单的方法可能是使用SerializeWithLengthPrefix/ DeserializeWithLengthPrefixmethods,它通过在消息开头预先设置有效负载长度来处理所有这些,并且只处理那么多数据.
最后的想法是:我不清楚您的代码是否会保证读取整个消息; 单个接收可以(至少在TCP上)返回消息的一部分 - 或2和一些消息等:TCP是基于流的,而不是基于消息的.
| 归档时间: |
|
| 查看次数: |
1201 次 |
| 最近记录: |