Question

I am using Java and ObjectInputStream and ObjectOutputStream to write a TCP client/server pair. The server sends data through the ObjectOutputStream, and the client receives the data in the ObjectInputStream.

Part of the client code is below:

try {
    newMessage = (Message) in.readObject();
    System.out.println(newMessage);

} catch (Exception e) { // temporary
    System.out.println(e);
}

Unfortunately readObject() is a blocking method, which means that if there is no new Object in the ObjectInputStream, it will simply wait until one arrives.

(Note: Unlike readInt(), readObject() does not throw an EOFException when the EOF has been reached.)

This is a problem: This may be in a separate thread, but I do not want the thread to hang while waiting for a new message to arrive. I would rather use a Timer to schedule a periodic check of ObjectInputStream.

How can I check whether there is new data in the ObjectInputStream, so that I can avoid calling readObject() when there is no new data?

Was it helpful?

Solution

The correct implementation is to block. Attempts to try to figure out if there is enough data available will not work reliably since you don't even know how many bytes you have to look for. Streams also often don't know how much data is available because that depends on the somewhere in your operating system handled network stack and other parameters.

There is a nonblocking alternative to blocking streams in the java.nio package which can handle multiple connections in a single thread but that's an entirely different story.

OTHER TIPS

Writing side can write object into byte array via ByteArrayOutputStream. Then it sends length (int) and then byte arrray. Receving sides reads the length and then bytes into byte array, then reads object from byte array via ByteArrayInputStream

My suggestion is using a NIO framework such as Netty to solve this problem. Netty is event based. When an incoming message is decoded by the NIO-thread(which is managed by Netty itself), you will receive a corresponding event. Then you can just send the message to your own working thread and process it.

Or if you don't like to involve 3rd-party dependencies, just use two thread to solve this problem. One thread loops and blocks on readObject(), once it gets an incoming message, it puts the message to a Queue such as java.util.concurrent.LinkedBlockingQueue. And the other thread is scheduled to check the queue with some rate, with LinkedBlockingQueue.peek() method. If peek returns something, just poll it out from the queue and handle it. If not, the thread won't be blocked and so it can to something else.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top