在套接字上发送多个图像

时间:2012-08-12 22:40:08

标签: java sockets

我想做什么:

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,这是不好的。

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

2 个答案:

答案 0 :(得分:0)

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

此外,客户端应在switch之后的接收无限循环中休眠一段时间。

答案 1 :(得分:0)

在我看来,你应该避免使用像

这样的无限循环
while (true)

这样的循环
while(!connectionAborted)
在这种情况下,

会更好。

另外你应该看看
Socket.setSoTimeout()

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