How can you tell if a socket is closed?

D

Dave Rathnow

Normally I would hang a thread on socket.getInputStream().read()
and wait for a -1 to come back but I've had to use a different
approach. My thread can't block so it is calling
socket.getInputStream().available() to see if anything is waiting and
only then will it read.

while (true) {
if (socket.getInputStream().avilable() > 0)
...read some chars...
}

My problem is I can't tell when the socket is closed by the remote
end. Socket.isClose() always returns false so it's no help. Same with
isConnected(). available() always return 0.

Can anyone tell me the trick?

Thanks,
Dave.
 
G

Gordon Beaton

My thread can't block so it is calling
socket.getInputStream().available() to see if anything is waiting
and only then will it read.

while (true) {
if (socket.getInputStream().avilable() > 0)
...read some chars...
}

My problem is I can't tell when the socket is closed by the remote
end. Socket.isClose() always returns false so it's no help. Same
with isConnected(). available() always return 0.

Unfortunately isClosed() and isConnected() don't tell you the status
of the underlying connection, they tell you the status of the Socket
object itself. As such they really only tell you whether close() or
connect() has been invoked.

The only way to tell is to (attempt to) read or write something. That
is the nature of the underlying TCP stream.

If that's a problem, why can't your thread block, or why can't you
start an additional thread that *can* block? It could also be argued
that whether the socket is closed or not is (usually) uninteresting
until you actually need to read or write.

Realize too that relying on available() wastes most of your CPU while
you spin. Additionally it prevents you from detecting EOF since
available() will return 0 then and you won't read.

A better solution is Selector.select() in java.nio, which is quite
similar to using select() in the standard socket API and lets you
handle IO from several sources in the same thread. The variants
select(timeout) and selectNow() let you do so without blocking.

/gordon
 
L

Leon Lambert

I have resorted to a dummy read so that an exception is thrown when the
connection is broken.

// dummy read on raw input to force error if connection broke
// this doesn't actually ready anything but does throw connection broken
exception
socket.getInputStream().read(tempBuffer,0,0);
for (;socket.available() >= bytesToRead;){
}

Hope this helps
Leon Lambert
 
R

Roedy Green

Normally I would hang a thread on socket.getInputStream().read()
and wait for a -1 to come back but I've had to use a different
approach. My thread can't block so it is calling
socket.getInputStream().available() to see if anything is waiting and
only then will it read.

What I have done in two of my big traffic apps is send a dummy
heartbeat packet every N seconds in both directions if there has been
no other traffic. This keeps the channel open and avoids reads timing
out. You find out within N seconds if something has gone awry and
attempt to open a new socket.

There may be some lower level way of accomplishing the same thing with
a dummy heartbeat TCP/IP probe of 0 bytes. In any case, this
application level packet is something very explicit to deal with and I
can easily tell if it is working.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top