ProtoBuf.ProtoException:子消息无法正确读取(protobuf-net版本2.4.0)

时间:2018-12-22 15:27:52

标签: c# sockets protobuf-net

我有两个应用程序(SocketClient和SocketServer),都是用.NET core 2.1编写的。 SocketClient(在unix计算机上运行)读取大小约为10GB的文件,并通过Socket发送读取的字节。

Sub Workload_Schedule_Conditional_Formatting_Short()

    Dim rng As Range, ProjectRange As Range

    With Worksheets("Project_Summary")
        Set ProjectRange = .Range(Cells(2, 1), _
                Cells(.Range("B" & .Rows.Count).End(xlUp).Row, 2))
    End With
    With Worksheets("Workload_Schedule")
        Set rng = .Range(Cells(4, 3), _
                Cells(.Range("A" & .Rows.Count).End(xlUp).Row, 7))
    End With

    ' Other code for validation list.

End Sub

SocketServer(在Windows计算机上运行)接收发送的字节并尝试反序列化它:

var serverAddress = new IPEndPoint(IPAddress.Parse(args[0]), Convert.ToInt32(args[1]));
using (var clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
    clientSocket.Connect(serverAddress);
    using (var f = new FileStream(args[2], FileMode.Open, FileAccess.Read))
    {
        using (var read = new BinaryReader(f, Encoding.UTF8))
        {
            const int bufferSize = 4096;
            byte[] buffer = new byte[bufferSize];
            int count;
            while ((count = read.Read(buffer, 0, buffer.Length)) != 0)
            {
                int byteSend = clientSocket.Send(buffer, 0, count, SocketFlags.None);
                totalBytesSend += byteSend;
                Console.WriteLine($"Sent bytes {byteSend}");
            }
        }
    }
}

此代码在将近9600万个SomeObject成功反序列化(文件包含约1.01亿个对象)后均能正常工作,此后它始终以消息ProtoBuf.ProtoException中断:子消息无法正确读取。

该文件包含通过重复调用以下方法(使用SomeObject批处理)获得的字节数组。单个调用的输出为〜270KB,将被追加到文件中。

using (NetworkStream stream = client.GetStream())
{
    if (!stream.CanRead) return;
    while (true)
    {
        Serializer.DeserializeWithLengthPrefix<SomeObject[]>(stream, PrefixStyle.Fixed32);
        Console.WriteLine($"{count += d.Length}");
    }
}

任何帮助,不胜感激!感谢您的阅读。

文件创建逻辑非常简单。 SomeObject仅包含三个字段(字符串ID,字符串LogicalDateTime和双精度值),并且以下方法被多个线程调用

public static byte[] GetSerialisedWithLengthPrefix(SomeObject[] dto)
{
    using (var ms = new MemoryStream())
    {
        Serializer.SerializeWithLengthPrefix(ms, dto, PrefixStyle.Fixed32);
        return ms.ToArray();
    }
}

0 个答案:

没有答案