2016-12-14 3 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[]. Вместо этого он возвращает количество прочитанных байтов. Для чтения всех байтов может потребоваться многократное чтение.

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