3

I'm making a program that sends the clients screen to the server and displays it but it's being extremely slow. It's taking 2-3 seconds for one frame and the upload/download speed is not a problem. Is there anything I'm doing wrong/anything I can change to speed this up?

Server:

import java.awt.BorderLayout;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.zip.GZIPInputStream;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

public class Server {

    public static void main(String[] args) {
        try {
            JPanel panel = new JPanel();
            panel.setLayout(new BorderLayout());

            JLabel label = new JLabel();
            label.setSize(800, 600);
            label.setVisible(true);

            JScrollPane scroll = new JScrollPane();
            scroll.getViewport().add(label);
            panel.add(scroll, BorderLayout.CENTER);

            JFrame frame = new JFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.getContentPane().add(panel);
            frame.setSize(800, 600);
            frame.setVisible(true);

            ServerSocket serverSocket = new ServerSocket(25565);
            Socket socket = serverSocket.accept();
            GZIPInputStream in = new GZIPInputStream(socket.getInputStream());
            BufferedImage image = null;
            while(socket.isConnected()) {
                image = ImageIO.read(in);
                if(image != null) {
                    label.setIcon(new ImageIcon(image));
                    label.repaint();

                }
            }
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Client:

import java.awt.AWTException;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.io.IOException;
import java.net.Socket;
import java.util.zip.GZIPOutputStream;

import javax.imageio.ImageIO;

public class Client {

    public static void main(String[] args) {
        try {
            Robot robot = new Robot();
            Toolkit toolkit = Toolkit.getDefaultToolkit();
            Rectangle screen = new Rectangle((int) toolkit.getScreenSize().getWidth(), (int) toolkit.getScreenSize().getHeight());
            Socket socket = new Socket("127.0.0.1", 25565);
            GZIPOutputStream out = new GZIPOutputStream(socket.getOutputStream());

            while(socket.isConnected()) {
                ImageIO.write(robot.createScreenCapture(screen), "png", out);
            }
            out.close();
        } catch (AWTException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
user207421
  • 305,947
  • 44
  • 307
  • 483
user1007883
  • 69
  • 2
  • 6
  • What have you tried so far to identify the performance bottleneck? Did you do any profiling? – cyroxx Aug 10 '12 at 23:47
  • Look here: http://stackoverflow.com/questions/2293556/looking-for-a-faster-alternative-to-imageio or here: http://stackoverflow.com/questions/7726583/java-imageio-write-takes-up-to-6-seconds – paulsm4 Aug 11 '12 at 00:01
  • I'm pretty sure it's ImageIO because I remember when I was checking out which image format would be best some of them took up to 7 seconds just to write to the disk. – user1007883 Aug 11 '12 at 00:02
  • @paulsm4 I would really prefer not to use any libraries but I will if I find no other option. Any other ideas? – user1007883 Aug 11 '12 at 00:03
  • You should start by running the program under a profiler to see where the time is going. It's silly to guess when knowing is so easy. I like the Netbeans profiler interface extremely well. – Gene Aug 11 '12 at 00:14
  • It's ImageIO I just don't know how to fix it without using a library. – user1007883 Aug 11 '12 at 00:19

3 Answers3

5

If you are sending the image as png the GZIPStream is probable a bad idea. You won't achieve a signicant compression gain as png already has good compression. Depending on the kind of image you can also consider jpeg to achieve better compression.

But probably the most important is wrapping the output stream with a BufferedOuputStream:

BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream());

You can do the same in the input stream.

pmoleri
  • 4,238
  • 1
  • 15
  • 25
  • PNG actually uses zip compression, and using a GZIPInput/OutputStream will just make things slower (and most likely add data overhead instead of compression). – Harald K Jun 03 '13 at 14:08
2

Your question is contradicting itself.

On the one hand you ask about sending images over a socket. On the other you say "It's taking 2-3 seconds for one frame and the upload/download speed is not a problem."

I suggest that you attempt to profile your application to determine if the bottleneck is in the image capture, the image conversion, the image compression or the socket I/O. Any one of these is a plausible explanation, and guesswork is not a good strategy for identifying the real one.

(And if you already know where the bottleneck is ... don't confuse the issue by including the rest of the steps in your question. For instance, if you already know that the problem is in the image conversion, there's no need to even mention that you are sending the images over the network. But if you don't know this, then don't feed us potentially false information ... like "the upload/download speed is not a problem".)

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
2

I believe all given answers don't address the problem. I suspect, that the problem is not the network connection, but the ImageIO.read(InputStream) method. This version of the method is just simply insanely slow. The 2-3 seconds would also occur, if you'd try to load it from your local drive as a stream (whereas ImageIO.read(File) performs just fine).

I solved the problem with:

ImageIO.setUseCache(false);

More info here: Byte array to buffered image conversion slow

Community
  • 1
  • 1
Wolf
  • 892
  • 2
  • 8
  • 22