1

我想做什么:

client connects to server
server sends READY
client takes screenshot and sends it
server processes image

server sends READY
client takes screenshot and sends it
server processes image
...

我有一个工作的客户端和服务器:

Client() {

    try {
        socket = new Socket(host, 4444);
        in = new DataInputStream(socket.getInputStream());
        out = new DataOutputStream(socket.getOutputStream());
        int ix = 0;
        while (true) {
            switch (in.readInt()) {
            case Var.READY:
                image = new Robot().createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()));
                ByteArrayOutputStream byteArrayO = new ByteArrayOutputStream();
                ImageIO.write(image,"PNG",byteArrayO);
                byte [] byteArray = byteArrayO.toByteArray();
                out.writeInt(byteArray.length);
                out.write(byteArray);
                System.out.println("send screen " + ix++);
                break;
            }
        }
    } catch (UnknownHostException e) {
        System.err.println("Don't know about host");
        System.exit(1);
    } catch (IOException e) {
        System.err.println("Couldn't get I/O for the connection " + e.getMessage());
        System.exit(1);
    } catch (Exception e) {
        e.printStackTrace();
        System.exit(1);
    }
}

服务器:

 public class ServerWorker implements Runnable {

private Socket socket = null;

DataInputStream in = null;
DataOutputStream out = null;

ServerWorker() {

}

synchronized void setSocket(Socket socket) {
    this.socket = socket;
    try {
        in = new DataInputStream(socket.getInputStream());
        out = new DataOutputStream(socket.getOutputStream());
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    notify();
}

public synchronized void run() {
    int ix = 0;
    try {
        while (true) {
            out.writeInt(Var.READY);
            int nbrToRead = in.readInt();
            byte[] byteArray = new byte[nbrToRead];
            int nbrRd = 0;
            int nbrLeftToRead = nbrToRead;
            while(nbrLeftToRead > 0){ 
                int rd =in.read(byteArray, nbrRd, nbrLeftToRead);
                if(rd < 0)
                    break;
                nbrRd += rd; // accumulate bytes read
                nbrLeftToRead -= rd;
            }
            //Converting the image
            ByteArrayInputStream byteArrayI = new ByteArrayInputStream(byteArray);
            BufferedImage image = ImageIO.read(byteArrayI);
            System.out.println("received screen " + ix++);
            //image.flush();
            File of = new File("RecvdImg" + ix + ".jpg");
            ImageIO.write(image, "PNG" ,of);
            System.out.println("Sleeping 1..");
            Thread.sleep(1000);
        }
    } catch (Exception e) {
        e.printStackTrace();
        Thread.currentThread().interrupt();
    }
}
}

那么你可能会问什么问题?好吧,我做得对吗?活动监视器告诉我客户端不断占用大约 40% 的 cpu,这不是很好。

只是想知道是否有人能指出我正确的方向来提高代码的效率。

4

2 回答 2

0

在我看来,您应该避免使用无限循环,例如

while (true)

循环喜欢

while(!connectionAborted)

在这种情况下会更好。

你也应该看看
Socket.setSoTimeout()

SoTimeout 会in.readInt()在特定时间后取消 ie 的读取过程,具体取决于您的参数。
结果是在这一行SocketTimeoutException抛出了 a,但您的代码不会停留在该代码行上,并且可以对不同的用户输入做出反应。

于 2012-08-12T22:54:46.383 回答
0

客户端可以检测图像是否已更改,如果没有更改,则可以向服务器发送一个标志,指示重用接收到的先前图像。或者您可以“区分”图像并仅将更改的区域发送到服务器,服务器将重新组合图像。这减少了带宽使用,也许还减少了 CPU 使用。

此外,客户端应该在switch.

于 2012-08-12T22:46:37.380 回答