2011-05-08 5 views
0

클라이언트가있는 서버에서 여러 이미지를 가져 오려고합니다.소켓 : 타이머로 이진 이미지를 얻으십시오.

나의 궁극적 인 목표는 JNI가 매우 어려워 보이기 때문에 (동일한 컴퓨터에있는) Java 프로그램에서 Ogre가있는 C++ 프로그램에 의해 생성 된 영화에서 이미지를 가져 오는 것입니다.

시도해보기 위해 테스트를 위해 자바 클라이언트/서버를 둘 다 만들었지 만 제대로 작동하지 않습니다. 사실, 그 결과는 무작위 적이며 때로는 2, 때로는 4 개의 이미지를 얻지 만 모두가 아닙니다.

내 스트림이 잘 동기화되지 않은 것 같아요. UDP가 더 충당 될 수 없다면 궁금 해서요.하지만 어떻게해야할지 모르겠군요.

은 여기에 사용하는 코드이다 :

public class Client { 

static final int port = 3334; 
static final String host = "aluminod"; 
public static final double STEP = 2000.0; 
public static final int DELAY = 0; 

private Socket socket; 
private PrintWriter printWriter; 
private BufferedReader input; 
private int imgNumber = 0; 
private static MoviePanel pane; 
private Timer timer; 

public Client() throws UnknownHostException, IOException{ 
    this.socket = new Socket(host, port); 
    System.out.println("SOCKET = " + socket); 
    this.printWriter = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true); 
    this.input = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
    start(); 
} 

public static void main(String[] args){ 
    JFrame frame = new JFrame("test"); 
    pane = new MoviePanel(); 
    frame.setPreferredSize(new Dimension(600,400)); 
    frame.setSize(new Dimension(600,400)); 
    frame.setVisible(true); 
    frame.setLocation(Toolkit.getDefaultToolkit().getScreenSize().width/2-300, Toolkit.getDefaultToolkit().getScreenSize().height/2-200); 

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.getContentPane().setLayout(new BorderLayout()); 
    frame.getContentPane().add(pane, BorderLayout.CENTER); 
    frame.add(pane); 


    try { 
     new Client(); 
    } catch (UnknownHostException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

} 

private void start(){ 
    this.timer = new Timer(); 
    timer.scheduleAtFixedRate(new TimerTask() { 
     public void run() { 
      try { 
       sendParamsToVC(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
    }, DELAY, (long) STEP); 
} 

private void sendParamsToVC() throws IOException { 
    System.out.println("---sending---"); 
    String mess = buildMessage(); 


    //envoi du message au serveur 
    printWriter.println(mess); 

    // lecture de la réponse du serveur 
    InputStream is = socket.getInputStream(); 
    int taille = Integer.parseInt(input.readLine()); 
    byte[] mybytearray = new byte[taille]; 
    is.read(mybytearray, 0, taille);  
    BufferedImage img = ImageIO.read(new ByteArrayInputStream(mybytearray)); 

    pane.change(img); 
    imgNumber++; 
} 

private String buildMessage(){ 
    String mess; 
    if(imgNumber <10)mess = "000"+imgNumber; 
    else if(imgNumber<=13)mess = "00"+imgNumber; 
    else { 
     mess = "NO_IMG"; 
     timer.cancel(); 
    } 
    return mess; 

} 

}

public class Server { 
static final int port = 3334; 

public static void main(String[] args) throws Exception { 
    ServerSocket servsocket = new ServerSocket(port); 
    while (true) { 
     Socket client = servsocket.accept(); 
     System.out.println("connection accepted"); 

     BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream())); 
     BufferedOutputStream output = new BufferedOutputStream(client.getOutputStream()); 

     while (true) { 
      String str = reader.readLine();   // lecture du message 
      if (str.equals("NO_IMG")){ 
       System.out.println("ECHO = " + str); 
       System.out.println("fermeture"); 
       break; 
      } 
      System.out.println("ECHO = " + str); // trace locale 

      //renvoi de l'image 
      OutputStream os = client.getOutputStream(); 
      byte[]data = getByteFromImage(str); 
      PrintWriter writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(client.getOutputStream())),true); 
      writer.println(data.length); 
      writer.flush(); 
      os.write(data, 0, data.length); 
      os.flush(); 

     } 
     output.close(); 
     reader.close(); 
     client.close(); 
    } 
} 

public static byte[] getByteFromImage(String numImage) {   

    BufferedImage img = ImageLoader.createBufferedImage(numImage); 

    /** On crée la nouvelle image */ 
    BufferedImage bufferedImage = new BufferedImage(
       img.getWidth(null), 
       img.getHeight(null), 
       BufferedImage.TYPE_INT_BGR); 
    Graphics g = bufferedImage.createGraphics(); 
    g.drawImage(img,0,0,null); 
    g.dispose();    
    ByteArrayOutputStream out = new ByteArrayOutputStream(); 

    try { 
     ImageIO.write(bufferedImage, "jpeg", out); 
     out.flush(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

    byte buffer[] = out.toByteArray(); 

    try { 
     out.close(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

    return (buffer); 
} 

}

답변

0

리더/라이터 스트림은 문자 데이터이다. 바이너리 데이터에는 사용하지 마십시오. 사용 (버퍼링 된) InputStream/OutputStream

편집 : 위에서 말한 것을 잊어 버려. 나머지 코드를 검사하고 스트림을 믹싱하는 것처럼 보입니다. 그리고 클라이언트는 명령을 보낼 때 스트림을 플러시하지 않습니다. 그 수단은 클라이언트에서 버퍼링 될 수 있습니다.

편집 2 : 또 다른 오류는 읽은 내용을 확인하지 않는 것입니다. 그것은 당신이받은 많은 바이트를 집에있는 int를 반환합니다. 항상 버퍼 크기와 같지는 않습니다. 그것은 더 적을 수 있습니다. 당신이 그것을 처리해야합니다.

+0

안녕하세요. 답변에 감사드립니다. 내가 추가했습니다 : printWriter.flush(); after printWriter.println (엉망); 클라이언트에서, 그리고 더 좋아 보인다, 나는 원시에 4 이미지를 표시 할 수 있습니다. 이제 코드 줄이 다음과 같이 차단됩니다. is.read (mybytearray, 0, size); 일부 이미지 후에 단계 5에서 블록. 두 번째 편집에서 말한 내용에 관한 것 같지만 크기를 확인하는 방법을 실제로 알지 못합니다. – minod

+0

이 해결되었습니다. 당신이 맞았어요, 내가받은 바이트를 확인했다 – minod

+0

그게 당신의 문제를 해결 :) – Kaj

관련 문제