24

I want to set timeout value of function connect but I get this error: "Operation now in progress"

My code:

if ((he = gethostbyname(authdefhost)) == NULL) {
        snprintf(errbuf, CERRBUFSIZ - 1, "cannot resolve %s: %s\n", authdefhost, hstrerror(h_errno));
        return -1;
}

sin.sin_family = AF_INET;
memcpy(&sin.sin_addr, he->h_addr_list[0], sizeof(struct in_addr));       

if ((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        snprintf(errbuf, CERRBUFSIZ - 1, "cannot create client socket: %s\n", strerror(errno));
        return -1;
}

if ((fcntl(sd, F_SETFL, O_NONBLOCK) < 0))
    printf("error on setting socket flags.");

if (connect(sd, (void *) & sin, sizeof(sin)) == -1) {
        snprintf(errbuf, CERRBUFSIZ - 1, "cannot connect to server %s: %s\n", authdefhost, strerror(errno));
        close(sd);
        return -1;
}

FD_ZERO(&fdset);
FD_SET(sd, &fdset);
int rv;
if ((rv = select(sd + 1, NULL, &fdset, NULL, &tv)) == -1) {
    printf("error occurred on select function.");
    return -1;
}
else if (rv == 0) {
    printf("time out occurred.");
    return -1;
}
else {
    printf("connection established");
    return sd;
}
tshepang
  • 12,111
  • 21
  • 91
  • 136
iyasar
  • 1,241
  • 3
  • 13
  • 27

1 Answers1

42

When you call connect() on a non-blocking socket, you'll get EINPROGRESS instead of blocking waiting for the connection handshake to complete. Then, you have to select() for writability, and check the socket error to see if the connection has completed.

From Linux's connect() manpage:

EINPROGRESS

    The socket is nonblocking and the connection cannot be completed
    immediately.  It is possible to select(2) or poll(2) for completion by
    selecting the socket for writing.  After select(2) indicates
    writability, use getsockopt(2) to read the SO_ERROR option at level
    SOL_SOCKET to determine whether connect() completed successfully
    (SO_ERROR is zero) or unsuccessfully (SO_ERROR is one of the usual
    error codes listed here, explaining the reason for the failure).

ninjalj
  • 42,493
  • 9
  • 106
  • 148
  • 9
    In short: This is expected. You need to specifically check for `errno != EINPROGRESS` in your error-checking path for `connect()`. – caf Jun 02 '11 at 06:21
  • 3
    *Chapter 16 Nonblocking I/O* of **UNIX Network Programming (Volume 1)** describe this feature in detail and present a demo. – diabloneo Feb 23 '14 at 09:08