У меня есть два приложения (SocketClient и SocketServer), оба написаны на .NET core 2.1.SocketClient (работает на Unix-машине) читает файл размером ~ 10 ГБ и отправляет прочитанные байты через Socket.
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}");
}
}
}
}
SocketServer (запускается на машине с Windows) получает отправленные байты и пытается десериализовать его:
using (NetworkStream stream = client.GetStream())
{
if (!stream.CanRead) return;
while (true)
{
Serializer.DeserializeWithLengthPrefix<SomeObject[]>(stream, PrefixStyle.Fixed32);
Console.WriteLine($"{count += d.Length}");
}
}
Этот код прекрасно работает с почти 96 миллионами успешно десериализованных SomeObject(файл содержит ~ 101 миллион объектов), и после этого он постоянно разрывается с сообщением ProtoBuf.ProtoException: вложенное сообщение не читается правильно.
Файл содержит байтовые массивы, полученные путем многократного вызова следующего метода (с пакетами SomeObject),Вывод одного одиночного вызова составляет ~ 270 КБ, который добавляется в файл.
public static byte[] GetSerialisedWithLengthPrefix(SomeObject[] dto)
{
using (var ms = new MemoryStream())
{
Serializer.SerializeWithLengthPrefix(ms, dto, PrefixStyle.Fixed32);
return ms.ToArray();
}
}
Любая помощь высоко ценится!Спасибо за чтение.
Логика создания файла довольно проста.SomeObject содержит только три поля (строковый идентификатор, строковое логическое значение и двойное значение), и следующий метод вызывается несколькими потоками
Dump(SomeObject[])
{
using (var ms = new MemoryStream())
{
requiredBytes = Serializer.SerializeWithLengthPrefix(ms, SomeObject.ToArray(), PrefixStyle.Fixed32);
}
lock (locker)
{
using (FileStream file = new FileStream(Filepath, FileMode.Append, FileAccess.Write, FileShare.Read))
using (BinaryWriter writer = new BinaryWriter(file, Encoding.UTF8))
{
writer.Write(requiredBytes);
}
}
}