Detecting dropped socket connections

M

Mike Ruane-Torr

I have a server with an open socket, and I'm doing this:

if (sock.Available > 0)
{
sock.BeginReceive(...)
}
else
{
Thread.Sleep(...)
}

....in a loop, so that I only run BeginReceive() when there is data present
to be received.

Problem: How can I introduce an extra bit of code before the above, which
will tell me whether the client has closed the connection?

I've tried this:

if (!sock.Poll(1,SelectMode.SelectRead))
{
Abort();
}

....but it doesn't seem to work.


If I understand TCP/IP correctly, when the client closes the connection, a
FIN packet is sent. Therefore the information is present in the server
machine SOMEWHERE. So how do I get to it?
 
M

Mike Ruane-Torr

I have a server with an open socket, and I'm doing this:

if (sock.Available > 0)
{
sock.BeginReceive(...)
}
else
{
Thread.Sleep(...)
}

...in a loop, so that I only run BeginReceive() when there is data
present to be received.

Problem: How can I introduce an extra bit of code before the above,
which will tell me whether the client has closed the connection?

I've tried this:

if (!sock.Poll(1,SelectMode.SelectRead))
{
Abort();
}

...but it doesn't seem to work.


If I understand TCP/IP correctly, when the client closes the connection,
a FIN packet is sent. Therefore the information is present in the
server machine SOMEWHERE. So how do I get to it?

Here is how I have now had to do it (for those who may have been
interested in the solution):

private bool ConnectionStillOK(ConnectState cstate)
{
// If no connection was established, say all is OK
// .Connected is set to true after a call to EndAccept(), and to false in
the code below
if (!cstate.Connected)
return true;

// Now check the active connection...

bool closed = false;

try
{
closed = (cstate.socket.Poll(100, SelectMode.SelectRead) &&
(cstate.socket.Available == 0));
}
catch(SocketException se)
{
// If socket throws an exception, it's probably closed!
closed = true;
}
catch(Exception ex)
{
Console.WriteLine(ex.ToString());
closed = true;
}

if (closed)
{
// Client dropped connection - go back to listening mode
cstate.Connected = false;
DoWaitAccept(cstate);
return false;
}

return true;
}

The above method is called at the start of each async callback method, and
if it returns false, the async thread is terminated. The call to
DoWaitAccept() is used to start a new one.

Note that I have to check .Available as well as .Poll(), because if there
is a pending Receive, .SelectRead tells you that fact, rather than telling
you that the connection has been closed. It has what you might call a
'multiplexed purpose' :)

The above seems to work, but it's not very pretty. It would be nice to be
able to say:

if (cstate.socket.Dropped) ...

or something.
 

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

Top