I am trying to write a TCP server with Visual C++ 5.0.
Everything is OK, ... EXCEPT that :
I don't detect wthen the client is killed by a reset.
So, I added this
sock_cnx = accept( ... );
int optval = TRUE ;
if (SOCKET_ERROR == setsockopt ( sock_cnx, SOL_SOCKET, SO_KEEPALIVE,
(char *)&optval, sizeof(optval) ) )
{
AfxMessageBox("setsockopt SO_KEEPALIVE error");
return FALSE;
}
nRead = recv( sock_cnx, (char far *)msgp, 8, 0 ) ;
But, I waited one full night, and the server didn't detect anything.
Do you have any suggestion, or do you know how to parameter the
keepalive mechanism to check the connexion every 10 mn for instance ?
Thanks for any answer.
>I don't detect wthen the client is killed by a reset.
[snip]
>int optval = TRUE ;
>if (SOCKET_ERROR == setsockopt ( sock_cnx, SOL_SOCKET, SO_KEEPALIVE,
> (char *)&optval, sizeof(optval) ) )
Read the Winsock 2 spec. It clearly states that stacks are not
required to implement SO_KEEPALIVE. History teaches us that Microsoft
implements almost none of the optional Winsock features. Microsoft is
also not required to return an error from this function if they don't
support the option. They can just quietly ignore your request. It's
also possible that your server machine's stack does support this
option, but the client machine's stack does not. The initial TCP
negotiation should uncover this; if so, the server won't send
keepalive packets.
A better idea is to implement keepalives at the protocol level, if you
control the protocol. Just require that either the client or the
server periodically send a "hey, are you there?" packet, and wait some
short but adequate amount of time for the remote host to answer. This
time will probably be between 1 second and 1 minute. You should
choose a time that is at least twice the minimum round-trip time you
expect to ever see. The host not sending the keepalive packets should
also keep a timer, which is reset every time they are asked if they
are still alive. That way, both hosts eventually clean themselves up
if the other goes away.
>nRead = recv( sock_cnx, (char far *)msgp, 8, 0 ) ;
If you are truly getting a RST bit from the client, this call will
eventually return 0 or SOCKET_ERROR, and WSAGetLastError() will return
WSAECONNRESET.
If the client is just unplugged from the network, or if its stack is
not well-implemented, you may not actually get that RST bit. Only a
network sniffer can tell you for sure, though. See my FAQ, linked
below, for links to a number of good sniffers, as well as plenty of
other Winsock info.
Good luck,
= Warren -- Maintainer of the Winsock Programmer's FAQ:
= http://www.cyberport.com/~tangent/programming/winsock/
=
= Remove the SPAMCATCHER to email. -- Finger me!