Send texture over network: 'SerializationException: serializationStream supports seeking, but...'

I would like to send a small texture (16x12px) over the network. I am using the Unity 5 Low-Level Networking API.

Connecting works fine. My problem is that I can’t figure out how to send the data.

Before serialization, I convert the sent texture into a base64 string.

How do I correctly send a texture as a base64 between websockets using Unity’s UNET Low-Level API?

Sending results in an error:

SerializationException: serializationStream supports seeking, but its length is 0
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.NoCheckDeserialize (System.IO.Stream serializationStream, System.Runtime.Remoting.Messaging.HeaderHandler handler) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/BinaryFormatter.cs:155)
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize (System.IO.Stream serializationStream) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/BinaryFormatter.cs:136)
networkReceiver.Update () (at Assets/networkReceiver.cs:95)

I have two scripts: sender and receiver.

Sender script:

using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;
using System.IO;
using System;
using System.Xml;
using System.Xml.Serialization;

public class networkSender : MonoBehaviour {

    //network variables
    int myReliableChannelId;
    int socketId;
    int socketPort = 8888;
    int connectionId;

    Camera thisCam; // for screenshot taking
    public GameObject textureObjectOriginal;
 
    void Awake ()
    {
     
        thisCam = this.GetComponent<Camera> ();
     
    }

    void Start () {


        Environment.SetEnvironmentVariable("MONO_REFLECTION_SERIALIZER", "yes");


        //OPEN SOCKET
     
                //initialize on the NetworkTransport class
                NetworkTransport.Init();
             
                //For most situations using default config is fine
                ConnectionConfig config = new ConnectionConfig();
             
                //keep the channelId so we can use it later for sending/receiving
                myReliableChannelId = config.AddChannel(QosType.Unreliable);
             
                //just sets the max number of connections allowed on your soon to exist socket
                int maxConnections = 5;
                HostTopology topology = new HostTopology(config, maxConnections);
             
                //finally open the socket
                socketId = NetworkTransport.AddHost(topology, socketPort);
                Debug.Log("Sender SocketId is: " + socketId);
                // the AddHost() method returns an int which is the “HostID”
                // but screw that name: it is a SocketId.
     
     
    }
 
    public void Connect()
    {
     
        //connects us to another server

        byte error;

                //the ip for the remote device
                //the socketPort of the remote machine
                //Connect(int hostId, string address, int port, int exeptionConnectionId, out byte error);
                connectionId = NetworkTransport.Connect(socketId, "127.0.0.1", socketPort, 0, out error);
             
        //if there is a problem we get an error out
        Debug.Log("Connected to receiver. ConnectionId: " + connectionId);
     
    }
 
    void OnGUI()
    {
     
        if (GUI.Button (new Rect (10, 10, 100, 30), "Connect"))
        {
                Connect() ;
        }

        if (GUI.Button (new Rect (10, 60, 100, 80), "Send Socket Message"))
        {
                SendSocketMessage() ;
        }
     
    }
 
    //turn a texture into a stream of bytes then send those bytes out our socket connection.
    public void SendSocketMessage()
    {

        //create texture container
        Texture2D tex = new Texture2D(16, 12, TextureFormat.RGB24, false);
     
        // Initialize rendertexture and render screenshot of cam
        RenderTexture rt = new RenderTexture(16, 12, 24);
        thisCam.targetTexture = rt;
        thisCam.Render();
        RenderTexture.active = rt;
     
        // Read pixels of rendertexture into texture2d container
        tex.ReadPixels(new Rect (0,0,16,12), 0,0);
     
        //Clean up
        thisCam.targetTexture = null;
        RenderTexture.active = null; // to avoid errors
        DestroyImmediate(rt);

        //prepare texture for sending over network
        byte[] imgByteArray = tex.EncodeToJPG ();

        //for test: before sending, display texture on another object in the scene
        Texture2D receivedTexture = new Texture2D(16, 12, TextureFormat.RGB24, false);
        receivedTexture.LoadImage(imgByteArray);
        textureObjectOriginal.GetComponent<Renderer>().material.SetTexture("_MainTex", receivedTexture);

        //convert byte array to a base64 string
        string imgBase64;
        imgBase64 = Convert.ToBase64String (imgByteArray);
     
//        //--- Serialize ---
//        UnitySerializer srlzr = new UnitySerializer();
//        srlzr.Serialize(imgBase64);
//        byte[] byteArray = srlzr.ByteArray;
     
        byte[] buffer = new byte[1024];    //this is the max length of our message when it is in byte form
        int sizeToSend = 1024; //the size of our buffer
        byte error;

        //serialize image
        Stream stream = new MemoryStream();
        stream.Write(buffer, 0, sizeToSend);
        BinaryFormatter formatter = new BinaryFormatter();
        formatter.Serialize (stream, imgBase64);

        //send over network
        NetworkTransport.Send(socketId, connectionId, myReliableChannelId, buffer, sizeToSend, out error);

    }
}

Receiver script:

using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;
using System.IO;
using System.Collections.Generic;
using System;
using System.Text;

public class networkReceiver : MonoBehaviour {
 
    //network vars
    int myReliableChannelId; //use it for sending/receiving
    int socketId;
    int socketPort = 8000;
    int connectionId;

    //testobject to apply received texture to
    public GameObject textureObject;
 
    void Start ()
    {
     
        Environment.SetEnvironmentVariable("MONO_REFLECTION_SERIALIZER", "yes");
     
        //OPEN SOCKET
     
        //initialize on the NetworkTransport class
        NetworkTransport.Init();
     
        //For most situations using default config is fine
        ConnectionConfig config = new ConnectionConfig();
     
        //keep the channelId so we can use it later for sending/receiving
        myReliableChannelId = config.AddChannel(QosType.Unreliable);
     
        //just sets the max number of connections allowed on your soon to exist socket
        int maxConnections = 4;
        HostTopology topology = new HostTopology(config, maxConnections);
     
        //finally open the socket
        socketId = NetworkTransport.AddHost(topology, socketPort);
        Debug.Log("Receiver SocketId is: " + socketId);
        // the AddHost() method returns an int which is the “HostID”
        // but screw that name: it is a SocketId.
     
    }
 
 
 
    void Update () {
     
        //always check for new messages coming in
     
        //declare all the variables needed for receiving
        int recHostId;
        int recConnectionId;
        int recChannelId;
        byte[] recBuffer = new byte[1024];
        int bufferSize = 1024;
        int dataSize;
        byte error;

        // recBuffer contains the byte array message that was received
        NetworkEventType recNetworkEvent = NetworkTransport.Receive(out recHostId,
                                                                   out recConnectionId,
                                                                   out recChannelId,
                                                                   recBuffer,
                                                                   bufferSize,
                                                                   out dataSize,
                                                                   out error);
     
        switch (recNetworkEvent)
        {
                 
                case NetworkEventType.Nothing:
                 
                        break;
                 
                case NetworkEventType.ConnectEvent:
                 
                        Debug.Log("Receiver: incoming connection event received");
                        break;
                 
                case NetworkEventType.DataEvent:

                        //handle received string
                        //Stream stream = new MemoryStream(recBuffer);
                        Stream stream = new MemoryStream();
                        stream.Read(recBuffer, 0, bufferSize);
                     
                        //deserialize
                        BinaryFormatter formatter = new BinaryFormatter();
                        string receivedImgBase64 = formatter.Deserialize(stream) as string;
                     
                        //convert received base64 string to bytearray for texture display
                        byte[] imgByteArray = Encoding.ASCII.GetBytes(receivedImgBase64);
                     
                        //--- Deserialize ---
                        //UnitySerializer dsrlzr = new UnitySerializer(receivedImg);
                     
                        //create texture to display received image
                        Texture2D receivedTexture = new Texture2D(32, 24, TextureFormat.RGB24, false);
                     
                        //read received pixels to texture
                        receivedTexture.LoadImage(imgByteArray);
                     
                        //apply texture to object
                        textureObject.GetComponent<Renderer>().material.SetTexture("_MainTex", receivedTexture);
                     
                        break;
                 
                case NetworkEventType.DisconnectEvent:
                     
                        //display a disconnect message on screen.
                        Debug.Log("Receiver: disconnected");
                        break;
                     
        }
     
    }//update
 
}

Something is wrong here, but what?

Thank you & regards,
bm

Hello,
well i think the problem is with your encoding…
I did it like this…

             byte[] textureData = myTexture.EncodeToPNG();
             NetworkWriter writer = new NetworkWriter();
             writer.WriteBytesFull(textureData);
             byte[] data = writer.AsArray();