How do I properly determine if my client is still connected to the server with C sockets? -
i have client connected server via c berkeley sockets. (try to) periodically check see if connection still valid calling recv() on socket msg_dontwait , msg_peek. however, i'm finding call returns eagain both when connection down in cases (e.g., after connection's interface shut down) , when there no data read. hence, there no way me distinguish whether connection still valid or not using method.
here's function:
/* return 1 if still connected, 0 otherwise */ int still_connected() { int nbytes_recvd = 0; char buf[2]; int err; nbytes_recvd = recv(fd,buf,sizeof(buf),msg_peek|msg_dontwait); err = errno; if ( nbytes_recvd == 0 ) { return 0; } else if ( nbytes_recvd < 0 ) { if ( (err == enotsock) || (err == enotconn) || (err == einval) || (err == econnrefused) || (err == ebadf) || (err == eopnotsupp) ) { return -1; } } /* nbytes_recvd > 0 or eagain or ewouldblock */ /* eagain if connection down because shut down interface */ return 1; }
how can accurately check whether connection still valid?
from point of view of 1 of 2 endpoints of tcp connection, there no difference between peer had disappeared , peer still present isn't sending data. can't distinguish these situations recv()
or other method.
the way detect if peer down, has reset, has disappeared, or has become unreachable, send data , see happens. there 2 options:
- enable tcp keepalives (
so_keepalive
). cause tcp send keepalive packet once in while , expectack
peer. if peer failsack
, can learn connection has been broken. - send actual application data (or application-level keepalive message) on schedule of choice. similarily, if peer fails respond data (or socket error after sending it), can learn connection has been broken.
Comments
Post a Comment