3

我正在制作一个程序,将客户端屏幕发送到服务器并显示它,但它非常慢。一帧需要2-3秒,上传/下载速度不是问题。有什么我做错了/我可以改变什么来加快速度吗?

服务器:

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();
        }
    }
}

客户:

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();
        }
    }
}
4

3 回答 3

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.

于 2012-08-11T02:42:34.640 回答
2

你的问题自相矛盾。

一方面,您询问有关通过套接字发送图像的问题。另一方面,您说“一帧需要 2-3 秒,上传/下载速度不是问题。”

我建议您尝试分析您的应用程序以确定瓶颈是否在图像捕获、图像转换、图像压缩或套接字 I/O 中。其中任何一个都是合理的解释,而猜测并不是识别真实答案的好策略。

(如果您已经知道瓶颈在哪里......不要通过在问题中包含其余步骤来混淆问题。例如,如果您已经知道问题出在图像转换中,则无需甚至提到您正在通过网络发送图像。但如果您不知道这一点,请不要向我们提供潜在的虚假信息......比如“上传/下载速度不是问题”。)

于 2012-08-11T02:52:47.120 回答
2

我相信所有给出的答案都不能解决问题。我怀疑问题不是网络连接,而是 ImageIO.read(InputStream) 方法。这个版本的方法简直太慢了。如果您尝试从本地驱动器将其作为流加载(而 ImageIO.read(File) 执行得很好),也会发生 2-3 秒。

我解决了这个问题:

ImageIO.setUseCache(false);

此处的更多信息: 字节数组到缓冲图像的转换速度很慢

于 2016-11-02T18:35:42.763 回答