Garry
Garry

Reputation: 2355

java How to get faster speed using socket

I'm trying to make remote Desktop Application. but data transfer speed is slow anyone know how to speed up transfer speed my client app running on android

public class SendLiveScreenThread extends Thread {

    public void run() {
        try {
            while (true) {
                Socket socket = new Socket(connect.ConnectionDetails.clientip, connect.ConnectionDetails.RemoteDesktopFeedSendPort);
                BufferedImage screenshot = new Robot().createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()));

                ByteArrayOutputStream os = new ByteArrayOutputStream();
                ImageIO.write(resize(screenshot, 400, 200), "png", os);
                InputStream fis = new ByteArrayInputStream(os.toByteArray());
                byte[] buffer = new byte[fis.available()];
                fis.read(buffer);
                ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
                oos.writeObject(buffer);
                socket.close();
            }

        } catch (Exception e) {
            e.printStackTrace();
            run();

        }
    }

    public BufferedImage resize(BufferedImage img, int newW, int newH) {
        Image tmp = img.getScaledInstance(newW, newH, Image.SCALE_SMOOTH);
        BufferedImage dimg = new BufferedImage(newW, newH, BufferedImage.TYPE_INT_ARGB);

        Graphics2D g2d = dimg.createGraphics();
        g2d.drawImage(tmp, 0, 0, null);
        g2d.dispose();

        return dimg;
    }
}

Upvotes: 0

Views: 378

Answers (2)

user207421
user207421

Reputation: 310913

  1. Don't keep creating new connections. Use the same one.
  2. Get rid of the ByteArrayOutputStream, which is a complete waste of time and space, and the ObjectOutputStream, and write the image directly to the socket output stream.

Upvotes: 1

Ringo Store
Ringo Store

Reputation: 636

Creating a remote desktop application is a non-trivial task as the amount of data involved is huge and can only be handled in near real-time with a sophisticated approach.

Your approach consists of four expensive steps:

  1. Take screenshot
  2. Resize the screenshot
  3. Compress the screenshot as PNG
  4. Transmit the screen over the network

Have you measured these steps separately? My guess is that each one is prohibitively expensive.

It could be that it is not possible to achieve sufficient speed with an Android app. Many remote desktop applications do not transmit the screen content itself. Instead the capture the graphics subsystem calls (such a drawing commands) and transmit those. If they do transmit the screen content, they only transmit what has changed.

Furthermore, you will need to have some flow control for the network transmission, i.e. you need to be able to adapt to network condition and reduce the amount of data to be transmitted if the network is slow.

You only have a chance with the remote desktop app if you make good use of hardware-optimized Android APIs. The first thing that comes to mind is to create and transmit a video stream. This reduces the amount of data to be transmitted and makes good use of the hardware.

Upvotes: 1

Related Questions