C# 为什么我的protobuf网络流不工作?
我有一个可以序列化和反序列化的对象,但在反序列化时会抛出一个错误:C# 为什么我的protobuf网络流不工作?,c#,serialization,protobuf-net,C#,Serialization,Protobuf Net,我有一个可以序列化和反序列化的对象,但在反序列化时会抛出一个错误: 源数据中的字段无效:0 我不知道为什么会这样 反序列化和接收代码: public void listenUDP() { EndPoint ep = (EndPoint)groupEP; //BinaryFormatter bf = new BinaryFormatter(); recieving_socket.Bind(ep); while (true)
源数据中的字段无效: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();
}
}
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();
}
public void listenUDP()
{
终点ep=(终点)组ep;
//BinaryFormatter bf=新的BinaryFormatter();
接收插座绑定(ep);
while(true)
{
字节[]objData=新字节[65535];
接收插座。接收自(objData,参考ep);
MemoryStream ms=新的MemoryStream();
ms.Write(objData,0,objData.Length);
Seek女士(0,SeekOrigin.Begin);
messageHandle(ProtoBuf.Serializer.Deserialize(ms));
Dispose女士();
}
}
序列化代码:
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();
}
}
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();
}
public void sendDataUDP(Vec2f[]数据)
{
SimplePacket=新的SimplePacket(DateTime.UtcNow,数据);
//IFormatter formatter=新的BinaryFormatter();
MemoryStream stream=新的MemoryStream();
System.Diagnostics.Stopwatch st=System.Diagnostics.Stopwatch.StartNew();
//序列化(流、数据);
ProtoBuf.Serializer.Serialize(流、包);
//控制台写入线(圣埃拉普塞迪克);
stream.Close();
st.重启();
发送\u socket.SendTo(stream.ToArray(),发送\u end\u point);
//控制台写入线(圣埃拉普塞迪克);
st.Stop();
}
根据google规范的定义,protobuf消息中的根对象不包括消息的结尾的任何概念。这是有意的,因此连接等同于合并两个片段。因此,消费代码需要将自身限制为单个消息。这在所有protobuf实现之间是相同的,并且不是protobuf net特有的
现在的情况是,您的缓冲区当前过大,末尾有垃圾当前(因为您正在阅读一条消息),垃圾很可能都是零,零不是字段的有效标记。然而,当重新使用缓冲区时,垃圾可能。。。什么都行
在您的情况下,可能最简单的方法是使用SerializeWithLengthPrefix
/反序列化WithLengthPrefix
方法,这些方法通过在消息开始处预先指定有效负载长度来为您处理所有这一切,并且只处理那么多数据
最后想一想:我不清楚您的代码是否能保证is已经阅读了整个消息;一次接收可能(至少在TCP上)返回一条消息的一部分,或2条和一位消息,等等:TCP是基于流的,而不是基于消息的