user3548681
user3548681

Reputation:

C# send images over socket as fast as possible

I'm trying to send as fast as possible images over socket tried to compress... compare the images... it's still working pretty slow... btw I tried to save the image before and after the compression and size was the same.... 1 or 2 kb les...

have a look in client side code:

    Bitmap pre;
    private void Form2_Load(object sender, EventArgs e)
    {
        pre = GetDesktopImage();

        prev = Compress(ImageToByte(pre)).Length;
        theThread = new Thread(new ThreadStart(startSend));

        theThread.Start();
    }

    Bitmap curr;
    byte[] compressed;

    private void startSend()
    {
        sck = client.Client;
        s = new NetworkStream(sck);

        while (true)
        {
            curr = GetDesktopImage();

            compressed = Compress(ImageToByte(curr));

            if (Math.Abs(compressed.Length - prev) > 500)
            {
                bFormat.Serialize(s, compressed);

                prev = compressed.Length;
                count++;
            }
        }
    }  

compression methods:

byte[] Compress(byte[] b)
    {
        using (MemoryStream ms = new MemoryStream())
        {
            using (GZipStream z = new GZipStream(ms, CompressionMode.Compress, true))
                z.Write(b, 0, b.Length);
            return ms.ToArray();
        }
    }

    byte[] ImageToByte(Image img)
    {
        ImageConverter converter = new ImageConverter();
        return (byte[])converter.ConvertTo(img, typeof(byte[]));
    }

and this is the server side:

        while (true)
        {
            try
            {
                bFormat = new BinaryFormatter();

                inBytes = bFormat.Deserialize(stream) as byte[];
                inImage = ByteToImage(Decompress(inBytes));

                theImage.Image = (Image)inImage;
                count++;
                label1.Invoke(new Action(() => label1.Text = count.ToString()));

            }
            catch { }
        }

btw I've seen some people who used socket.send and didn't save the image to stream.... may u guys explain the difference? and suggest me what wrong in my code and how can I improve my algorithm?

Upvotes: 1

Views: 3085

Answers (1)

Peter Duniho
Peter Duniho

Reputation: 70652

Your question is really pushing the limits in terms of "too broad" as a close reason. The general problem of sending image data over a network is a very broad area of research, with a large number of different techniques, the specific application/user-scenario determining which technique is actually best.

That said, there is one very obvious change you can make to you code that is needed, and which might speed it up, depending on where the bottleneck is.

Specifically, you are using ImageConverter.ConvertTo() to convert the Bitmap object to a byte[], and then you are using GzipStream to compress that array of bytes. The problem with this is that ConvertTo() is already compressing the data; the byte[] it returns contains the original bitmap represented as PNG format, which is a fairly good, lossless compression algorithm for images.

So not only does compressing it again accomplish practically nothing, it costs you a lot of CPU to do that nothing. Don't do that. Just send the byte[] data as-is, without running it through GzipStream.


Now, all that said…

As I mentioned, whether that change will really help all that much depends on other things, including how large the bitmaps are, and how fast the network you are using is. If you are already saturating the network even with the inefficient code you posted in your question, then speeding that code up isn't going to help.

Techniques that are used to deal with network bandwidth as a bottleneck include (but are not limited to):

  1. Using lossy compression (e.g. JPEG, MPEG, etc.), and so simply discarding information that costs too much to send.
  2. Using a differential compression technique (e.g. MPEG, MP4, Quicktime, etc.), which takes advantage of the fact that when dealing with motion picture video, most of the pixels from one frame to the next are unchanged or at least are very similar.
  3. Sending rendering commands instead of bitmap data. This is commonly used for things like VNC or Microsoft's Remote Desktop/Terminal Server APIs, and takes advantage of the fact that on-screen drawing is very commonly affecting a large number of pixels using relatively simple drawing commands (filling/outlining rectangles, drawing text, painting small bitmaps, etc.).

In many cases, these techniques are combined in varying ways to achieve maximum performance.

If you want to use these kinds of techniques, you need to do a bit more than just asking a question on Stack Overflow. It is well beyond the scope of this site to provide broad documentation and tutorials on those techniques. You'll need to research them yourself, or even better just use existing implementations to achieve your goals.

Upvotes: 1

Related Questions