Luis Garcia
Luis Garcia

Reputation: 77

How can I improve send/receive speed using TCP? C#

I'm making a Remote Desktop application using TCP, I've tried/searched for many ways to capture the screen and send it but they all do the same thing.

To Send:

  1. Capture the screen using Bitmap and the copyfrom method
  2. Use memorystream to save the bitmap
  3. Use TCP socket to send the bitmap serialized

To Recive:

  1. Receive the message with readbytes method
  2. Use memorystream to store the byte array
  3. Use Image.FromStream(memorystream) to create a image

It works nice on LAN connection but when I connect with a remote server using VPN, the image takes 0.5 to 5 seconds to arrive

this is my code:

DeskTop Class:

internal static class Desktop
{
    public static Image TakeScreenShoot()
    {
        Bitmap bitmap = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
        try
        {
            using (Graphics Graphics = Graphics.FromImage(bitmap))
            {
                Graphics.CopyFromScreen(0, 0, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy);
            }
        }
        catch
        {
            bitmap = null;
        }
        return bitmap;
    }

    public static void SerializeScreen(Stream stream, Image Image)
    {
        MemoryStream memory = new MemoryStream();
        Image.Save(memory, System.Drawing.Imaging.ImageFormat.Jpeg);
        int numBytes = (int)memory.Length;
        BinaryWriter binaryWriter = new BinaryWriter(stream);
        binaryWriter.Write(numBytes);
        binaryWriter.Write(memory.GetBuffer(), 0, numBytes);
        stream.Flush()
    }

    public static Image DeserializeScreen(Stream stream)
    {
        BinaryReader binaryReader = new BinaryReader(stream);
        int numBytes = binaryReader.ReadInt32();
        byte[] buffer = binaryReader.ReadBytes(numBytes);
        MemoryStream memory = new MemoryStream(buffer);
        return Image.FromStream(memory);
    }
}

Host class

private void SendImage()
    {
        while (Status == ServerStatus.Connected)
        {
            try
            {
                Image bitmap = Desktop.TakeScreenShoot();
                Desktop.SerializeScreen(_NetStream,bitmap);
            }
            catch
            {
                
            }
        }
    }

Client Class

protected void ReciveMessage()
    {
     while(Status == ServerStatus.Connected)
      {
        try
        {
            ImageRecibed?.Invoke(Desktop.DeserializeScreen(_NetStream));
        }
        catch
        {

        }
      }
    }

How can I improve my code to run faster?

here a Video of the application speed

PD. I'm so new on this

Upvotes: 3

Views: 997

Answers (2)

Rick Jones
Rick Jones

Reputation: 234

One of the common limits to the performance of a TCP connection is:

Throughput <= WindowSize / RoundTripTime

If things were "fast" on your LAN but slow through the VPN, I assume the use of a VPN means greater distance, which means RoundTripTime will increase. And unless WindowSize increases accordingly, Throughput will decrease. So, what you want to do is increase WindowSize. How one does that will depend on the specifics of the OS/stack being used.

Upvotes: 1

ABI
ABI

Reputation: 191

I believe this is a good question. My socket programming experience is very limited. But I can think of a simple way. If you reduce the size of the byte array by compressing it before sending, the performance will probably improve slightly.

here is a good example => How to compress a Byte array without stream or system io

After the packet leaves the LAN, many external factors come into play. For example, it can make a big difference whether the VPN server you use is paid or not, or where is the location of this VPN Server? is it close to you or not?, or what is the hardware power of the vpn server you are using? There are a lot of possibilities.

Also, using Udp instead of Tcp will cause a slight increase in performance too, because the packet size of Udp is smaller and no acknowledgment. So if you use Udp and compress it before sending, maybe you can get a suitable result but the problem here is reliability. Also, even if you use Udp and compression, I'm not sure that there will be a performance increase at the level you are aiming for.

Therefore, I hope someone who is an expert on this subject will give detailed information because I am very curious about it.

Upvotes: 2

Related Questions