我想做什么:
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,这是不好的。
只是想知道是否有人能指出我正确的方向来提高代码的效率。
答案 0 :(得分:0)
客户端可以检测图像是否已更改,如果没有,则可以向服务器发送指示重用先前接收的图像的标志。或者您可以“区分”图像并仅将更改的区域发送到服务器,服务器将重新构图。这样可以减少带宽使用量,也可能降低CPU使用率。
此外,客户端应在switch
之后的接收无限循环中休眠一段时间。
答案 1 :(得分:0)
在我看来,你应该避免使用像
这样的无限循环while (true)
像
这样的循环while(!connectionAborted)
在这种情况下,会更好。
另外你应该看看
Socket.setSoTimeout()
SoTimeout会在特定时间后取消in.readInt()
的阅读过程,具体取决于您的参数。
结果是在这一行抛出了SocketTimeoutException
,但是你的代码并没有停留在这个代码行上,并且可以对不同的用户输入作出反应。