2012-08-12 25 views
0

什么即时试图做的:通过套接字发送多张图片

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

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

另外,客户端应该在接收无限循环中睡了一会儿,之后是switch

+0

谢谢我将实施更改检测!对于睡眠,是否有必要像in.readInt()块一样,直到它收到正确的东西? – YRM 2012-08-12 22:50:48

+0

关于睡眠,无论如何,客户端应该在大部分时间都在'in.readInt()中被阻塞。 – 2012-08-12 22:51:35

+0

但是我担心readInt本身会消耗CPU周期......无论如何,我认为睡眠可以提高性能,因为在发送图像之后,客户端可以在再次等待请求之前“休息一下”。 – 2012-08-12 22:55:52

0

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

while (true) 

循环无穷远,环状

while(!connectionAborted) 

是在这种情况下更好。

你也应该在
Socket.setSoTimeout()

看看SoTimeout取消的即in.readInt()阅读过程的时间具体数额后,根据您的参数。
结果是,在这一行上抛出了一个SocketTimeoutException,但是你的代码没有卡在这个代码行上,并且可以对不同的用户输入做出反应。