Search code examples
javaobjectoutputstreamobjectinputstream

Having to recreate ObjectOutputStream every time


I have seen a few people ask similar questions but the only answer anyone ever posts is that you shouldn't have to do it.

But I've tested it both ways - and it only works this way.

Server Side

    try {
        // Obtain input and output streams to the client
        while(true) {
            ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
            ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
            Object input = in.readObject();
            if(input == RequestEnums.GETCURRENTGRID) {
                out.writeObject(ContagionServerData.getImagePixels());
                out.writeObject(ContagionServerData.getImageHeight());
                out.writeObject(ContagionServerData.getImageWidth());
            }
        }
    } catch( Exception e ) {
        e.printStackTrace();
    }

Client Side

    try {
        inputStream = new ObjectInputStream(serverSocket.getInputStream());
        outputStream = new ObjectOutputStream(serverSocket.getOutputStream());
        outputStream.writeObject(RequestEnums.GETCURRENTGRID);
        int[] imagePixels = (int[]) inputStream.readObject();
        int imageHeight = (Integer) inputStream.readObject();
        int imageWidth = (Integer) inputStream.readObject();
        copyImage(background, imagePixels, imageHeight, imageWidth);
    } catch (IOException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }

This works all day long.

But if I change it to this -

    try {
        // Obtain input and output streams to the client
        ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
        ObjectInputStream in = new ObjectInputStream(socket.getInputStream());

        while(true) {
            Object input = in.readObject();
            if(input == RequestEnums.GETCURRENTGRID) {
                out.writeObject(ContagionServerData.getImagePixels());
                out.writeObject(ContagionServerData.getImageHeight());
                out.writeObject(ContagionServerData.getImageWidth());
                out.flush();
            }
        }
    } catch( Exception e ) {
        e.printStackTrace();
    }

(I have created the input and output stream farther up in the code)

    try {
        outputStream.writeObject(RequestEnums.GETCURRENTGRID);
        outputStream.flush();
        int[] imagePixels = (int[]) inputStream.readObject();
        int imageHeight = (Integer) inputStream.readObject();
        int imageWidth = (Integer) inputStream.readObject();
        copyImage(background, imagePixels, imageHeight, imageWidth);
    } catch (IOException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }

Then I successfully receive the correct data the first time from the server - but everytime after that - I just receive the same data and not the updated data and no errors as to why.


Solution

  • When you send data on an object stream, it will send each object only once. This means if you modify and object and send it multiple times, you need to either use writeUnshared(mutableObject) or reset() which clears the cache of objects already sent.


    You can't create an ObjectOutput/InputStream repeatly. If you want to make sure data is sent instead of buffered use flush(). If you are sending data like int instead of Objects, try DataOutput/InputStream.