Check if socket is connected or not
Solution 1
Don't check first and then send. It's wasted effort and won't work anyway -- the status can change between when you check and when you send. Just do what you want to do and handle the error if it fails.
To check status, use:
int error_code;
int error_code_size = sizeof(error_code);
getsockopt(socket_fd, SOL_SOCKET, SO_ERROR, &error_code, &error_code_size);
Solution 2
You need to enable non-blocking behavior, by setting O_NONBLOCK
using fcntl
. One easy but non-standard way to do a non-blocking read would be to use:
recv(sock, &buf, 1, MSG_PEEK | MSG_DONTWAIT);
Afterwards, you must check errno if it fails. It can fail with EAGAIN
or it can fail with EBADF
or ENOTCONN
etc.
Obviously, the simplest and cleanest way to deal with this would be to avoid "forgetting" if the socket is connected or not. You'll notice if the socket becomes disconnected once a recv
returns 0 or a send
returns EPIPE
.
Solution 3
Default use of TCP doesn't allow very timely detection of dead sockets (outside of normal closure) so I'll suggest that an "is_connected" function like this is largely useless for all practical purposes. Consider implementing an application-layer keep-alive and track if it's alive based on timely responses (or lack thereof).
edit: after posting i see BoBTFish's link, which is effectively the same thing.
Related videos on Youtube
opc0de
a life full of mistakes is better than a life full of regrets!
Updated on February 25, 2020Comments
-
opc0de about 4 years
I have an application which needs to send some data to a server at some time. The easy way would be to close the connection and then open it again when I want to send something. But I want to keep the connection open so when I want to send data, I first check the connection using this function:
bool is_connected(int sock) { unsigned char buf; int err = recv(sock,&buf,1,MSG_PEEK); return err == -1 ? false : true; }
The bad part is that this doesn't work. It hangs when there is no data to receive. What can I do? How can I check if the connection is still open?
-
BoBTFish over 11 years
-
-
user207421 over 11 yearsThis won't detect all connection failures. Only a send() can do that.
-
cnicutar over 11 years@EJP That's true in fact. I was just improving the solution of the op. What you are suggesting is the only bullet-proof solution, but it entails sending.
-
Rafael Baptista almost 11 yearsTrue... but sometimes it is useful to check if a socket is still connected. Setting it to non-block, and then reading with peek_msg is a good way to elicit an error code to check it the socket is still connected.
-
user207421 almost 11 years@RafaelBaptista Why? Using it will check. Testing first cannot work reliably, for the reason David gives above.
-
che over 9 years@EJP: I want to check client connection is alive so I don't waste resources in case it is not.
-
David Schwartz over 9 years@che Right, so check by using it. Then if it's not alive, you can stop wasting resources. The check itself is a waste of resources.
-
Seth about 7 yearsIf you are monitoring connections, say for a clustered app, it can be nice to periodically test connections to ensure that any failover can be performed even when connections are not in use. That would be a decent reason to test a connection.
-
David Schwartz about 7 years@seth Which you do by using it.
-
avernus over 2 yearsAlso, it is worth mentioning here that since we are using MSG_DONTWAIT flag, we do not need a separate fcntl() syscall to mark socket non-blocking via O_NONBLOCK: MSG_DONTWAIT makes socket non-blocking here.