tags:

views:

47

answers:

4

Hello Experts,

I am using the TCP Socket in my Java application. I am trying to receive the byte data from some device. I am using the readInt(); method for receiving the data form the device. This method works fine if i am getting the 4 bytes from the device and if the bytes are less then 4 bytes or nothing then readInt(); hangs(blocked and not returning back the control) method. It should throw EOFException exception if no data is to receive but its hanging.

Code Sample :-

DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream()); DataInputStream din = new DataInputStream(socket.getInputStream());

int res = din.readInt();

Thanks in advance. Aj

+3  A: 

An EOFException doesn't get thrown until the socket closes.

This method should block when you try to read more data than is available. It returns EOFException only when the socket closes, as this is the actual EOF condition. If the socket remains open, it blocks until it has enough data to fill the request.

This is part of the fundamental nature of the way sockets work. For Java to behave any differently, it would have to incorrectly implement socket behavior.

When putting together your socket protocol, you should consider this. Why are you waiting for an int to be received and only part of an int is being sent? This should never happen. If you want to send different types of data, you should include some sort of header byte first to tell the receiver what kind of data is coming next so it knows how to process it and what to do with it.

Erick Robertson
True, blocking is a natural behaviour.
Chris Dennett
A: 

That exception is probably only thrown when the other side of the connection closes the socket. Otherwise the receiving side has no indication that no more data is going to come, so it waits (you did tell it to get at least four bytes when you called readInt). You will have to read bytes and parse them into application blocks yourself.

Nikolai N Fetissov
A: 

The classes you are using form part of the java.io package which performs blocking I/O. The correct solution is to switch to using the non-blocking I/O classes defined in java.nio. Be warned that writing a non-blocking I/O application is non-trivial. However, it is the only solution to avoiding having your I/O thread potentially block indefinitely.

Note that as a hacky solution you could use a dedicated blocking I/O thread that simply reads and adds bytes to a BlockingQueue being polled by another thread. The consumer thread could call poll(long, TimeUnit) on the BlockingQueue with a reasonably long time-out value, and if the call returned null it could take this to mean that no more data was available. Note that this is a fairly ugly solution as it means your I/O "producer" thread would remain blocked at this point.

Adamski