Проблема с использованием XMLSerializer для сериализации и десериализации - PullRequest
1 голос
/ 20 января 2011

Я работаю с сокетами C # и использую XMLSerializer для отправки и получения данных. Данные XML отправляются с сервера клиенту по сетевому соединению по протоколу TCP / IP. XML.Serializer.Serialize(stream) сериализует данные XML и отправляет их через сокетное соединение, но когда я хочу использовать XMLSerializer.Deserialize(stream) для чтения. Отправленные данные возвращают ошибку синтаксического анализа xml.

Вот как я сериализуюсь:

Memory Stream ms = new MemoryStream();
FrameClass frame= new FrameClass ();
frame.string1 = "hello";
frame.string2 = "world";

XmlSerializer xmlSerializer = new XmlSerializer(frame.GetType());
xmlSerializer.Serialize(ms, frame);

socket.Send(ms.GetBuffer(), (int)ms.Length, SocketFlags.None);

десериализация:

FrameClass frame;
XmlSerializer xml = new XmlSerializer(typeof(FrameClass));
frame= (FrameClass)xml.Deserialize(new MemoryStream(sockCom.SocketBuffer));
listbox1.Items.Add(frame.string1);
listbox2.Items.Add(frame.string2);

Я думаю, что это как-то связано с отправкой данных один за другим. Кто-нибудь может научить меня, как это сделать правильно?

Ответы [ 3 ]

0 голосов
/ 20 января 2011

Попробуйте это:

using (MemoryStream ms = new MemoryStream())
{
    FrameClass frame= new FrameClass ();
    frame.string1 = "hello";
    frame.string2 = "world";

    XmlSerializer xmlSerializer = new XmlSerializer(frame.GetType());
    xmlSerializer.Serialize(ms, frame);
    ms.Flush();
    socket.Send(ms.GetBuffer(), (int)ms.Length, SocketFlags.None);
}

Если вы отправляете Frame XML один за другим, значит, вы не отправляете XML-документ. Сериализатор XML попытается десериализовать весь ваш документ!

У меня нет времени исследовать это сейчас, но загляните в свойство XmlReaderSettings для чтения фрагментов XML. Затем вы создадите XmlReader в потоке памяти с этими настройками и вызовете его в цикле.

Главное, чтобы смыть поток. Также полезно поместить поток в блок using, чтобы обеспечить его быструю очистку.

0 голосов
/ 21 января 2011

Кроме того, что @John сказал о вызове Flush, ваш код выглядит хорошо.

Вы говорите, что отправляете несколько фрагментов данных FrameClass, тогда код должен работать, отправляя только один фрагмент данных.

Если вам нужно отправить несколько объектов данных, то вы не можете отправить их все за один раз, иначе процесс десериализации наткнется на данные. Вы можете настроить связь между сервером и клиентом, чтобы сервер знал, что он получает.

клиент: у меня есть данные

Сервер: хорошо, я готов, отправьте его

клиент: отправляет

Сервер: завершена обработка

повторить процесс ...

0 голосов
/ 20 января 2011

Получили ли вы все данные перед попыткой десериализации (это неясно из вашего кода). Я был бы склонен получать все данные в локальную строку и десериализовать их, а не пытаться напрямую десериализовать из сокета. Это также позволит вам на самом деле посмотреть на данные в отладчике перед десериализацией.

...