0

I've made these codes to send and receive an Image with a TCP socket but the receive code didn't work, hope you can help me this is the Send Code

public void SendImage()
{
    int ScreenWidth = Screen.GetBounds(new Point(0, 0)).Width;
    int ScreenHeight = Screen.GetBounds(new Point(0, 0)).Height;
    Bitmap bmpScreenShot = new Bitmap(ScreenWidth, ScreenHeight);

    Graphics gfx = Graphics.FromImage((Image)bmpScreenShot);
    gfx.CopyFromScreen(0, 0, 0, 0, new Size(ScreenWidth, ScreenHeight));
    bmpScreenShot.Save(Application.StartupPath + "/ScreenShot.jpg", ImageFormat.Jpeg);
    byte[] image = new byte[1];
    bmpScreenShot = ResizeBitmap(bmpScreenShot, 300, 300);

    image = ImageToByte(bmpScreenShot);
    //get the length of image (length of bytes)
    int NumberOfBytes = image.Length;
    //put the size into a byte array
    byte[] numberofbytesArray = BitConverter.GetBytes(NumberOfBytes);

    //send the size to the Client
    int sizesend = sck.Send(numberofbytesArray, 0, numberofbytesArray.Length, 0);
    if (sizesend > 0)
    {
        MessageBox.Show("Size Sent");
    }
    //send the image to the Client
    int imagesend =sck.Send(image, 0, NumberOfBytes, 0);
    if (imagesend > 0)
    {
        MessageBox.Show("Image Sent");
    }
}

And Here is the Receive Code

public void ReceiveImage()
{
    if (sck.Connected)
    {
        NetworkStream stream = new NetworkStream(sck);
        byte[] data = new byte[4];

        //Read The Size
        stream.Read(data, 0, data.Length);
        int size = IPAdress.HostToNetworkOrder(BitConverter.ToInt32(data,0));
        // prepare buffer
        data = new byte[size];

        //Load Image
        int read = 0;
        while (read != data.Length)
        {
           read += stream.Read(data, read, data.Length - read);
        }
        //stream.Read(data, 0, data.Length);
        //Convert Image Data To Image
        MemoryStream imagestream = new MemoryStream(data);
        Bitmap bmp = new Bitmap(imagestream);
        pictureBox1.Image = bmp;                    
    }
}

Edit After removing IPAdress.HostToNetworkOrder to the following

int size = BitConverter.ToInt32(data,0);

there's still a problem. The problem is when I send the size, it's sent as 5kb but when I receive it I find it to be closer to 2GB.

Further more, I get an error at this line

read += stream.Read(data, read, data.Length - read);

With the following message

Unable to read data from the transport connection. An operation on a socket could be performed because the system lacked sufficient buffer space or because a queue was full.

tshepang
  • 12,111
  • 21
  • 91
  • 136
Tarek Adel
  • 161
  • 1
  • 6
  • 15
  • What value is in *size* just before you try to execute the line `data = new byte[size];`? – Eric J. Jul 31 '12 at 00:02
  • -1991225785 is the value but when i removed the IPAdress.HostToNetworkOrder it became positive – Tarek Adel Jul 31 '12 at 00:07
  • It seems like you'd want the opposite - `IPAddress.NetworkToHostOrder`, no? You're getting it from the network and need it as an int on the current host. – ceyko Jul 31 '12 at 00:08
  • btw, you don't have to assign `image`, since you assign it to the result of "ImageToByte" just a few lines after that. Trying to allocate 1 000 000 000 bytes and then throwing it away seems like a waste... – Patrick Jul 31 '12 at 00:18
  • Where is your ImageToByte() function? That appears to be flawed and returning more bytes than need be. Check this SO link that shows how to convert an image to byte and vice-versa: http://stackoverflow.com/questions/8764280/c-sharp-image-to-byte-and-byte-to-image – Prahlad Yeri Jul 31 '12 at 11:56
  • public byte[] imageToByteArray(System.Drawing.Image imageIn) { MemoryStream ms = new MemoryStream(); imageIn.Save(ms,System.Drawing.Imaging.ImageFormat.Gif); return ms.ToArray(); } This is my ImageToByte() – Tarek Adel Jul 31 '12 at 12:25
  • Let me rephrase my previous comment. Doing `byte[] b = new byte[1]; b = new byte[2];` makes the initial assignment unnecessary. You can just write `byte[] image = ImageToByte()`.. – Patrick Jul 31 '12 at 13:56
  • I edited your question to include the former text as well. IMO, the original question should be intact, since others with the same problem should be able to follow the progress if they are in the same situation. If you don't like it, you are free to roll it back. – Patrick Jul 31 '12 at 14:06
  • This should not make a difference..but what happens if you don't create a networkstream but just read directly from the socket? – Patrick Jul 31 '12 at 19:50

1 Answers1

1

Don't use HostToNetwork order unless you are creating a server that should be compliant with a java server/client for instance. If you do, you also need to change the order of the int data buffer you are sending.

You may also benefit from writing the bytes you receive on the client directly in to the memorystream instead of allocating data and writing the bytes to that. And an important note, don't forget to set imagestream.Position = 0 before you hand it over to the bitmap constructor.

Patrick
  • 17,669
  • 6
  • 70
  • 85
  • ok when i removed it this error came up ` Unable to read data from the transport connection. An operation on a socket could be performed because the system lacked sufficient buffer space or because a queue was full. ` – Tarek Adel Jul 31 '12 at 00:12
  • @TarekAdel: Where did it "come up"? When you stepped through the line of code with the `Read` function? – Patrick Jul 31 '12 at 00:16
  • i made it because when i remove it the method converts an empty byte to image, but when i put this method it waits until its not = 0 – Tarek Adel Jul 31 '12 at 00:16
  • 2
    @TarekAdel: What method converts an empty byte to an image? What is an empty byte? What do you put where, and what is not equal to 0? Would you mind elaborating on your last comment? – Patrick Jul 31 '12 at 00:22
  • @TarekAdel: How large is size when the client converted it when you get the error you described in your first comment to this answer? – Patrick Jul 31 '12 at 00:34
  • it came up in here 'read += stream.Read(data, read, data.Length - read);', sry for the delay the electricity went down – Tarek Adel Jul 31 '12 at 01:15
  • @TarekAdel: The size should be a warning signal here. Trying to receive an image of a size roughly 2GB is not normal. You need to compare the size that is sent and the one that is received. If they are not the same, you need to figure out why. Based on the facts you have given (and you're not using HostToNetworkOrder anymore), I can't see why it should not work. – Patrick Jul 31 '12 at 09:11
  • oO i found where is the problem , i wrote 'byte[] image = new byte[10000*10000*10];' let me try and see if it work – Tarek Adel Jul 31 '12 at 11:11
  • Didn't Work, when i removed it and typed 1byte it sent me this size – Tarek Adel Jul 31 '12 at 11:16
  • When i checked the size before it is sent to the server , i found that its 5kb , but why does it receive it 2GB – Tarek Adel Jul 31 '12 at 11:23
  • @TarekAdel: That's for you to find out. If you want, you might edit your question and make a note of the changes you made in your code, and the new error that occurs. – Patrick Jul 31 '12 at 11:29