Cydhra
Cydhra

Reputation: 581

Further problems with ObjectInputStreams with Sockets

In another thread I asked for help with a problem of sockets and ObjectInputStreams.

swapnil7 answered and gave me help: My Code said:

        while(!line.equalsIgnoreCase("exit")){
            while(in.available() <= 0){}
                line = in.readObject().toString();
                System.out.println(">>> recieved: " + line);
        }

I thought, that in.available() requests, how much bytes are ready to recieve. So I did a loop, that did nothing, until in.available() said, that there are more bytes to recieve. Then swapnil7 said, that I have to do it like this:

        while(!line.equalsIgnoreCase("exit")){
            while(in.available() <= 0){
                line = in.readObject().toString();
                System.out.println(">>> recieved: " + line);
            }
        }

I worked. But that was only the test application. My real application, that uses the ObjectStreams not only for text, looks like this:

    while(true){
        try{
            while(in.available() <= 0) {
                Object obj = in.readObject();
                if(obj instanceof ArrayList){
                    Main.info("recieved package: " + obj.getClass());
                    app.sendClientUpdate(this, obj);
                }else{
                    Main.info("recieved unexpected package: " + obj.toString());
                }
            }

        }catch(Exception ex){
            Main.error("Error while reading: " + ex.getMessage());
        }
    }

This should be the exact same thing, but it throws an exception:

Error while reading: invalid type code: 42

Thrown here in code:

Main.error("Error while reading: " + ex.getMessage());

This is what I expected, when I thought, that in.available() returns the amount of recievable bytes. I thought, that this exception means, that the inputStream blocks the reading, because the buffer is empty. Now, I am confused, because on one hand, I had to do it like swapnil7 said, on the other hand, my big application throws an exception. Can anyone explain these two different behaviors to me?

P.S. English is still not my mother language :) So I'm sorry about mistakes.

EDIT: So, here is the writing part. It writes to the sockets more than one time per second (I think 6 times, or so):

public void sendPackets() throws IOException{
    out.writeObject(tanks);
    out.flush();
    out.writeObject(enemies);
    out.flush();
    out.writeObject(bullets);
    out.flush();
}

This code works perfectly, throws nothing and do not abort (Everything tested). The written objects are ArrayLists of serializble Objects, containing some primitive data.

Upvotes: 0

Views: 124

Answers (2)

Cydhra
Cydhra

Reputation: 581

Ok-.- It was that easy: I forgot to use the same generated serialization-ids at the client AND the server. By using for each object the same serialization id, everything worked perfectly. But anyway, thank you for your help!

Upvotes: -1

Stephen C
Stephen C

Reputation: 718708

Don't use in.available().

Just call in.readObject().

If there is nothing there to read yet, the readObject() call will block until some data arrives from the other end of the socket. If the socket closes, then your code will get an IOException of some kind instead of returning an object.

If you want an explanation of why your code is failing when you get rid of the available() calls, you will need to show us exactly what you are doing. Ideally create an SSCCE for the client and server sides that >>we<< can run to see the problem for ourselves.

For what it is worth, the "invalid type code: 42" indicates either a stream corruption, or that there is a mismatch between the sequences of write and read operations. There are lots of possible explanations, but without an SSCCE, it is impossible narrow it down further.

Upvotes: 2

Related Questions