c# – ProtoBuf-Net和Compact Framework中的“源数据中的无效字段:0”错误

有人在使用ProtoBuf-Net在紧凑框架和完整的.Net框架之间进行序列化/反序列化时,是否知道任何问题?我有一个名为LogData的类,我在紧凑框架3.5下进行序列化,传输到服务器(运行.Net框架4.0),然后反序列化.有时它的工作,有时它会抛出上述错误,我还没有把它缩小到任何具体的原因.我已经做了很多不同的测试,不能发现任何韵律或理由.我在下面包括我的类(减去各种构造函数).我已经在多个场合看过任何一方的字节缓冲区,并且还没有找到通过电线从一边发送到另一边的数据的差异.
[ProtoContract]
public class LogData
{

  [ProtoContract]
  public enum LogSeverity
  {
     [ProtoEnum(Name = "information",Value = 0)]
     information,[ProtoEnum(Name = "Warning",Value = 1)]
     Warning,[ProtoEnum(Name = "Error",Value = 2)]
     Error,[ProtoEnum(Name = "Critical",Value = 3)]
     Critical
  }

  [ProtoMember(1)]
  public string UserID { get; set; }
  [ProtoMember(2)]
  public string ComputerName { get; set; }
  [ProtoMember(3)]
  public ExceptionProxy Exception { get; set; }
  [ProtoMember(4)]
  public LogData.LogSeverity Severity { get; set; }
  [ProtoMember(5)]
  public string Source { get; set; }
  [ProtoMember(6)]
  public string Caption { get; set; }
  [ProtoMember(7)]
  public string Description { get; set; }
  [ProtoMember(8)]
  public DateTime TimeOfOccurrence { get; set; }
  [ProtoMember(9)]
  public Guid SessionID { get; set; }
  [ProtoMember(10)]
  public string MethodName { get; set; }
  [ProtoMember(11)]
  public string Osversion { get; set; }
  [ProtoMember(12)]
  public string Category { get; set; }
  [ProtoMember(13)]
  public string Location { get; set; }
}

[ProtoContract]
public class ExceptionProxy
{

  [ProtoMember(1)]
  public Type ExceptionType { get; set; }
  [ProtoMember(2)]
  public string Message { get; set; }
  [ProtoMember(3)]
  public string StackTrace { get; set; }
  [ProtoMember(4)]
  public ExceptionProxy InnerException { get; set; }

}

这是我的代码,进行序列化和发送

private void WriteLogDataToServer(LogData data)
  {
     using (var client = new TcpClient())
     {
        client.Connect(Host,SignalLineserverPort);
        using (var stream = client.GetStream())
        {
           using (var ms = new MemoryStream())
           {
              Serializer.Serialize<LogData>(ms,data);
              var buffer = ms.GetBuffer();
              int position = 0;
              WriteFrameMarkers(stream);
              byte[] frameLengthBuffer = BitConverter.GetBytes(buffer.Length);
              stream.Write(frameLengthBuffer,IntByteSize);
              while (position < buffer.Length)
              {
                 int length = Math.Min(ChunkSize,buffer.Length - position);
                 stream.Write(buffer,position,length);
                 position += ChunkSize;
              }
           }
        }
        client.Close();
     }         
  }

这是读取服务器上的数据的代码

public override LogData ReadData(NetworkStream stream)
  {
     if (stream.DataAvailable)
     {
        try
        {
           const int chunkSize = 250;
           byte[] buffer = new byte[IntByteSize];
           int messageSize = 0;
           int totalBytesRead = 0;
           LogData data;
           using (var ms = new MemoryStream())
           {
              if (!ReadFrameMarkers(stream))
                 return null;
              totalBytesRead = stream.Read(buffer,IntByteSize);
              if (totalBytesRead != IntByteSize)
                 return null;
              messageSize = BitConverter.ToInt32(buffer,0);
              totalBytesRead = 0;
              while ((totalBytesRead < messageSize))
              {
                 int bufferSize = Math.Min(chunkSize,messageSize - totalBytesRead);
                 buffer = new byte[bufferSize];
                 int bytesRead = stream.Read(buffer,bufferSize);
                 if (bytesRead != 0)
                 {
                    totalBytesRead += bytesRead;
                    ms.Write(buffer,bytesRead);
                 }
              }
              ms.Seek(0,SeekOrigin.Begin);
              data = Serializer.Deserialize<LogData>(ms);
           }
           return data;
        }
        catch (Exception ex)
        {
           Console.WriteLine(string.Format("Error occurred: {0}",ex.Message));
           return null;
        }
     }
     return null;
  }

解决方法

简单的一个:你使用:
var buffer = ms.GetBuffer();

然后buffer.Length.这意味着您正在使用超大型的填充缓冲区.如果你这样做,你需要使用ms.Length,这将告诉你实际的长度.或者,可以使用ms.ToArray(),但这涉及额外的副本.

我的建议:继续使用GetBuffer(),但只能写入ms.Length字节,而不是buffer.Length字节.

一旦你删除了这些额外不正确的零,我期望你会发现它的作品.

相关文章

在要实现单例模式的类当中添加如下代码:实例化的时候:frmC...
1、如果制作圆角窗体,窗体先继承DOTNETBAR的:public parti...
根据网上资料,自己很粗略的实现了一个winform搜索提示,但是...
近期在做DSOFramer这个控件,打算自己弄一个自定义控件来封装...
今天玩了一把WMI,查询了一下电脑的硬件信息,感觉很多代码都...
最近在研究WinWordControl这个控件,因为上级要求在系统里,...