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.

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))
{
    // ...
}