This project has moved. For the latest updates, please go here.

intermittent SerializationException

Nov 12, 2010 at 12:59 AM

First of all, my profound thanks for providing such a powerful library!  Socket programming is certainly not a strength of mine, and I found yours as a more recent attempt to overcome an issue I have invested well over 100 hours unsuccessfully trying to solve.  I am using your SimpleServerTcpSocket and SimpleClientTcpSocket.  I began with your example code, and integrated it into my code base.  My sockets receive data, then fire an event with the deserialized object as an eventArg to a listening DataTransmitter class.  That class enqueues the message, and processes them within its own timer-based loop.

Intermittently, clients are disconnected.  This occurs when the server attempts to Deserialize the bytestream into an object.  I am using the static Serialize and Deserialize methods you provided (some small modifications which didn't seem to effect the error).  With no determinable pattern, upon attempting to deserialize the bytestream, the server will throw the SerializationException:

'Binary stream '0' does not contain a valid BinaryHeader'

In the past, some of these were caused by a dll mismatch - a client with older dlls.  This is no longer the case.  I also saw it caused because I had a debug server listening to a release client.  This is no longer occurring.  The data that I am transmitting are classes I have flagged as ISerializable.  I have gone over the marshalling calls (SerializationInfo/StreamingContext constructor, GetObjectData method) countless times - if any errors remain in them, I have overlooked them in all articles I have researched, and they are now blind spots.  I am using a threadsafe Queue to receive the messages received in the DataTransmitter fired from the socket.

The one longshot idea I have seen but have not yet attempted involves a workaround suggested by a Microsoft employee in a post - to define all the member data of the serialized classes as type object.  This worked around some known limitation in the Serialization class, related to interface types.

I find myself at a loss for what to attempt next.  My inability to reproduce this, paired with my inexperience with socket-layer programming, leaves me not knowing what it is I don't know.  Having replaced the entire socket layer, the fact I'm continuing to see this error leaves me thinking it is probably a symptom or side effect of something else I am doing, but I cannot fathom what it would be at this point.

I would happily send any/all source code if you were willing to take a look at it.  Otherwise, any suggestions, or places you could point me for further potential help, would be greatly appreciated.

Thanks so much, and thank you once again for the wonderful contribution to the code community in your socket classes.

-James Russell

Coordinator
Nov 13, 2010 at 3:46 PM

I do not have much experience with serialization, but there are two socket-related situations which can cause serialization errors:

  1. The socket has been closed. In this case, the Read operation will return 0 bytes. For Nito.Async.Sockets, ReadCompleted will fire with an argument of 0.
  2. There is no framing in the protocol. See http://nitoprograms.blogspot.com/2009/04/message-framing.html

Of these two, I believe (2) is the more likely culprit.

        -Steve

May 6, 2011 at 7:29 PM
Edited May 6, 2011 at 7:32 PM

Hi Steve,

I too am having intermittent SerializationException's while using NitoAsync in a server I have developed. As with James Russell, it happens when I try to deserialize the bytestream in the ChildSocket_PacketArrived callback function. The following is what I believe is happening:

First off, in my code, I'm using the SocketPacketProtocol.WriteKeepaliveAsync() feature.

For my regular messages sent to the server, when things are working correctly, the bytestream for the object is '0 1 0 0 0 255 255 255 255 ...'. I noticed that the only time I receive the SerializationException is when the bytestream starts with '0 0 0 0 0 1 0 0 0 255 255 255 255 ...'. So other than starting with '0 0 0 0', the rest of the bytestream is the same.

While looking at the code for NitoAsync, I noticed that for every message two WriteAsync's were done, one for the length prefix and the other for the packet. Is it possible that the following is happening?

1) the length prefix stream is sent to the server

2) the WriteKeepalive is sent to the server (which would explain the four 0 bytes)

3) the packet is sent to the server

Therefore the bytes for the WriteKeepalive is put in the front of the buffer before the packet is sent. If this seems feasible to you, is there anyway to fix this? Would I have to provide some type of locking behavior in my client code so that the WriteKeepalive message would not be sent at the same time as my message?

Thanks for your help in advance,

Cory

Coordinator
May 6, 2011 at 8:29 PM
crainbeau wrote:

While looking at the code for NitoAsync, I noticed that for every message two WriteAsync's were done, one for the length prefix and the other for the packet. Is it possible that the following is happening?

1) the length prefix stream is sent to the server

2) the WriteKeepalive is sent to the server (which would explain the four 0 bytes)

3) the packet is sent to the server

Therefore the bytes for the WriteKeepalive is put in the front of the buffer before the packet is sent. If this seems feasible to you, is there anyway to fix this? Would I have to provide some type of locking behavior in my client code so that the WriteKeepalive message would not be sent at the same time as my message?


Are you calling WriteKeepaliveAsync from a different thread than the one calling WritePacketAsync?

       -Steve

May 6, 2011 at 8:37 PM
Edited May 6, 2011 at 8:49 PM

Steve,

It is being called in the callback function for a Nito.Async.Timer object.

Update: I realize my comment was not clear. Yes, WriteKeepaliveAsync is being called on a different thread than the call for WritePacketAsync.

Cory