-2

I have currently wrote the following codes. Client and Server side. I want to send on demand an image from server to client. The image will be a screenshot from the server, so I will always be different size.

Sending the first image is a task well accomplished. But when I am sending the next the picturebox does not refresh. From debugging I can see that the bytes from server to client get through successfully. But the code seems to just receive the bytes and not continue with the rest of the code

The "commented" line for the "while" loop ( client ) seem to work in debugging, but I cannot see the result 'cause the program gets stuck in the while loop and I can't get the application's window on the foreground

I am currently testing in windows but the client is going to get adjusted to work on android

SERVER picture Server Client picture enter image description here

SERVER

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }
    Socket client;
    private void button2_Click(object sender, EventArgs e)
    {
        Bitmap bmp = TakingScreenshotEx1();
        bmp.Save("1.jpeg", ImageFormat.Jpeg);

        byte[] buffer = ReadImageFile("1.jpeg");
        int v = client.Send(buffer, buffer.Length, SocketFlags.None);
        Console.WriteLine("Image SENT!");
    }

    private Bitmap TakingScreenshotEx1()
    {
        //Create a new bitmap.
        var bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
                                       Screen.PrimaryScreen.Bounds.Height,
                                       PixelFormat.Format32bppArgb);

        // Create a graphics object from the bitmap.
        var g = Graphics.FromImage(bmpScreenshot);

        // Take the screenshot from the upper left corner to the right bottom corner.
        g.CopyFromScreen(Screen.PrimaryScreen.Bounds.X,
                         Screen.PrimaryScreen.Bounds.Y,
                         0,
                         0,
                         Screen.PrimaryScreen.Bounds.Size,
                         CopyPixelOperation.SourceCopy);

        return bmpScreenshot;
    }

    private void button1_Click(object sender, EventArgs e)
    {
        IPEndPoint iep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9999);
        Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        server.Bind(iep);
        server.Listen(100);
        Console.WriteLine("Waiting for client....");
        client = server.Accept();
    }
    private static byte[] ReadImageFile(String img)
    {
        FileInfo fileinfo = new FileInfo(img);
        byte[] buf = new byte[fileinfo.Length];
        FileStream fs = new FileStream(img, FileMode.Open, FileAccess.Read);
        fs.Read(buf, 0, buf.Length);
        fs.Close();

        GC.ReRegisterForFinalize(fileinfo);
        GC.ReRegisterForFinalize(fs);
        return buf;
    }
}

CLIENT

public Form1()
{
    InitializeComponent();
    pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
}
IPEndPoint iep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9999);
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
byte[] buffer = new byte[1000000];
private void button1_Click(object sender, EventArgs e)
{  

   if(client.Connected != true)
    client.Connect(iep);


 //   while (true)
 //   {
        int v = client.Receive(buffer, buffer.Length, SocketFlags.None);

        Console.WriteLine("Data Received!");

        Stream stream = new MemoryStream(buffer);
        var img = Bitmap.FromStream(stream);
        pictureBox1.Image = img;

 //   }

}
ehem
  • 70
  • 7
  • Firstly, to make things much easier, you should use `TcpClient` and `TcpServer`. Secondly, socket I/O is nothing like file I/O. Just because you called `Receive` doesn't mean you will get the entire packet. The server should send the length of the data first, then send the actual data. Then the client will read in the length. At that point it will read from the socket until it has the length of the data that was stated. This is usually done in a loop. – Andy Apr 15 '21 at 18:19
  • It's not clear what you're asking here. You've commented out the part that _seems_ to be problematic, so of course your code doesn't reproduce the problem you're asking about. If you uncommented the `while (true)` then you'd be blocking the UI thread, which is a topic that has only been covered thousands of times on this site already. Did you research that? You should be reading the data asynchronously. Also, while it's _possible_ that `Bitmap.FromStream()` can determine _exactly_ the number of bytes it needs to read, if it's off by even one byte, your client will wind up out of sync ... – Peter Duniho Apr 15 '21 at 18:23
  • ... with the data being sent. I don't agree that `TcpClient` and `TcpServer` are necessarily better, but the other information in the previous comment absolutely must be heeded; your data format must include some mechanism to allow the receiving endpoint to know where a single unit of data (such as, an image) begins and ends. – Peter Duniho Apr 15 '21 at 18:23
  • TcpClient and TcpServer are great but they don't fit my objective because they cannot be handled in android well. The image bytes that I send, they all get read on Receive. @PeterDuniho That sounds interesting but I don't know how to implement it. I will check how to solve the blocked UI and get back with a response. What can i use instead of `Bitmap.FromStream()` ? – ehem Apr 15 '21 at 19:07

1 Answers1

0

As Peter Duniho pointed out the while loop is blocking the UI thread

I found a fitting solution here How to wait for thread to complete without blocking UI

Also you can check Invoking the Main Thread inside Timer Method

ehem
  • 70
  • 7