XmlSerializer.Deserialize blocks through NetworkStream

I am trying to pass XML serializable objects over a network stream.

I already used this on a UDP broadcast server, where it receives UDP messages from the local network. Here is a fragment of the server side:

while (mServiceStopFlag == false) { if (mSocket.Available > 0) { IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, DiscoveryPort); byte[] bData; // Receive discovery message bData = mSocket.Receive(ref ipEndPoint); // Handle discovery message HandleDiscoveryMessage(ipEndPoint.Address, bData); ... 

Instead, this is the client side:

 IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Broadcast, DiscoveryPort); MemoryStream mStream = new MemoryStream(); byte[] bData; // Create broadcast UDP server mSocket = new UdpClient(); mSocket.EnableBroadcast = true; // Create datagram data foreach (NetService s in ctx.Services) XmlHelper.SerializeClass<NetService>(mStream, s); bData = mStream.GetBuffer(); // Notify the services while (mServiceStopFlag == false) { mSocket.Send(bData, (int)mStream.Length, ipEndPoint); Thread.Sleep(DefaultServiceLatency); } 

It works very well.

But now I'm trying to get the same result, but on the TcpClient socket, but using the XMLSerializer instance XMLSerializer :

On the server side:

  TcpClient sSocket = k.Key; ServiceContext sContext = k.Value; Message msg = new Message(); while (sSocket.Connected == true) { if (sSocket.Available > 0) { StreamReader tr = new StreamReader(sSocket.GetStream()); msg = (Message)mXmlSerialize.Deserialize(tr); // Handle message msg = sContext.Handler(msg); // Reply with another message if (msg != null) mXmlSerialize.Serialize(sSocket.GetStream(), msg); } else Thread.Sleep(40); } 

And on the client side:

 NetworkStream mSocketStream; Message rMessage; // Network stream mSocketStream = mSocket.GetStream(); // Send the message mXmlSerialize.Serialize(mSocketStream, msg); // Receive the answer rMessage = (Message)mXmlSerialize.Deserialize(mSocketStream); return (rMessage); 

Data is sent (the available property is greater than 0), but the XmlSerialize.Deserialize method (which should deserialize the Message class).

What am I missing?

+4
source share
1 answer

Of course, because the serializer continues to read NetworkStream , and it does not end when the main element appears.

To achieve the desired result, you must use a MemoryStream , which notifies the end of the stream when the last byte has been read.

+2
source

Source: https://habr.com/ru/post/1232429/


All Articles