tags:

views:

1408

answers:

3

How can I check if a client disconnected through Winsock in C++?

+6  A: 

Beej's Network Programming Guide

if you call recv in blocking mode and it returns with 0 bytes read, the socket has disconnected, else it wait for bytes to be received.

Look in this FAQ 2.12

example from select on this page.

int nRet;

if(( nRet = select( 0, &fdread, NULL, NULL, NULL )) == SOCKET_ERROR )
{
 // Error condition
 // Check WSAGetLastError
}

if( nRet > 0 )
{
 // select() will return value 1 because i m using only one socket
 // At this point, it should be checked whether the
 // socket is part of a set.

 if( FD_ISSET( s, &fdread ))
 {
  // A read event has occurred on socket s
 }
}
sfossen
Isn't "Beej's Network Programming Guide" for Linux sockets?
AntonioCS
BSD sockets, and they are used everywhere.
Brian R. Bondy
+1  A: 

You can only tell if a TCP socket is 'disconnected' by attempting to send data. This is because the design of the protocol is such that it's supposed to allow for temporary outages between peers. So, if you connect from A via R1 via R2 via R3 to B and send data for a while and then stop sending you could unplug R2->R3 (for example) and neither A nor B would notice (or care). If you then plugged R2->R4 and R4->R3 and then tried to send data between A and B then things would 'just work' and you'd never know. If, however, you tried to send data when R2->R3 was disconnected then you'd (eventually, after all the TCP level retries) get an error back.

Now, some operating systems may be able to alert you to the fact that your local network adapter isn't currently connected and you could use that to say "I'm no longer connected to my peers" but I wouldn't advise it.

If having your peers know when connections are 'broken' is important then either use an application level 'ping' message to occasionally send data between the peers or use TCP keep-alive. Personally I'd go for the ping messages...

Edit: Of course all that is assuming that you want to know if you can still send data on a connection, after all, you're TOLD when the client is no longer sending because your reads will return 0 bytes and you KNOW when it disconnects its send side because your writes will fail; you also KNOW when you shutdown either the send or recv side of your own end of the connection...

I guess I should have stuck with initial gut reaction response of "define disconnected" ;)

Len Holgate
+2  A: 

There are a few different ways, but the most common is to check the result of a send or receive command:

 nReadBytes = recv(sd, ReadBuffer, BufferSize, 0);
 if (nReadBytes == SOCKET_ERROR)
 {
     //error
 }
 nSendBytes = send(sd, WriteBuffer, BufferSize, 0);
 if (nSendBytes == SOCKET_ERROR)
 {
     //error
 }

More examples (complete with error checking, both client and server) here:

http://tangentsoft.net/wskfaq/examples/basics/

Adam Davis