Search code examples
c#arraysbytebuffertcpserverreceiver

Second byte array of frame received by Tcpclient-Tcpserver goes negative responseBytes Length = 347713


Please help me understand why when sending via the network a number of Frame converted byte array the first frame (byte array) arrives correctly, while the second byte array (the second frame) that arrive has a wrong size or even negative.

This is the client-side code that sends frames:

public static void invia(byte[] bytetosend)
{
    byte[] compressed;
    compressed = Compressor.Compressor.Compress(bytetosend);

    byte[] bytes = new byte[1024];

    try
    {
        IPAddress ipAddressremoto = IPAddress.Parse("192.168.1.191");
        IPEndPoint remoteEP = new IPEndPoint(ipAddressremoto, 8585);
        try
        {
            if (Form1.z == 0)
            {
                Form1.client = new TcpClient();
                Form1.client.Connect(remoteEP);
                Form1.streamclient = client.GetStream();
                Form1.z = 1;
            }
            Form1.streamclient.Flush();
            byte[] sizePacket = new byte[50];
            sizePacket = BitConverter.GetBytes(compressed.Length);
            System.Console.WriteLine("size of packet = " + sizePacket.Length + " compressed.Length = " + compressed.Length + " " + "size inside packet " + BitConverter.ToInt32(sizePacket, 0));
            byte[] requestWithHeader = new byte[sizePacket.Length + compressed.Length];
            sizePacket.CopyTo(requestWithHeader, 0);
            bytetosend.CopyTo(requestWithHeader, sizePacket.Length);
            streamclient.Write(requestWithHeader, 0, requestWithHeader.Length);
        }
        catch (ArgumentNullException ane)
        {
            Console.WriteLine("ArgumentNullException : {0}", ane.ToString());
        }
        catch (SocketException se)
        {
            Console.WriteLine("SocketException : {0}", se.ToString());
        }
        catch (Exception e)
        {
            Console.WriteLine("Unexpected exception : {0}", e.ToString());
        }
    }
    catch (Exception e)
    {
        Console.WriteLine(e.ToString());
    }
}

this is instead the server-side code that receives the frame, where unfortunately I get correctly, with the right size frame only the first but not the second fram NB: some old instructions are described rather than removed

public WindowsFormsServer()
{
    var frameTask = Task.Factory.StartNew(() =>
    {
        try
        {
            while (true) 
            {
                if (WindowsFormsServer.y == 0)
                {
                    WindowsFormsServer.server = WindowsFormsServer.Idea_server();
                    // WindowsFormsServer.server.ReceiveTimeout = 50000;
                    //          Console.WriteLine("Waiting for a connection...");
                    WindowsFormsServer.streamserver = server.GetStream();
                }
                //streamserver.Flush();

                byte[] responseBytes = null;

                //if (streamserver.CanRead)
                //{
                    var responseStream = new System.IO.MemoryStream();
                    byte[] sizePacket = new byte[50];

                    streamserver.Read(sizePacket, 0, sizePacket.Length);
                    int responseLength = BitConverter.ToInt32(sizePacket, 0);
                    System.Console.WriteLine("size of packet = " + sizePacket.Length + "size inside packet = " + responseLength);
                    byte[] response = new byte[responseLength];

                    int bytesReceived = 0;
                    while (bytesReceived < responseLength)
                    {
                        int bytesRead = streamserver.Read(response, bytesReceived, responseLength - bytesReceived);
                        bytesReceived += bytesRead;
                    }
                    System.Console.WriteLine("frameTask attivo \r\n");
                    responseStream.Write(response, 0, responseLength);
                    //System.Threading.Thread.Sleep(1); //added this line
                    responseBytes = responseStream.ToArray();
                    Console.WriteLine("responseBytes Length = " + responseBytes.Length);
                //}
            }
        }
        catch (NullReferenceException ex) 
        { 
            System.Console.WriteLine("Errore: " + ex.ToString()); 
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }

        try
        {
            //MessageData.Picture2 = (Bitmap)byteArrayToImage(Compressor.Compressor.Decompress(responseBytes));
            MessageData.Picture2 = (Bitmap)byteArrayToImage(responseBytes);
            CamImageBox.Image = MessageData.Picture2;
        }
        catch (NullReferenceException ex)
        {
            System.Console.WriteLine("Errore: " + ex.ToString());
        }
        catch (Exception ex)
        {
            System.Console.WriteLine("Errore: " + ex.ToString());
        }

    });
    //frameTask.Start();
    InitializeComponent();
}

This is an error on the server side that receives the frame as a byte array

'WindowsFormsServer.vshost.exe' (CLR v4.0.30319: WindowsFormsServer.vshost.exe): caricamento di 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Configuration\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Configuration.dll' completato. Caricamento dei simboli ignorato. Il modulo è ottimizzato e l'opzione del debugger 'Solo codice utente' è abilitata.
lunghezza = 5

THIS IS THE LENGTH OF COURSE THAT USE HEADER TO WRITE THE SIZE OF CLIENT SIDE SENDER BYTE ARRAY FRAME AND THEN I READ SERVER SIDE RECEIVER

inviocomandoTask attivo 
  • size of packet = 50
  • size inside packet = 347713

this is the length of the first frame received and it's correct because it's the same sent by the sender.

'WindowsFormsServer.vshost.exe' (CLR v4.0.30319: WindowsFormsServer.vshost.exe): caricamento di 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\mscorlib.resources\v4.0_4.0.0.0_it_b77a5c561934e089\mscorlib.resources.dll' completato. Modulo compilato senza simboli.

frameTask attivo

  • responseBytes Length = 347713
  • size of packet = 50
  • size inside packet = -383988050

this is the length of the second frame received and it's wrong

Eccezione generata: 'System.OverflowException' in WindowsFormsServer.exe
Eccezione generata: 'System.ArgumentNullException' in mscorlib.dll
System.OverflowException: Le dimensioni della matrice hanno superato l'intervallo supportato. The size of the array exceeded the supported range.
   in WindowsFormsServer.WindowsFormsServer.<.ctor>b__12_0() in C:\Users\vmtest\Documents\CamDisplay4\WindowsFormsServer\Form1.cs:riga 70
Errore: System.ArgumentNullException: Il buffer non può essere null.
Nome parametro: buffer
   in System.IO.MemoryStream..ctor(Byte[] buffer, Boolean writable)
   in WindowsFormsServer.WindowsFormsServer.byteArrayToImage(Byte[] bytesArr) in C:\Users\vmtest\Documents\CamDisplay4\WindowsFormsServer\Form1.cs:riga 170
   in WindowsFormsServer.WindowsFormsServer.<.ctor>b__12_0() in C:\Users\vmtest\Documents\CamDisplay4\WindowsFormsServer\Form1.cs:riga 98
Il thread 0x19ec è terminato con il codice 0 (0x0).
Il thread 0x19d4 è terminato con il codice 0 (0x0).
Il programma '[1352] WindowsFormsServer.vshost.exe' è terminato con il codice 0 (0x0).

Do you have suggestions on what happens in this second frame byte array received?* Do you think that it's caused from the server that it's receiving bytes in sync mode without an ASYNC method ?


Solution

  • byte[] sizePacket = new byte[50];
    streamserver.Read(sizePacket, 0, sizePacket.Length);
    

    Here, you're reading 50 bytes but only using the first 4 bytes. The rest is thrown away.

    I would do this:

    var br = new BinaryReader(someStream);
    var length = br.ReadUInt32();
    var contents = br.ReadBytes(length);
    

    That's really all you need.


            byte[] sizePacket = new byte[50];
            sizePacket = BitConverter.GetBytes(compressed.Length);
    

    Why always 50 bytes?? This makes no sense. Use the right length in the first place. Here, you overwrite that variable anyway so this should be:

            byte[] sizePacket = BitConverter.GetBytes(compressed.Length);
    

    System.Console.WriteLine("size of packet = " + sizePacket.Length + "size inside packet = " + responseLength);
    

    And this message is false. That's not the size of the "packet". TCP does not expose packets. The array size is 50, the read the return value from Read which might be different from 50.