Question How receive a complete screenshot/text in Async socket?

King Sauron

New member
Joined
Jun 25, 2019
Messages
1
Programming Experience
1-3
I have a Java android code that sends data (image or text) to a C# application, to receive these data I'm using Async socket. But exists a problem that is relative to BeginReceive() function is not receiving the complete data when is sent an image. Then how I can make a kind of "loop" to receive full data and after show the image on Picturebox (for example)?

i'm always getting the error Invalid Parameter in this line

C#:
var bitmap = new Bitmap(msInner);

and using compression also happens the same here:

C#:
z.CopyTo(msInner);

IvalidDataException

on ServerReceivedImage() method respectively.

using this:

C#:
File.WriteAllBytes(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyPictures), "image.png"), newImage);

i noted that is receiving only 15KB (size of file without use compression).

PS: The android code is OK. My problem is only with C# code.

Form:
private Listener listener;
private Thread startListen;
private Bitmap _buffer;


    public frmMain()

    {

      InitializeComponent();

    }

    private void serverReceivedImage(Client client, byte[] image)

    {

        try

        {

            byte[] newImage = new byte[image.Length - 6];

   

            Array.Copy(image, 6, newImage, 0, newImage.Length);

   

                using (var stream = new MemoryStream(newImage))

                {

                    using (var msInner = new MemoryStream())

                    {

   

                      stream.Seek(2, SeekOrigin.Begin);

   

                      using (DeflateStream z = new DeflateStream(stream, CompressionMode.Decompress))

                      {

                        z.CopyTo(msInner);

                      }

   

                      msInner.Seek(0, SeekOrigin.Begin);

   

                      var bitmap = new Bitmap(msInner);

                      Invoke(new frmMain.ImageCompleteDelegate(ImageComplete), new object[] { bitmap });

                    }

                }

        }

         catch (Exception)

         {

            System.Diagnostics.Process.GetCurrentProcess().Kill();

         }

    }

   

    private delegate void ImageCompleteDelegate(Bitmap bitmap);

    private void ImageComplete(Bitmap bitmap)

    {

       if (_buffer != null)

           _buffer.Dispose();

   

           _buffer = new Bitmap(bitmap);

           pictureBox1.Size = _buffer.Size;

           pictureBox1.Invalidate();

    }

   

    private void pictureBox1_Paint(object sender, PaintEventArgs e)

    {

      if (_buffer == null) return;

          e.Graphics.DrawImage(_buffer, 0, 0);

    }

   

    private void startToolStripMenuItem_Click(object sender, EventArgs e)

    {

      startListen = new Thread(listen);

      startListen.Start();

    }

   

    private void listen()

    {

      listener = new Listener();

      listener.BeginListen(101);

      listener.receivedImage += new Listener.ReceivedImageEventHandler(serverReceivedImage);

   

      startToolStripMenuItem.Enabled = false;

    }

Listener:
class Listener
{
   
        private Socket s;
        public List<Client> clients;
       
        public delegate void ReceivedImageEventHandler(Client client, byte[] image);
        public event ReceivedImageEventHandler receivedImage;
   
        private bool listening = false;
   
        public Listener()
        {
            clients = new List<Client>();
            s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        }
   
        public bool Running
        {
            get { return listening; }
        }
   
        public void BeginListen(int port)
        {
            s.Bind(new IPEndPoint(IPAddress.Any, port));
            s.Listen(100);
            s.BeginAccept(new AsyncCallback(AcceptCallback), s);
            listening = true;
        }
   
        public void StopListen()
        {
            if (listening == true)
            {
                s.Close();
                listening = false;
            }
        }
   
        void AcceptCallback(IAsyncResult ar)
        {
            Socket handler = (Socket)ar.AsyncState;
            Socket sock = handler.EndAccept(ar);
            Client client = new Client(sock);
            clients.Add(client);
   
            sock.BeginReceive(client.buffer, 0, client.buffer.Length, SocketFlags.None, new AsyncCallback(ReadCallback), client);
           
            client.Send("REQUEST_PRINT" + Environment.NewLine);
           
            handler.BeginAccept(new AsyncCallback(AcceptCallback), handler);
        }
   
        void ReadCallback(IAsyncResult ar)
        {
   
            Client client = (Client)ar.AsyncState;
            try
            {
                int rec = client.sock.EndReceive(ar);
                if (rec != 0)
                {
                    string data = Encoding.UTF8.GetString(client.buffer, 0, rec);
   
                    if (data.Contains("SCREEN"))
                    {
                byte[] bytes = Encoding.UTF8.GetBytes(data);
                        receivedImage(client, bytes);
                    }
                    else // not is a image, is a text
                    {
                        // prepare text to show in TextBox
                    }
                }
                else
                {
                    return;
                }
   
                client.sock.BeginReceive(client.buffer, 0, client.buffer.Length, SocketFlags.None, new AsyncCallback(ReadCallback), client);
            }
            catch
            {
                client.sock.Close();
            }
        }
   
}

Client:
class Client
{
        public Socket sock;
        public byte[] buffer = new byte[8192];
   
        public Client(Socket sock)
        {
            this.sock = sock;
        }
   
        public void Send(string data)
        {
            byte[] buffer = Encoding.ASCII.GetBytes(data);
            sock.BeginSend(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback((ar) =>
            {
                sock.EndSend(ar);
            }), buffer);
        }
}

Android code:
private byte[] compress(byte[] data) {
   
        Deflater deflater = new Deflater();
        deflater.setInput(data);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream(data.length);
        deflater.finish();
        byte[] buffer = new byte[1024];
        while (!deflater.finished()) {
            int count = deflater.deflate(buffer);
            outputStream.write(buffer, 0, count);
        }
        outputStream.close();
        byte[] output = outputStream.toByteArray();
   
        return output;
}
   
    public static DataOutputStream dos;
    public static byte[] array;
   
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.PNG, 100, bos);
    array = compress(bos.toByteArray());
   
    //...
   
    dos = new DataOutputStream(SocketBackgroundService.clientSocket.getOutputStream());
    byte[] header = ("SCREEN").getBytes(StandardCharsets.UTF_8);
    byte[] dataToSend = new byte[header.length + array.length];
    System.arraycopy(header, 0, dataToSend, 0, header.length);
    System.arraycopy(array, 0, dataToSend, header.length, array.length);
    dos.writeInt(dataToSend.length);
    dos.write(dataToSend, 0, dataToSend.length);
   
    dos.flush();
 
Back
Top Bottom