0

my program right now is sending a screen shot from one computer to the other but the result on the receiving side the img looks like:

https://i.stack.imgur.com/gyCIA.jpg

Bitmap bmpScreenShot = new Bitmap(screenWidth, screenHeight);
                  Graphics gfx = Graphics.FromImage((Image)bmpScreenShot);
                  gfx.CopyFromScreen(0, 0, 0, 0, new Size(screenWidth, screenHeight));
                  bmpScreenShot.Save("pic.jpg", ImageFormat.Jpeg);
                  MemoryStream ms = new MemoryStream();
                  bmpScreenShot.Save(ms, ImageFormat.Jpeg);
                  bmpbyte = ms.ToArray();

                  bmpScreenShot.Dispose();
                  ms.Close();
                  ///////////////////////////
                  Send_Text("" + screenHeight);
                  textBox3.Text += ("\r\nSending Hight=" + screenHeight);
                  Send_Text("" + screenWidth);
                  textBox3.Text += ("\r\nSending Width=" + screenWidth);
                  System.Threading.Thread.Sleep(200);
                  Send_Text("" + bmpbyte.Length);
                  textBox3.Text += ("\r\nSending size of:" + bmpbyte.Length);

                  textBox3.Text += "\r\nTransmiting the Screenshot";
                  stm.Write(bmpbyte, 0, bmpbyte.Length);
                  textBox3.Text += "\r\nSent IMG :)";

the code on top is the client side of it im sending the size of the pic (hight and width and array length) and it transfers properly but the server as i said has trobles getting the full pic

textBox2.Text += "\r\n Getting h";
            byte[] buffer = new byte[320];
            s.Receive(buffer);
            string str = Encoding.UTF8.GetString(buffer, 0, buffer.Length);
            Array.Clear(buffer, 0, buffer.Length);
            int h = int.Parse(str);
            textBox2.Text += "="+h+"\r\n Getting w";
            s.Receive(buffer);
             str = Encoding.UTF8.GetString(buffer, 0, buffer.Length);
             Array.Clear(buffer, 0, buffer.Length);
             int w = int.Parse(str);
            textBox2.Text += "="+w+"\r\n Getting p";
            s.Receive(buffer);
            str = Encoding.UTF8.GetString(buffer, 0, buffer.Length);
            Array.Clear(buffer, 0, buffer.Length);
            int p = int.Parse(str);
            textBox2.Text += "=" + p;
            byte[] asd = new byte[p];
            Bitmap cc = new Bitmap(h, w);


            s.Receive(asd);

            MemoryStream ms = new MemoryStream(asd);

            Image bmp = Image.FromStream(ms);
            bmp.Save("End.jpg", ImageFormat.Jpeg);
            pictureBox1.Image = bmp;

plz note that alll of the undefined things are defind some where in the code and the text box lines are just for the user interface one more thing im using the localhost \local network and it all tcp

Cœur
  • 37,241
  • 25
  • 195
  • 267

1 Answers1

3

You're not telling us how you send the information (over network? serial? TCP?), but from your code I can see one thing:

You do receive the actual number of bytes to wait for, but you're not waiting for the actual number of bytes.

byte[] asd = new byte[p];
s.Receive(asd);

This does create a byte array large enough to keep all the bytes, but does s.Receive(asd) really receive all the bytes?


After you edited your question, let me clarify one thing: TCP communication can be fragmented. Just because you send 4000 bytes in one go does not guarantee the receiver to receive 4000 bytes in one go. He probably won't. That's why the Receive method returns the actual number of bytes received.

So what your receiver needs to do is this (pseudo code):

int totalBytesRead = 0;

do
{
    int bytesRead = s.Receive(buffer);
    totalBytesRead += bytesRead;

    if (bytesRead == 0)
    {
        // Stream was closed - no more bytes
        break;
    }
    else
    {
        // Write bytesRead bytes from buffer to memory stream
    }
}
while (totalBytesRead < expectedNumberOfBytes);

if (totalBytesRead < expectedNumberOfBytes)
    throw new Exception("Premature end of transmission");

Actually, thinking things through again and looking at your code I noticed that you're actually sending JPEG bytes to the receiver. It's highly improbable that an uninitialized buffer on the receiver's side should be valid JPEG.

So while all the above is still true, I now doubt that the receiver is actually the one doing things wrong. It seems now that saving the bytes to the memory stream doesn't work properly.

I see from your code you're saving the image both to a file and to a memory stream. Does the file contain a valid picture? If not you need to look for the cause of the screenshot not being created properly. If the picture is valid, you could try two other things:

  1. Read the JPEG bytes from the file instead of creating a memory stream
  2. Don't dispose of the memory stream before sending the bytes to the client, but after that

There are questions on SO that indicate that timing seems to be an issue when saving images to a memory stream and getting the bytes from the stream. Sometimes it won't work.

Thorsten Dittmar
  • 55,956
  • 8
  • 91
  • 139
  • This, make a while out of it, control if the content you receive is 0, if it is start a timer, after a given time if it keeps delivering null then it means that there is nothing else to receive. – Steven Borges Apr 29 '14 at 09:18
  • strange it seem like it dose not have a good time gap to send all of the image – user3573002 Apr 29 '14 at 09:27
  • It's not a matter of time, it's a matter of packet fragmentation. http://stackoverflow.com/questions/756765/when-will-a-tcp-network-packet-be-fragmented-at-the-application-layer – Thorsten Dittmar Apr 29 '14 at 09:28
  • Socket receive buffer default size is 8192 bytes anyway, so, if I'm not mistaken, you can't receive more than that in one receive call. – Nicolas Repiquet Apr 29 '14 at 09:35
  • and so i need to send it the same way? - so it will fit in bytesRead – user3573002 Apr 29 '14 at 09:38
  • No. You can send it in one go. You just need to make sure the receiver is able to handle a fragmented transmission. – Thorsten Dittmar Apr 29 '14 at 10:23