none
Передача массива байт как поля объекта при помощи XmlSerializer RRS feed

  • Вопрос

  • Возникла следующая проблема: есть класс Data с полями для сериализации.

    [XmlIgnore] public Image Image { get; set; } public byte[] ImageBytes { get { if (Image == null) return new byte[0]; using (var ms = new MemoryStream()) { Image.Save(ms, ImageFormat.Png); return ms.GetBuffer(); } } set { if ((Image != null)) { using (var ms = new MemoryStream(value)) { Image = Image.FromStream(ms); } } } }

    При передаче сериализованного документа теряется часть данных. Фактически, отправляя порядка 200 кб,

    на сервере я получаю около 30 кб, что вызывает ошибку при десериализации. Причем количество отправленных

    байт явно указывает на то, что массив был отправлен полностью, но получен лишь частично.

    Передача.

    public static Data SendMessageReturnData(byte[] msg) { try { // Буфер для входящих данных byte[] data = new byte[102400]; // Соединяемся с удаленным устройством // Устанавливаем удаленную точку для сокета IPHostEntry ipHost = Dns.GetHostEntry(IpAddr); IPAddress ipAddr = IpAddr; IPEndPoint ipEndPoint = new IPEndPoint(ipAddr, Port); Socket sender = new Socket(ipAddr.AddressFamily, SocketType.Stream, ProtocolType.Tcp); // Соединяем сокет с удаленной точкой sender.Connect(ipEndPoint); // Отправляем данные через сокет int bytesSent = sender.Send(msg); File.WriteAllBytes(@"client.xml", msg); MessageBox.Show("Bytes sent: "+bytesSent.ToString()+""); int bytesRec = sender.Receive(data); MessageBox.Show("Bytes rec: "+bytesRec.ToString()+""); MessageBox.Show("data[rec-1]: " + data[bytesRec-1] + ""); Data dt = Deserialize(data); // Получаем ответ от сервера // Используем рекурсию для неоднократного вызова SendMessageFromSocket() //if (message.IndexOf("<TheEnd>") == -1) // SendMessageFromSocket(port); // Освобождаем сокет sender.Shutdown(SocketShutdown.Both); sender.Close(); return dt; } catch { MessageBox.Show("Нет"); Data dt = new Data(); return dt; } }

    Прием.

    IPAddress ipAddr = IPAddress.Parse(Values.IpAddress);
    IPEndPoint ipEndPoint = new IPEndPoint(ipAddr, Int32.Parse(Values.Port));
    Socket sListener = new Socket(ipAddr.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
    sListener.Bind(ipEndPoint);
    sListener.Listen(10);
    Console.WriteLine("\n[{0}] Сервер запущен, адрес для подключения {1}\n", DateTime.Now, ipEndPoint);
    while (true)
       {
           Socket handler = sListener.Accept();
           Console.WriteLine("[{0}] Подключен клиент: {1}", DateTime.Now, handler.RemoteEndPoint.ToString());
           byte[] bytes = new byte[1024000];
           int bytesRec = handler.Receive(bytes);
           Console.WriteLine("bytesRec: {0}", bytesRec);
           Console.WriteLine("bytes[rec - 1]: {0}", bytes[bytesRec-1]);
           File.WriteAllBytes(@"new.xml", bytes);



    2 июня 2014 г. 22:49

Ответы

  • Дело в том, что Receive получает данные не одним большим пакетом, а несколькими меньшими. В вашем случае этот пакет имеет размер "около 30 кб". Для того, чтобы получить все данные необходимо получать пакеты до тех пор пока не останется доступных данных.

    Могу предложить изменить код сервера таким образом :

    Console.WriteLine("[{0}] Подключен клиент: {1}", DateTime.Now, handler.RemoteEndPoint);

    var fs = new FileStream(@"new.xml", FileMode.Create); do { var buffer = new byte[1024000]; int bytesRec = handler.Receive(buffer); Console.WriteLine("bytesRec: {0}", bytesRec); Console.WriteLine("bytes[rec - 1]: {0}", buffer[bytesRec - 1]); fs.Write(buffer,0, bytesRec); } while (handler.Available > 0); fs.Close();





Все ответы

  • Дело в том, что Receive получает данные не одним большим пакетом, а несколькими меньшими. В вашем случае этот пакет имеет размер "около 30 кб". Для того, чтобы получить все данные необходимо получать пакеты до тех пор пока не останется доступных данных.

    Могу предложить изменить код сервера таким образом :

    Console.WriteLine("[{0}] Подключен клиент: {1}", DateTime.Now, handler.RemoteEndPoint);

    var fs = new FileStream(@"new.xml", FileMode.Create); do { var buffer = new byte[1024000]; int bytesRec = handler.Receive(buffer); Console.WriteLine("bytesRec: {0}", bytesRec); Console.WriteLine("bytes[rec - 1]: {0}", buffer[bytesRec - 1]); fs.Write(buffer,0, bytesRec); } while (handler.Available > 0); fs.Close();





  • Благодарю за ответ.
    10 июня 2014 г. 9:38