Search code examples
javasocketsobjectinputstreamobjectoutputstream

Java - Sending of ImageIcon through ObjectOutputStream works first time, but not after that


I'm working on a server/client project in Java where, at any point during the running of the program, the client can request a set of details related to a unique ID, and the server returns the relevant set of details. This is done through PrintWriter objects accessing the socket.getOutputStream, and works fine.

I am trying to also include the sending/receiving of an image from the server to the client, and have met some very strange behaviour from the program.

The methods that send and receive the images are shown below:

SERVER-SIDE:

//send image associated with item
//through ObjectOutputStream to client
private void sendItemImage(BidItem item)
{
    try
    {
        //wrap object output stream around
        //output stream to client at this socket
        ObjectOutputStream imageOutput =
                new ObjectOutputStream(client.getOutputStream());
        //send image object to client
        imageOutput.writeObject(item.getItemImage());
    }
    catch (IOException ioEx)
    {
        //alert server console
        System.out.println("\nUnable to send image for item "
                        + item.getItemCode() + " to "
                        + bidderName + "!");
        //no exit from system
        //bidding can still continue
    }
}

CLIENT-SIDE:

//to be displayed on GUI
private static void receiveItemImage()
{
    try
    {
        //wrap ObjectInputStream around socket
        //to receive objects sent from server
        ObjectInputStream imageInput =
                new ObjectInputStream(socket.getInputStream());
        //read in image and store in ImageIcon instance
        image = (ImageIcon) imageInput.readObject();

        //re-create label object to be blank
        imageLabel = new JLabel();
        //remove label containing last image
        imagePanel.remove(imageLabel);
        //just ignores command if it does not already contain image

        //apply image to label
        imageLabel.setIcon(image);
        //apply image to CENTER of panel
        imagePanel.add(imageLabel, BorderLayout.CENTER);
    }
    //problem in input stream
    catch (IOException ioEx)
    {
        //alert user
        JOptionPane.showMessageDialog(
                null, "Error receiving image!");
        //allow system to continue
        //no exit
    }
    //problem casting to ImageIcon type
    catch (ClassNotFoundException cnfEx)
    {
        //alert user
        JOptionPane.showMessageDialog(
                null, "Error converting Object to ImageIcon!");
        //allow system to continue
        //no exit
    }
}

So, each time there is a request, an ObjectOutpuStream and ObjectInputStream are created to handle the passing of the image, using the socket.getOutputStream/socket.getInputStream.

These methods are first called when a client connects to the server, and the first image and set of details are sent automatically. This works fine, but any subsequent attempts at requesting the image throughout the program result in the catch (IOException) clause being met, and the error messages shown above being displayed.

I cannot for the life of me work out why it would work the first time but not again after this. If anyone could point me in the right direction, that would be great!

Thanks, Mark


Solution

  • You should only wrap a stream once. In this case, you can't wrap it again as this will not work for an Object Stream.

    Once you are wrapping the stream only once, call ObjectOutputStream.reset() after sending an image. If you don't do this it will just pass the reference to the object again (and use a lot of memory)