0

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.

5
  • 1
    Don't use available(). Read from the stream until you have read everything you wanted to read, and this stream will block until what you want to read has been received. Don't catch Exception. And don't swallow exception stack traces. Print the stack traces of your exceptions, to know their type and origin. Commented Mar 1, 2014 at 12:45
  • Your stream looks corrupted, so you should probably post the writing code too. Commented Mar 1, 2014 at 12:50
  • @JB Nizet I write to the Stream the whole time, but when I leave out the in.available(), nothing happens. The streamReader DOES'T DO ANYTHING Commented Mar 1, 2014 at 12:54
  • You seem to be mixing both text and binary in a same connection... That can easily break. If I were you, I'd go one way or the other but not both. And since you seem to mostly do binary, go binary all the way -- or encode the binary content using Base64 for instance. Commented Mar 1, 2014 at 14:48
  • I thought the class String is serializable?? I sended String-instances as variables, I thought that should be possible? Commented Mar 2, 2014 at 11:21

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

Comments

-1

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!

2 Comments

That doesn't cause the exception you have described here.
Well, the exception raised, because the application was not able to deserialize the object with the wrong serialization-id. So the data stream seems corrupted and was unreadable

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.