Check if socket is connected or not

102,570

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.

Share:
102,570

Related videos on Youtube

opc0de
Author by

opc0de

a life full of mistakes is better than a life full of regrets!

Updated on February 25, 2020

Comments

  • opc0de
    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?

  • user207421
    user207421 over 11 years
    This won't detect all connection failures. Only a send() can do that.
  • cnicutar
    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
    Rafael Baptista almost 11 years
    True... 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
    user207421 almost 11 years
    @RafaelBaptista Why? Using it will check. Testing first cannot work reliably, for the reason David gives above.
  • che
    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
    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
    Seth about 7 years
    If 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
    David Schwartz about 7 years
    @seth Which you do by using it.
  • avernus
    avernus over 2 years
    Also, 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.