2012-08-12 2 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(); 
    } 
} 
} 

그래서 무슨 질문을하면 묻을지도 몰라? 글쎄, 내가 제대로하고 있니? 활동 모니터는 클라이언트 측이 지속적으로 CPU의 약 40 %를 차지한다고 말합니다.

누군가 코드를보다 효율적으로 만들 수있는 올바른 방향으로 나를 안내 할 수 있는지 궁금합니다.

답변

0

클라이언트는 이미지가 변경되었는지 감지하고, 변경되지 않은 경우 수신 된 이전 이미지를 다시 사용하도록 나타내는 플래그를 서버에 보낼 수 있습니다. 또는 이미지를 "diff"하여 변경된 영역 만 서버로 보내면 이미지가 다시 구성됩니다. 따라서 대역폭 사용량과 CPU 사용량이 줄어 듭니다.

또한 클라이언트는 수신 무한 루프에서 switch 다음에 잠시 대기해야합니다.

+0

감사합니다. 변경 감지 기능을 구현합니다! 잠자는 동안, 뭔가 올바르게받을 때까지 in.readInt() 블록처럼 필요한 것입니까? – YRM

+0

잠자기와 관련해서는 클라이언트가 대부분의 경우 in.readInt()에서 차단되어야합니다. –

+0

하지만 readInt가 CPU 사이클을 소비하는 경우 걱정됩니다. 어쨌든 이미지를 보낸 후 클라이언트가 요청을 다시 기다리기 전에 잠시 휴식을 취할 수 있기 때문에 수면이 성능을 향상시킵니다. –

0

내 생각에 당신은 그런 상황에서 더 나은

while(!connectionAborted) 

처럼

while (true) 

루프처럼 infinit - 루프를 사용하지 않아야합니다.

또한 당신은 SoTimeout은 매개 변수에 따라 시간의 특정 시간 후에 즉 in.readInt()의 독서 프로세스를 취소
Socket.setSoTimeout()

에서 살펴 보셔야합니다.
결과적으로이 줄에 이 발생하지만 코드가이 코드 라인에서 멈추지 않아 다른 사용자 입력에 반응 할 수 있습니다.

관련 문제