Есть клиент который принимает данные с сервера. Используется библиотека SuperSocket.
Ну тут даже не в это дело.
Для приема данных создан фильтр.
В него приходят данные с сервера, далее я их разбираю неким образом и дальше десереализую.
Вот здесь и вся проблема. При десереализации иногда возникает исключение OutOfMemoryException, Вычисление функции отключено из-за исключения, вызванного нехваткой памяти, Измерения массива превысили поддерживаемый диапазон.
С сервера для теста просто шлется 100 сериализованных объектов, вес одного объекта 183 байта.
Клиент может получить 3 объекта и выдать ошибку, может получить 6, может 20, короче под настроение. Хотя объекты всегда шлются одинаковые. Ну один раз запустил программу она приняла 5 и выдала ошибку, второй раз уже 3 и ошибка... Загадка крч.
Ошибка именно при вызове метода Deserialize.
В чём может быть причина?
код фильтра клиента, где ошибки
public class RecieveFilterX : IReceiveFilter<DataPackageInfo>{
public DataPackageInfo Filter(BufferList data, out int rest){
if (data.Total > 4){
byte[] head = new byte[4];
Buffer.BlockCopy(data[0].Array, 0, head, 0, 4);
int sizeContent = BitConverter.ToInt32(head, 0);
if (data.Total >= sizeContent + 4){
int needCopiedBytes = sizeContent + 4;
using (MemoryStream msTemp = new MemoryStream()){
for (int i = 0; i < data.Count && needCopiedBytes > 0; i++){
int lenCopy = Math.Min(needCopiedBytes, data[i].Count);
msTemp.Write(data[i].Array, data[i].Offset, lenCopy);
needCopiedBytes -= lenCopy;
}
msTemp.Seek(4, SeekOrigin.Begin);
try{
BinaryFormatter formatter = new BinaryFormatter();
Message msg = (Message)formatter.Deserialize(msTemp);//Ошибка возникает тут
rest = data.Total - sizeContent - 4;
return new DataPackageInfo(){
Data = msg
};
}
catch (OutOfMemoryException ex){
//Вычисление функции отключено из-за исключения, вызванного нехваткой памяти
//Измерения массива превысили поддерживаемый диапазон
throw ex;
}
}
}
}
rest = 0;
return null;
}
public void Reset()
{
}
public IReceiveFilter<DataPackageInfo> NextReceiveFilter { get; set; }
public FilterState State { get; set; }
}
Кстате на сервере похожий механизм, ну чуть другой. Но на сервер я могу послать 1000000 объектов и всё отлично залетает без ошибок, могу слать объекты весом несколько мегабайт и всё ок. Хотя там таже десериализация, объекты того же класса, почему же на клиенте ошибки??
Рабочий код фильтра сервера, на котором нет ошибокclass DataRecieveFilter : IReceiveFilter<DataRequestInfo> {
private byte[] reserveBuff;
public DataRequestInfo Filter(byte[] readBuffer, int offset, int length, bool toBeCopied, out int rest) {
byte[] localBuffer = new byte[length];
if (reserveBuff != null && reserveBuff.Length > 0){
localBuffer = new byte[reserveBuff.Length + length];
Buffer.BlockCopy(reserveBuff, 0, localBuffer, 0, reserveBuff.Length);
Buffer.BlockCopy(readBuffer, offset, localBuffer, reserveBuff.Length, length);
reserveBuff = null;
}
else
Buffer.BlockCopy(readBuffer,offset,localBuffer,0,length);
if (localBuffer.Length > 4){
byte[] head = new byte[4];
Buffer.BlockCopy(localBuffer, 0, head, 0, 4);
int sizeContent = BitConverter.ToInt32(head, 0);
if (localBuffer.Length >= sizeContent + 4){
BinaryFormatter formatter = new BinaryFormatter();
byte[] dataMessage = new byte[sizeContent];
Buffer.BlockCopy(localBuffer, 4, dataMessage, 0, sizeContent);
using (MemoryStream msTemp = new MemoryStream(dataMessage)){
Message msg = (Message) formatter.Deserialize(msTemp);
rest = localBuffer.Length - sizeContent - 4;
return new DataRequestInfo()
{
Key = msg.key,
message = msg
};
}
}
}
rest = 0;
reserveBuff = localBuffer;
return null;
}
public void Reset()
{
reserveBuff = null;
}
public int LeftBufferSize { get; set; }
public IReceiveFilter<DataRequestInfo> NextReceiveFilter { get; set; }
public FilterState State { get; set; }
}