Detecting socket close

V

Vuun Harjnes

Hi,

I'm having trouble detecting when a socket gets closed. I've created a
ServerSocket and a Socket but when either side closes their socket I don't
know how to detect this at the other side. I would have thought that the
isConnected() or isClosed() methods would tell me but their state doesn't
change at all once the other side of the connection closes the connection
down.

At first I thought this might be a bug but I've tried it on j2sdk 1.4.2_01
and 1.4.2_03. (On a Debian 3.0r1 box)

Doing it across two machines I can see (via ethereal) that the socket gets
created and torn down correctly.

I've got a bad feeling that its something simple that I've overlooked but I
just can't see what it is. I'd appreciate any help anyone can give me.

Regards

Haan.


Here's my sample code

serv.java
Creates a server socket at port 7777, listens for a single connection and
reports the state of that connection every 300ms.
----------------

import java.io.*;
import java.net.*;

public class serv
{
public static void main(String[] args)
{
try
{
ServerSocket sS = new ServerSocket(7777);
Socket s = sS.accept();

while (true)
{
System.out.println("" + s.isOutputShutdown() + " " +
s.isInputShutdown() + " " +
s.isClosed() + " " +
s.isConnected() + " " +
s.isBound());
try
{
Thread.sleep(300);
} catch (Exception e)
{
System.out.println(e);
}
}
} catch (Exception e)
{
System.out.println(e);
}
}
}


sock.java
Connects to the server socket created above and closes the connection after
4 seconds.
--------------------
import java.io.*;
import java.net.*;

public class sock
{
public static void main(String[] args)
{
try
{
Socket s = new Socket("127.0.0.1", 7777);

try
{
Thread.sleep(4000);
} catch (Exception e)
{
}

s.close();
} catch (Exception e)
{
System.out.println(e);
}
}
}
 
T

Tony Morris

This is the unfortunate nature of TCP.
Either end can close transmission without letting the other end know.
A common solution to this problem is to send a "Ping / Pong" request and
response at certain intervals to ensure that the connection is alive.
 
G

Gordon Beaton

I'm having trouble detecting when a socket gets closed. I've created
a ServerSocket and a Socket but when either side closes their socket
I don't know how to detect this at the other side. I would have
thought that the isConnected() or isClosed() methods would tell me
but their state doesn't change at all once the other side of the
connection closes the connection down.

You posted the exact same question the other day in c.l.j.help and the
answer hasn't changed since the one you received then: you need to
read from or write to a stream associated with the connection in order
to detect whether the socket is still connected.

If you read (carefully) the documentation for isConnected, you'll see
that it doesn't actually tell you whether the socket is connected,
only that it once was connected (i.e. that connected() has been
successfully invoked). Similarly for isClosed(), which only indicates
that close() has been called.

If there is something you don't understand about the answer or if you
have follow up questions, please don't just repeat the original
question in a new thread.

/gordon
 
V

Vuun Harjnes

Gordon said:
You posted the exact same question the other day in c.l.j.help and the
answer hasn't changed since the one you received then: you need to
read from or write to a stream associated with the connection in order
to detect whether the socket is still connected.
If there is something you don't understand about the answer or if you
have follow up questions, please don't just repeat the original
question in a new thread.

My apologies. I've been monitoring both a.c.lang.java and c.l.java.help
and according to my newsgroup client (or my newsgroup server) I haven't
received any replies. So I thought I'd try a new group....Using google
I've just realised that I'd received two replies..now I'm left wondering
what my I didn't receive them via the normal channels.

Thanks for your (and Tony's) reply. I would have thought that since the
connection must first be established, then torn down afterwards, it would
be possible to know whether the connection is still there. ie, I would
have hoped that as the server acknowledged the RST packet it would somehow
let the Socket object know that the client had terminated the connection.

Oh well, I suppose there must be a good reason for it not to work like this.

Regards,

Haan
 
G

Gordon Beaton

Thanks for your (and Tony's) reply. I would have thought that since
the connection must first be established, then torn down afterwards,
it would be possible to know whether the connection is still there.
ie, I would have hoped that as the server acknowledged the RST
packet it would somehow let the Socket object know that the client
had terminated the connection.

Yes it is possible, but the interface requires you to call read() or
write() to get the information. Consider that there might be unread
data still available. Read all the remaining data first, and
subsequent attempts will result in an EOF indication.

If you are using selection keys (java.nio), the socket will becomes
ready for reading and writing when the remote closes, but you still
need to actually invoke read() or write() to detect the close. This
isn't java, it's the way the Berkeley socket interface works.

/gordon
 
E

Esmond Pitt

Gordon said:
If you are using selection keys (java.nio), the socket will becomes
ready for reading and writing when the remote closes, but you still
need to actually invoke read() or write() to detect the close. This
isn't java, it's the way the Berkeley socket interface works.

Gordon, this isn't quite right. The case is the same as for reading and
writing: you can only detect the EOF after you've read all the data. If
there's unread data, the socket state doesn't change when the FIN is
received.
 
G

Gordon Beaton

Gordon, this isn't quite right. The case is the same as for reading
and writing: you can only detect the EOF after you've read all the
data. If there's unread data, the socket state doesn't change when
the FIN is received.

Sorry I didn't mean to imply that using select() was somehow a
shortcut for detecting EOF, rather that it too requires the read() or
write() that I'd already described.

/gordon
 

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

Staff online

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,071
Latest member
MetabolicSolutionsKeto

Latest Threads

Top