Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > Sockets - Checking For Dropped Connections & close()

Reply
Thread Tools

Sockets - Checking For Dropped Connections & close()

 
 
JTeagle
Guest
Posts: n/a
 
      10-03-2007
What is the correct way to determine if a socket to which you were
connected has been closed, either by implicitly calling close() on it,
or because the code that created it has been terminated?

This, for example, does not do what I believe it should:

import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

import javax.swing.JOptionPane;

public class TestSocketCloseApp
{
public static void main(String[] args)
{
try
{
// Create a listening socket.
ServerSocket listener = new ServerSocket(9999);

// Create a client socket and initiate a connection.
Socket client = new
Socket(InetAddress.getLocalHost().getHostAddress() , 9999);
// Stop it from lingering - when we say close, we mean close.
client.setSoLinger(false, 0);

// Accept a connection from this client socket.
Socket server = listener.accept();

// Now close the client connection.
client.close();

// What does the server say our state is?
if (server.isConnected() )
JOptionPane.showMessageDialog(null,"Apparently we're still
connected.");
else
JOptionPane.showMessageDialog(null,"As expected, we're
disconnected.");

server.close();
listener.close();
}
catch(Exception e)
{
}
}

}


It still thinks it's connected when I clearly closed the other end.

I have tried other options in my original code - grabbing the output
stream and sending data (that didn't fail, even though there should be
no link), trying to request the remote address we are connected to -
they all work as if we are still connected.

Does close() not do what it claims? I would say it's fairly
fundamental of any program that deals with socket connections to know
when the other end has dropped.

 
Reply With Quote
 
 
 
 
Gordon Beaton
Guest
Posts: n/a
 
      10-03-2007
On Wed, 03 Oct 2007 00:56:35 -0700, JTeagle wrote:
> What is the correct way to determine if a socket to which you were
> connected has been closed, either by implicitly calling close() on
> it, or because the code that created it has been terminated?


When isConnected() is true, it only indicates that s.connect() has
been called at some previous time. It says nothing about the state of
the underlying socket itself.

To determine whether the socket has been closed, attempt to read()
from it or write() to it. Either of these operations will indicate EOF
(exactly how depends on which class you use to read or write).

/gordon

--
 
Reply With Quote
 
 
 
 
Gordon Beaton
Guest
Posts: n/a
 
      10-03-2007
On Wed, 03 Oct 2007 00:56:35 -0700, JTeagle wrote:
> What is the correct way to determine if a socket to which you were
> connected has been closed, either by implicitly calling close() on it,
> or because the code that created it has been terminated?


I find it interesting that you asked the exact same question exactly 4
years (plus one day) ago. It was answered then, but you seem to be
making the same mistakes again.

/gordon

--
 
Reply With Quote
 
JTeagle
Guest
Posts: n/a
 
      10-03-2007
On Oct 3, 9:50 am, Gordon Beaton <(E-Mail Removed)> wrote:
> On Wed, 03 Oct 2007 00:56:35 -0700, JTeagle wrote:
> > What is the correct way to determine if a socket to which you were
> > connected has been closed, either by implicitly calling close() on it,
> > or because the code that created it has been terminated?

>
> I find it interesting that you asked the exact same question exactly 4
> years (plus one day) ago. It was answered then, but you seem to be
> making the same mistakes again.
>
> /gordon
>
> --


I guess that means the API is still badly named - if there were
functions that actually did what they claim in the name, we wouldn't
be here again.

Not sure how you found that previous message - even I hadn't
remembered that - it's been that long since I did any Java. Pity the
API hasn't improved much since then.

The problem with doing a read is that if the socket hasn't closed, you
end up blocking - it defeats the purpose of a 'test' to see if the
socket is closed. The problem with a write is that you end up writing
spurious data out to the socket. If the implementation can tell (when
you read or write) that the network has been lost, why can't it do so
to provide a proper test method - hasRemoteSocketClosed(), for
example?

Sorry that I brought the same question back.

 
Reply With Quote
 
Gordon Beaton
Guest
Posts: n/a
 
      10-03-2007
On Wed, 03 Oct 2007 12:08:38 -0000, JTeagle wrote:
> I guess that means the API is still badly named - if there were
> functions that actually did what they claim in the name, we wouldn't
> be here again.


The methods are poorly named, but they do work as documented.

> Not sure how you found that previous message - even I hadn't
> remembered that - it's been that long since I did any Java. Pity the
> API hasn't improved much since then.


I recognized the question, and the asker...

> The problem with doing a read is that if the socket hasn't closed, you
> end up blocking - it defeats the purpose of a 'test' to see if the
> socket is closed. The problem with a write is that you end up writing
> spurious data out to the socket. If the implementation can tell (when
> you read or write) that the network has been lost, why can't it do so
> to provide a proper test method - hasRemoteSocketClosed(), for
> example?


The socket interface provided by the OS works that way, and in that
respect there is no difference reading from any kind of descriptor,
regardless of the underlying structure (file, pipe, socket, character
device, etc). Not all of these interact with a remote that actively
closes the other end.

Note too that the remote may have closed while you have remaining
unread data, in which case you don't actually reach EOF until you've
read to the end of the data stream.

If you don't want to risk blocking, use a Selector. It provides the
necessary test, and will tell you when you can safely read *without*
blocking.

/gordon

--
 
Reply With Quote
 
JTeagle
Guest
Posts: n/a
 
      10-03-2007
> The methods are poorly named, but they do work as documented.

The docs are a bit lacking in that respect - they need to make the
distinction between "is currently connected" and "has connected at
some moment in the past" clear for new programmers, but I accept your
point.

> I recognized the question, and the asker...


I guess I should worry about that in my spare time! {:v)

> Note too that the remote may have closed while you have remaining
> unread data, in which case you don't actually reach EOF until you've
> read to the end of the data stream.


That's a very valid point. My initial problem was that available() on
the BufferedInputStream() returns 0 even when disconnected, which is
fairly logical but not helpful - this prompted me to look more
closely.

> If you don't want to risk blocking, use a Selector. It provides the
> necessary test, and will tell you when you can safely read *without*
> blocking.


Unfortunately that doesn't help - I'm assuming that's similar to
available(), which as mentioned above returns 0 for the disconnected
case (technically, there are 0 bytes you can read from a closed socket
without blocking), which doesn't hint that the connection has been
lost.

I did eventually realise, however, that I can use setSoTimeout() on
the socket to minimise blocking time.

Thanks for your thoughts.

 
Reply With Quote
 
Gordon Beaton
Guest
Posts: n/a
 
      10-03-2007
On Wed, 03 Oct 2007 12:39:29 -0000, JTeagle wrote:
>> If you don't want to risk blocking, use a Selector. It provides the
>> necessary test, and will tell you when you can safely read *without*
>> blocking.

>
> Unfortunately that doesn't help - I'm assuming that's similar to
> available(), which as mentioned above returns 0 for the disconnected
> case (technically, there are 0 bytes you can read from a closed
> socket without blocking), which doesn't hint that the connection has
> been lost.


A Selector can tell you when it's safe to read without blocking.
Actually reading is still necessary to tell you whether there was data
to read, or you're at EOF. A single Selector can be used to monitor
many existing and arriving connections simultaneously for connecting,
accepting, reading or writing, according to which SelectionKeys you've
registered interest in.

InputStream.available() tells you how much data has arrived and is
waiting to be read on a single InputStream. It can't tell the
difference between EOF and "currently no data", so reading might still
block.

/gordon

--
 
Reply With Quote
 
JTeagle
Guest
Posts: n/a
 
      10-03-2007
> A Selector can tell you when it's safe to read without blocking.
> Actually reading is still necessary to tell you whether there was data
> to read, or you're at EOF. A single Selector can be used to monitor
> many existing and arriving connections simultaneously for connecting,
> accepting, reading or writing, according to which SelectionKeys you've
> registered interest in.
>
> InputStream.available() tells you how much data has arrived and is
> waiting to be read on a single InputStream. It can't tell the
> difference between EOF and "currently no data", so reading might still
> block.


OK... I'll look into trying a Selector. Thanks.


 
Reply With Quote
 
Lew
Guest
Posts: n/a
 
      10-03-2007
JTeagle wrote:
>> The methods are poorly named, but they do work as documented.

>
> The docs are a bit lacking in that respect - they need to make the
> distinction between "is currently connected" and "has connected at
> some moment in the past" clear for new programmers, but I accept your
> point.


Blame the docs, blame the language, but by no means blame yourself.

Here's what the docs say:
> true if the socket successfuly connected to a server


We look at your code and see that the socket successfully connected to a
server. Working as advertised. Nothing there says the socket still has to be
connected. Yep, still working as advertised.

--
Lew
 
Reply With Quote
 
Thomas Schodt
Guest
Posts: n/a
 
      10-03-2007
Lew wrote:
> JTeagle wrote:
>>> The methods are poorly named, but they do work as documented.

>>
>> The docs are a bit lacking in that respect - they need to make the
>> distinction between "is currently connected" and "has connected at
>> some moment in the past" clear for new programmers, but I accept your
>> point.

>
> Blame the docs


Rather than blaming the docs, suggest an improvement.


bool Socket.isConnected()
Indicates if connect() has been called on this socket.
Initially this method returns false. After a connection is established,
this method method returns true. It will never change back to false for
any reason (like the connection failing).

bool Socket.isClosed()
Indicates if close() has been called on this socket.
Initially this method returns false. After Socket.close() is invoked
this method returns true. It will not return true for any other reason
(like the connection being closed by the remote end).
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: dropped connections Jack \(MVP-Networking\). Wireless Networking 0 12-16-2006 02:58 AM
For What It's Worth: Dropped Connections Alan Wireless Networking 3 11-02-2006 09:31 AM
Dropped Sockets? Joshua Jung Java 5 10-17-2006 09:04 PM
connections intermittently dropped Intel 2200BG / WRT54G V5 ZinG Wireless Networking 0 08-24-2006 01:02 AM
dropped connections Malc Computer Support 5 04-19-2004 05:57 PM



Advertisments