简体   繁体   中英

Deserializing XML from a NetworkStream fails

I have my application set up to send objects over the network by serializing them into XML on the sending side and deserializing them on the receiving side. I first set it up with UDP, which worked fine. Code like so:

Sender:

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

Receiver:

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;

Now I have to switch it over to use TCP. The sender seems to work fine, and is impressively simple:

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

But I'm having trouble with the receiver. I tried the simple, obvious thing:

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

And I get the exception: There is an error in XML document (5, 14). The XML looks like so:

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

So the 5,14 position is 2 chars after the end of the received data. I read the data into a char array, and confirmed that there is nothing after the end of the closing bracket, so I'm not sure what the deserializer is talking about.

Meanwhile, if I do this, then the receiver works:

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;

This seems crazy. Why can't it just read directly from the NetworkStream? Do I really have to read the data into a MemoryStream and then pass it to the deserializer?

See: Deserializing data sent via TCP

The answer there suggests that NetworkStream won't notify when the last byte is read. So it seems that your deserlializer keeps trying to read (even after reaching end; because NetworkStream doesn't notify it) from the NetworkStream and hence results in exception. You will need to read into MemoryStream.

How do you know when you have received the entire XML file? As long as the remote end has not closed the connection, calling Read (which XmlSerializer will do) will block and wait for data.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM