- 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