2016-12-14 17 views
0

剛剛在java中寫了一個客戶端 - 服務器程序。 現在,所有的程序做:客戶端發送截圖,comprass圖像,將其發送到服務器,該服務器在一個目錄保存圖像。只有圖像的一部分被保存而不是整個圖像,我該怎麼修復?

出於某種原因,由服務器保存的圖像是局部的,這意味着並非所有的屏幕截圖保存在服務器端。

在客戶端側的屏幕截圖:

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[]。相反,它會返回讀取多少個字節。它可能需要多次讀取才能讀取所有字節。

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

相關問題