I am trying to utilize the benefits of asynchronous sockets in C# with serializing/deserializing with BinaryFormatter, but am running into serveral issues. Mainly, I keep getting the error:
No map for object 1953724755
when trying to deserialize the network stream.
I've tried changing to a synchronous socket, and that seems to work fine, but when using an asynchronous one (with BeginRecieve and EndRecieve and such), I still get this error.
Here is the code where I am deserializing:
private void BeginDictionaryRecieve(IAsyncResult ar)
{
Stream socketStream = new NetworkStream(socketState.workSocket);
IFormatter dataFormatter = new BinaryFormatter();
socketState.workSocket.EndReceive(ar);
List<string> rackthatWasClicked = (List<string>)
dataFormatter.Deserialize(socketStream);
this.recievedListForRackDisplay = rackthatWasClicked;
OnDataRecieved.Invoke();
socketState.workSocket.BeginReceive(socketState.buffer, 0, StateObject.BufferSize, 0,new AsyncCallback(BeginDictionaryRecieve), socketState);
}
And here is the serialization code (synchronous):
IPAddress ipAdd = IPAddress.Parse("127.0.0.1");
TcpClient myClient = new TcpClient();
myClient.Connect(ipAdd, 8002);
Stream clientStream = myClient.GetStream();
IFormatter f = new BinaryFormatter();
f.Serialize(clientStream, ShelfDataToSend);
clientStream.Dispose();
myClient.Dispose();
I should note that I am using BinaryFormatter because I can't seem to find a way to serialize an object other than a string with normal .Write operations on a socket.
Thanks to the direction from Hans, I was able to find a solution that works nicely. I'm now receiving data like this:
try
{
StateObject state = (StateObject) ar.AsyncState;
Socket client = state.workSocket;
int bytesRead = client.EndReceive(ar);
if (bytesRead > 0)
{
stream.Write(state.buffer, 0, bytesRead);
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(BeginDictionaryRecieve), state);
}
else
{
if (stream.Length > 1)
{
BinaryFormatter formatter = new BinaryFormatter();
stream.Position = 0;
this.recievedListForRackDisplay =(List<string>)formatter.Deserialize(stream);
OnDataRecieved.Invoke();
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(BeginDictionaryRecieve), state);
}
}
}
catch (Exception e)
{
throw e;
}
It should also be noted that this solution only works if the client Socket is disposed of after sending its data.