- Home /
BinaryFormatter and MemoryStream cause a loop of "SerializationException: Unexpected binary element: 0"
Hi, Iam trying to make a multiplayer game using webgl.
Sending a message from player to server works, but not the other way around.
I have this in Update function
         int recConnectionId;
         int recChannelId;
         byte[] recBuffer = new byte[1024];
         int bufferSize = 1024;
         int dataSize;
         byte error;
         NetworkEventType recNetworkEvent = NetworkTransport.ReceiveFromHost(
             socketId, out recConnectionId, out recChannelId, recBuffer, 
             bufferSize, out dataSize, out error);
 
         switch (recNetworkEvent)
         {
             case NetworkEventType.DataEvent:
 
                 MemoryStream str = new MemoryStream(recBuffer);
                 
                 BinaryFormatter formatter = new BinaryFormatter();
                 //the line below causes a loop of exceptions in console
                 string msg = formatter.Deserialize(str) as string; 
                 Debug.Log("from server: "  + msg.ToString());                    
                 break;
         }
The switch has other cases but they are mostly empty.
The mentioned line causes a loop of "SerializationException: Unexpected binary element: 0" in console and the message itself is never written.
This exact same code works when I run it in unity editor but not when I build the app and run it in browser.
What am I doing wrong?
Thank you.
Answer by Bunny83 · Jun 28, 2017 at 08:50 PM
Your buffer size is quite small. If your message is greater than 1024 bytes it can't be obtained by a single "ReceiveFromHost" call and would be fragmented.
I barely used the new networking system. So i'm not sure if "ReceiveFromHost" guarantees to receive a complete message as long as it fits into the provided buffer. Maybe it's still fragmented.
You can only deserialize a binary stream when you can guarantee that all data from the serialized stream is available. Also you need to use the "dataSize" out value and create a Memory stream that is limited to that size. You need this constructor.
Also you should wrap your memory stream into a using statement (just for good practise):
 using(MemoryStream str = new MemoryStream(recBuffer, 0, dataSize))
 {
     // ...
 }
ps: the BinaryFormatter has a quite verbose serialization format. It seems like a waste of space to use it to send a single string value. It would be much more compact to use something like
 // sending
 byte[] data = System.Text.Encoding.UTF8.GetBytes(str);
 
 // receiving
 string str = System.Text.Encoding.UTF8.GetString(data, 0, dataSize);
The message being sent is really short.
I tried the other constructor and made sure the message would fit. It still ends up with SerializationException: Unexpected binary element: 0
I'll try the other method of sending a string but the general purpose of what Iam doing is to send more than just a string.
wait, guess I still did something wrong. I think I fixed it with a bigger buffer. making the sending message smaller didn't work but making the buffer bigger did. Thank you.
Your answer
 
 
             Follow this Question
Related Questions
Client to client Serialization 1 Answer
NetworkReader/Writer with GameObject 0 Answers
Acess server stuff by the client 0 Answers
Network Instiantiate Terrain (Voxel) issues C# 0 Answers
Bug in editor regarding networkspawn 0 Answers
 koobas.hobune.stream
koobas.hobune.stream 
                       
                
                       
			     
			 
                