2013-03-08 3 views
0

У меня есть приложение, настроенное для отправки объектов по сети путем их сериализации в XML на отправляющей стороне и десериализации их на принимающей стороне. Я сначала установил его с UDP, который работал нормально. Код так:Удаление десериализации XML из NetworkStream не удается

Отправитель:

MemoryStream ms = new MemoryStream(); 
dataSerializer.Serialize(ms, dataToSend, serNamespaceRemover); 
senderClient.Send(ms.GetBuffer(), (int)ms.Length); 

Приемник:

IPEndPoint beaconEndpoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), SharedData.udpPort); 
byte[] receiveData = beaconClient.Receive(ref beaconEndpoint); 
MemoryStream ms = new MemoryStream(receiveData); 
CommData recieved = dataDeserializer.Deserialize(ms) as CommData; 

Теперь я должен переключить его на использование TCP. Отправитель, кажется, работает отлично, и впечатляюще просто:

dataSerializer.Serialize(senderClient.GetStream(), dataToSend, serNamespaceRemover); 

Но у меня проблемы с приемником. Я попробовал простую, очевидную вещь:

NetworkStream netstr = client.GetStream(); 
CommData data = dataDeserializer.Deserialize(netstr) as CommData; 

И я получаю исключение: Существует ошибка в документе XML (5, 14). XML выглядит так:

<?xml version="1.0"?> 
<CommData> 
    <RigName>Rig 100</RigName> 
    <IsShutDown>false</IsShutDown> 
</CommData> 

Так 5,14 позиция 2 символа после окончания полученных данных. Я прочитал данные в массиве char и подтвердил, что после окончания закрывающей скобки нет ничего, поэтому я не уверен, о чем говорит десериализатор.

Между тем, если я это сделаю, то приемник работает:

NetworkStream netstr = client.GetStream(); 
byte[] arry = new byte[client.Available]; 
netstr.Read(arry, 0, client.Available); 
MemoryStream ms = new MemoryStream(arry); 
CommData data = dataDeserializer.Deserialize(ms) as CommData; 

Это кажется сумасшедшим. Почему он не может просто читать непосредственно из NetworkStream? Мне действительно нужно прочитать данные в MemoryStream, а затем передать его десериализатору?

ответ

1

См: Deserializing data sent via TCP

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

+0

Хороший улов, я сам думал по тем же линиям. Сэкономил мне несколько исследований, и я узнал что-то новое :) – Nevyn

+0

[NetworkStream.DataAvailable] (http://msdn.microsoft.com/en-us/library/system.net.sockets.networkstream.dataavailable.aspx) - это нечто близкое, но не думайте, что это поможет в вашем сценарии. – publicgk

0

Как вы узнали, когда получили весь XML-файл? Пока удаленный конец не закрыл соединение, вызов Read (который будет делать XmlSerializer) будет блокировать и ждать данных.

+1

У меня на самом деле была эта проблема раньше, но в этом случае она не блокирует, а скорее читает что-то недействительное и бросает исключение. – Mason

Смежные вопросы