有人在使用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字节.
一旦你删除了这些额外不正确的零,我期望你会发现它的作品.