Click here to Skip to main content
15,888,527 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
Hi everyone,

I must do an application client-server for a university course.

The server must acquire the desktop, show it in a pictureBox, then send the image over tcp connection to the client (or to more clients).

The server must send the images continuously (like a little video) or to stop the send (event on a button).

Unluckily I've this error: "The binary flux doesn't contain a valid binary header; that due to a non-valid flux or a change on the version of the object between serialization and deserialization".

Please help me, I'm desperate!!!
Sissi
Posted
Updated 24-Oct-11 4:52am
v2
Comments
Yuri Vital 24-Oct-11 10:59am    
show revelant part of your code if you want to be helped...
Sissi1987 24-Oct-11 15:32pm    
I write my code! Help me!

My program run 3 times (buttons startCapture-stopCapture, startCapture-stopCapture, then ERROR)

SERVER(class VideoServer, separate from main form)

C#
namespace ChatServer
{
    class VideoServer
    {
        // The thread that will hold the connection listener
        private Thread thrListener;
        private Thread thrCapturing;
        // The TCP object that listens for connections
        private TcpListener tlsClient;
        // Will tell the while loop to keep monitoring for connections
        bool ServRunning = false;
        public static List<tcpclient> ClientList = new List<tcpclient>();
   
        private TcpClient tcpClient;
     
        public Image img;
        public Image img1;
        public event EventHandler sendPicture;
        public Form1 padre;

       public VideoServer(Image image, Form1 dad)
       {
          img = image;
          padre = dad;  
           
       }

        public void StartListening()
        {
            // Create the TCP listener object using the IP of the server and the specified port
            tlsClient = new TcpListener(3700);


            // Start the TCP listener and listen for connections
            tlsClient.Start();

            // The while loop will check for true in this before checking for connections
            ServRunning = true;

            thrListener = new Thread(KeepListening);
            thrListener.Start();

        }

        private void KeepListening()
        {
            // While the server is running
            while (ServRunning == true)
            {
                // Accept a pending connection
                tcpClient = tlsClient.AcceptTcpClient();

                // Create a new instance of Connection
                ConnectionImage newConnection = new ConnectionImage(tcpClient);
            }
        }

        public void StartCapturing()
        { 
         thrCapturing = new Thread(KeepCapturing);
         thrCapturing.Start();
        }

        public void KeepCapturing()
        {
            while (true)
            {
                
                Console.WriteLine("DEBUG: Server--> Entra nel While");
                ScreenCapture sc = new ScreenCapture(); // capture entire screen
                img = sc.CaptureScreen();
                img1 = (Image)img.Clone();
                padre.setImage(img1);
                //if (img != null) //If you choosed an image
                //{
                    //videoServer.SendImage(img); //Send the image
                    this.SendImage(img);
                //}

            }
        }

        public void StopCapturing()
        {
            thrCapturing.Abort();
            
           /* //codice per deallocare memoria
            IntPtr ptr = Marshal.AllocHGlobal(1024);
            GC.AddMemoryPressure(1024);
            if (ptr != IntPtr.Zero)
            {
                Marshal.FreeHGlobal(ptr);
                ptr = IntPtr.Zero;
                GC.RemoveMemoryPressure(1024);
            }
            */
        }

         // Add the user to the List
        public static void AddUser(TcpClient tcpUser)
        {
            ClientList.Add(tcpUser);
        }

        // Remove the user from the hash tables
        public static void RemoveUser(TcpClient tcpUser)
        {

                ClientList.Remove(tcpUser);
        }

        private  void CloseConnection(TcpClient tcpCon)
        {
            // Close the currently open objects
            tcpCon.Close();
        }

        public void SendImage(Image img)
        {
            for (int i = 0; i < ClientList.Count; i++)
            {
                TcpClient tempClient = (TcpClient)ClientList[i];
                if (tempClient.Connected) //If the client is connected
                {
                     BinaryFormatter formatter = new BinaryFormatter();
                     formatter.Serialize(tempClient.GetStream(), img);
                     //Serialize the image to the tempClient NetworkStream
                 }
                 else
                 {
                     ClientList.Remove(tempClient);
                     i--;
                 }

              
            }
        }

    }

    class ConnectionImage 
    {
        TcpClient tcpCon;
        // The thread that will send information to the client
        private Thread thrSender;

        // The constructor of the class takes in a TCP connection
        public ConnectionImage(TcpClient tcpClient)
        {
             tcpCon=tcpClient;
            // The thread that accepts the client and awaits messages
            thrSender = new Thread(AcceptClient);
            // The thread calls the AcceptClient() method
            thrSender.Start();
        }
 
        private void AcceptClient()
        {
          VideoServer.AddUser(tcpCon);
        }


    }
}

</tcpclient></tcpclient>



CLIENT'S PART

C#
//StartConnectionVideo();
        Client = new TcpClient();
         Client.Connect("127.0.0.1", 3700);
         //Connect to 127.0.0.1 on port 3700
         readingThread = new Thread(new ThreadStart(StartReading));
         //Start a new thread to receive images

         readingThread.Start();
     }


 private void StartReading()
        {
            while (true)
            {
             
                NetworkStream stream = Client.GetStream();
                    BinaryFormatter formatter = new BinaryFormatter();
                
                        Image img = (Image)formatter.Deserialize(stream);
                        //Deserialize the image from the NetworkStream
                        pictureBox.Image = img; //Show the image in the picturebox
                    
                  }
              
            }
 
Share this answer
 
v3
TCP won't necessarily give you a single receive per send; of particular relevance here is that you can get a partial receive, which is an incomplete message and which will possibly cause deserialisation to fail, and you can get a combined receive (i.e. the last part of the previous message and the first part of the next mushed together) which, if you're trying to deserialise at the start of each received block, will definitely cause a failure.

You need to 'repacketise' (or 'messagise' or any number of made up words) the stream before trying to use the contents for anything. Since you're sending binary data, a delimiter will be unreliable, so you should send a size indication at the start of each message and buffer the storage until that many bytes have been read, to form a complete message. This isn't as trivial as it might appear, because you can get a partial or combined read that includes only a part of the header (yes, even if the header is only 4 bytes). See ClientInfo.ReadInternal in my sockets library article for an example of how to handle it.
 
Share this answer
 
Comments
Sissi1987 24-Oct-11 15:32pm    
Please send me a portion of code may I use!
BobJanova 24-Oct-11 16:21pm    
As I said, look at the code in my Sockets article (specifically, ClientInfo.ReadInternal) for some inspiration. You need to send the message length and then the content, and at the other end, buffer input until you have (message length + 4) bytes (assuming you use a 32 bit int for length) and then interpret the content as appropriate to restore the image.

Since it's for a course, you should be working it out, not copy-pasting code, anyway.
Sissi1987 25-Oct-11 2:31am    
...2 weeks on this problem made me crazy and I've also other courses!!! So, thanks for the response but you CAN'T judge me!
can you write me a portion of code may I use?
 
Share this answer
 
Comments
[no name] 24-Oct-11 12:01pm    
You need to respond to the solution of which you are refering. This sends an email to the poster. Responding to your original question will not do anything.
Member 12070650 18-Mar-16 2:12am    
Can i ask how to do it the other way around. Capture images from client to server whereas the server can handle multiple client and every client, a new winform will open that contains a picture box and in it was the client's desktop image.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900