2016-12-14 8 views
0

Javaでクライアントサーバープログラムを作成しました。 今のところ、すべてのプログラムは:クライアントはスクリーンショットを送信し、イメージを作成してサーバーに送信し、サーバーはそのイメージをディレクトリに保存します。イメージの一部だけが全体ではなく保存されていますが、修正する必要はありますか?

何らかの理由で、サーバーによって保存されたイメージが部分的です。つまり、すべてのスクリーンショットがサーバー側に保存されているわけではありません。

クライアント側のスクリーンショット:

here is the image saved in the server side

関連コード:

private static void screenshot(){ 

    try { 

     BufferedImage image = new Robot().createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize())); 
     File compressedImageFile = new File("C:\\Gilad\\Screenshots\\compress.jpg"); 
     OutputStream os = new FileOutputStream(compressedImageFile); 


     Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("jpg"); 
     ImageWriter writer = (ImageWriter) writers.next(); 

     ImageOutputStream ios = ImageIO.createImageOutputStream(os); 
     writer.setOutput(ios); 

     ImageWriteParam param = writer.getDefaultWriteParam(); 

     param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); 
     param.setCompressionQuality(1f); 
     writer.write(null, new IIOImage(image, null, null), param); 

     os.close(); 
     ios.close(); 
     writer.dispose(); 

     Path path = Paths.get("C:\\Images\\Screenshots\\compress.jpg"); 

     byte[] compressedImage = Files.readAllBytes(path); 
     serverThread.sendOutput(compressedImage); //serverThread is object of type ThreadForServer 

    } catch (HeadlessException | AWTException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 

ThreadForServerクラスから画像を送信:

outputThread = new Thread(new Runnable(){ 

     @Override 
     public void run() { 
      byte[] imageAr; 
      //ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 
      int len; 
      byte[] lenAr; 
      try{ 
       while(true){ 
        if(outputs.isEmpty()) Thread.sleep(10); 
        else{ 
         imageAr = outputs.remove(); 
         len = imageAr.length; 
         System.out.println("length: " + len); 
         lenAr = ByteBuffer.allocate(4).putInt(len).array(); 
         System.out.println("length array: " + lenAr + " " + System.currentTimeMillis()); 
         socketOutput.write(lenAr); 
         System.out.println("Image array: " + imageAr + " " + System.currentTimeMillis()); 
         socketOutput.write(imageAr); 
         socketOutput.flush(); 
         System.out.println("Flushed: " + System.currentTimeMillis()); 

        } 
       } 
      }catch(InterruptedException | IOException e){ e.printStackTrace(); } 

     } 

    }); 
サーバ側で

InputThread:画像を保存

inputThread = new Thread(new Runnable(){ 

     @Override 
     public void run() { 
      byte[] imageAr; 
      byte[] lenAr = new byte[4]; 
      int len; 

      try{ 
       while(running){ 
        System.out.println("Server input thread: " + System.currentTimeMillis()); 
        socketInput.read(lenAr); 
        len = ByteBuffer.wrap(lenAr).asIntBuffer().get(); 
        System.out.println("length: " + len); 
        imageAr = new byte[len]; 
        socketInput.read(imageAr); 

        inputs.add(imageAr); 
        break; 

       } 
      }catch(IOException e){ 
       e.printStackTrace(); 
      } 
     } 
    }); 

サーバー:事前に

private static void startClientThreadHandler(ThreadForClient clientThread){ 
    new Thread(new Runnable(){ 

     @Override 
     public void run() { 
      try{ 
       while(true){ 
        byte[] image = clientThread.getInput(); 
        if(image == null){ 
         Thread.sleep(10); 
         continue; 
        } 

        ByteArrayInputStream in = new ByteArrayInputStream(image); 
        BufferedImage buffImage = ImageIO.read(in); 

        ImageIO.write(buffImage, "jpg", new File(IMAGE_DESTINATION + "\\image" + counter)); 
        ++counter; 

       } 
      }catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    }).start();; 
} 

ありがとう!

答えて

1

ここには多数の潜在的な問題があります。ソケット入力から読み込むときに最も可能性が高いが、しかし、次のとおりです。

   imageAr = new byte[len]; 
       socketInput.read(imageAr); 

InputStream.read(byte[])は、提供byte[]を埋めるために保証するものではありません。代わりに、読み込まれたバイト数を返します。すべてのバイトを読み取るためにreadを複数回呼び出す必要があるかもしれません。

https://docs.oracle.com/javase/8/docs/api/java/io/InputStream.html#read-byte:A-

+0

ありがとうございました! – MuffinsDev

+0

@MuffinsDevを修正しました。これが本当に問題だった場合は、正解とマークすることを検討してください。 –

0

それは同時に、あまりにも多くのコードと十分ではないコードです。

まず問題を特定します。クライアントからの転送中(すべてのバイトを送信したか)、またはサーバー上で(すべてのバイトを受信したか)、クライアント側にあるかどうか(画像が正しくキャプチャされているかどうか)を確認します。

サーバー側でsocketInput.read(imageAr)を実行すると、すべてのデータが取得されず、その一部のみが取得されます。あなたは-1になるまで繰り返し読む必要があります。

+0

この場合、-1または 'len'バイトが読み込まれるまで読み込みます。クライアント側は画像を送信した後にソケットを閉じていないので、通常のワークフローではサーバー側は-1を受け取らないはずです。 –

+0

ありがとうございます!プログラムは今すぐうまくいきます – MuffinsDev

関連する問題