Что хочу сделать: отправить изображение по сокетам TCP.
Алгоритм:
- Клиент преобразует изображение в байтовый массив.
- Разбивает этот массив на фрагменты (пакеты).
- Последовательно отправляет пакеты серверу.
- Сервер считывает пакеты, достаёт из них байтовые массивы и склеивает их.
- Полученный байтовый массив дессериализуется в изображение.
Что отправляю (отдельный .dll-файл, который подключаю к клиентуи серверу):
[Serializable]
public struct DataPacket
{
public byte[] Bytes;
public bool IsEnclosing;
}
Как отправляю:
public static void SendByPackets(NetworkStream netStream, byte[] data)
{
MemoryStream memoryStream = null;
var formatter = new BinaryFormatter();
try
{
for (int i = 0; i * DATA_PACKET_BYTES_MAX_LENGTH <= data.Length; i++)
{
bool isLastPackage = ((i + 1) * DATA_PACKET_BYTES_MAX_LENGTH >= data.Length);
var packet = new DataPacket()
{
Bytes = SubArray<byte>(data, i * DATA_PACKET_BYTES_MAX_LENGTH, (isLastPackage) ? data.Length - i * DATA_PACKET_BYTES_MAX_LENGTH : DATA_PACKET_BYTES_MAX_LENGTH),
IsEnclosing = isLastPackage
};
memoryStream = new MemoryStream();
formatter.Serialize(memoryStream, packet);
byte[] arr = memoryStream.ToArray();
netStream.Write(arr, 0, arr.Length);
}
}
catch(Exception ex)
{
throw ex;
}
finally
{
memoryStream?.Close();
}
}
Как принимаю:
private BitmapImage ReceiveImageByPackets(TcpClient client)
{
NetworkStream netStream = client.GetStream();
BinaryFormatter formatter = new BinaryFormatter();
MemoryStream memoryStream = null;
byte[] serializedImage = new byte[0];
do
{
var bytes = new byte[client.ReceiveBufferSize];
int countOfReadBytes = netStream.Read(bytes, 0, client.ReceiveBufferSize);
if (countOfReadBytes > 0)
{
memoryStream = new MemoryStream(bytes);
memoryStream.Seek(0, SeekOrigin.Begin);
var packet = (DataPacket) formatter.Deserialize(memoryStream);
memoryStream.Close();
serializedImage = Concatenate<byte>(serializedImage, packet.Bytes);
if (packet.IsEnclosing)
break;
}
else
throw new Exception("Received 0 bytes!");
} while (true);
var stream = new MemoryStream(serializedImage);
return (BitmapImage) formatter.Deserialize(stream);
}
Проблема:
всегда десериализация второго пакета выдаёт ошибку "Недопустимый двоичный формат входного потока. Начало содержимого (в байтах): (здесь hex-код)". Что мешает десериализовать второй пакет? Получается он неправильно сериализуется? Если да, то в чём ошибка?