最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

java - Not all of the clients receive the image from the server - Stack Overflow

programmeradmin1浏览0评论

I made a simple chat application in Java. But when one of the clients sending an image, not all of the clients receive it. And those who don't receive it break..

There's my code responsible for sending and receiving images:

Client sending an image:

 public void sendImage(File selectedFile){
       try {
           BufferedImage image = ImageIO.read(selectedFile);

           // Write image into ByteArrayOutputStream to get it size
           ByteArrayOutputStream baos = new ByteArrayOutputStream();
           ImageIO.write(image, "png", baos);
           byte[] imageInBytes = baos.toByteArray();
           baos.close();

           String header = "IMAGE:" + imageInBytes.length;
           out.println(header);
           bos.write(imageInBytes);
           bos.flush();

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

    }

Server receive image and send it to all of the clients:

public void run(){
        try {
            while (true){
                String header = in.readLine();
                if (Objects.equals(header, "")) continue;

                String[] parts = header.split(":");
                String type = parts[0];
                int length = Integer.parseInt(parts[1]);

                if (type.equals("TEXT")){
                    char[] messageData = new char[length];
                    in.read(messageData, 0, length);
                    for (ClientHandler aClient : clients) {
                        aClient.sendMessage(messageData, length);
                    }
                } else if (type.equals("IMAGE")){
                    byte[] imageData = new byte[length];
                    int bytesRead = 0;
                    while (bytesRead < length) {
                        int result = bis.read(imageData, bytesRead, length - bytesRead);
                        if (result == -1) {
                            System.out.println("End of stream reached before reading the expected image size");
                            break;
                        }
                        bytesRead += result;
                        System.out.println(bytesRead);
                    }
                    for (ClientHandler aClient : clients) {
                        aClient.sendImage(imageData, length);
                    }
                }
                }
        } catch (IOException | NumberFormatException e) {
            System.out.println("Error processing image: " + e.getMessage());
        } finally {
            try{
                in.close();
                out.close();
                bis.close();
                bos.close();
                clientSocket.close();
            } catch (IOException e){
                e.printStackTrace();
            }
        }


    }

 private void sendImage(byte[] imageData, int length){
        try {
            String header = "IMAGE:" + length;
                out.println(header);
                bos.write(imageData);
                bos.flush();
            System.out.println("Image is send" + Arrays.toString(imageData));

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


Client receive image:

        new Thread(() -> {
            try{
                while(true){
                    String header = in.readLine();
                    if (Objects.equals(header, "")) continue;

                    String[] parts = header.split(":");
                    String type = parts[0];
                    int length = Integer.parseInt(parts[1]);

                    if(type.equals("TEXT")){
                        char[] messageData = new char[length];
                        in.read(messageData, 0, length);
                        SwingUtilities.invokeLater(() -> onMessageReceived.accept(new String(messageData)));
                    } else if (type.equals("IMAGE")) {
                        byte[] imageData = new byte[length];
                        int bytesRead = 0;
                        while (bytesRead < length){
                            int result = bis.read(imageData, bytesRead, length - bytesRead);
                            if (result == -1){
                                        System.out.println("End of stream reached before reading the expected image size");
                                        break;
                                    }
                                    bytesRead += result;
                                    System.out.println(bytesRead);
                        }

                        ByteArrayInputStream bais = new ByteArrayInputStream(imageData);
                        BufferedImage image = ImageIO.read(bais);
                        if(image != null){
                            SwingUtilities.invokeLater(() -> onImageReceived.accept(image));
                        }else{
                            System.out.println("Image is null");
                        }
                    }
                }
        }catch(IOException | NumberFormatException e) {
                e.printStackTrace();
            }
        }).start();
    }

Paste image into gui:

   private void onImageReceived(BufferedImage image){
                try {
                    ImageIcon icon = new ImageIcon(image);
                    JLabel imageLabel = new JLabel(icon);

                    messageArea.insertComponent(imageLabel);
                    doc.insertString(doc.getLength(), "\n", null);
                    messageArea.setCaretPosition(doc.getLength());
                    System.out.println("Image displayed in chat GUI");

                } catch (BadLocationException ex) {
                    throw new RuntimeException(ex);
                }
    }

I think the socket streams are getting overloaded, which is why the images aren't being delivered. At some point, the program might even start outputting a bunch of bytes as text instead of the image.

The debugger shows that the problem is in the following piece of code in the part where client receives the image:

while(bytesRead < imageSize){
                        bytesRead += bis.read(imageData, bytesRead, imageSize - bytesRead);
                    }

For some clients the while loop never ends and the image never appears. But for other clients, the loop successfully ends, and the client receives the image.

EDIT:

I changed the protocol by adding a text prefix and improving the separation, but the problem with the images persists.

发布评论

评论列表(0)

  1. 暂无评论