LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (http://www.linuxquestions.org/questions/programming-9/)
-   -   connect() timeout change (http://www.linuxquestions.org/questions/programming-9/connect-timeout-change-145433/)

nodger 02-12-2004 06:02 PM

connect() timeout change
 
Can the connect() function have its timeout changed? on redhat its about 3 minutes and I want to change that to about 10 seconds.

infamous41md 02-12-2004 07:34 PM

the solution is using nonblocking i/o and select. here is the function i use:
Code:

//do a nonblocking connect
//  return -1 on a system call error, 0 on success
//  sa - host to connect to, filled by caller
//  sock - the socket to connect
//  timeout - how long to wait to connect
inline int
conn_nonb(struct sockaddr_in sa, int sock, int timeout)

    int flags = 0, error = 0, ret = 0;
    fd_set  rset, wset;
    socklen_t  len = sizeof(error);
    struct timeval  ts;
   
    ts.tv_sec = timeout;
   
    //clear out descriptor sets for select
    //add socket to the descriptor sets
    FD_ZERO(&rset);
    FD_SET(sock, &rset);
    wset = rset;    //structure assignment ok
   
    //set socket nonblocking flag
    if( (flags = fcntl(sock, F_GETFL, 0)) < 0)
        return -1;
   
    if(fcntl(sock, F_SETFL, flags | O_NONBLOCK) < 0)
        return -1;
   
    //initiate non-blocking connect
    if( (ret = connect(sock, (struct sockaddr *)&sa, 16)) < 0 )
        if (errno != EINPROGRESS)
            return -1;

    if(ret == 0)    //then connect succeeded right away
        goto done;
   
    //we are waiting for connect to complete now
    if( (ret = select(sock + 1, &rset, &wset, NULL, (timeout) ? &ts : NULL)) < 0)
        return -1;
    if(ret == 0){  //we had a timeout
        errno = ETIMEDOUT;
        return -1;
    }

    //we had a positivite return so a descriptor is ready
    if (FD_ISSET(sock, &rset) || FD_ISSET(sock, &wset)){
        if(getsockopt(sock, SOL_SOCKET, SO_ERROR, &error, &len) < 0)
            return -1;
    }else
        return -1;

    if(error){  //check if we had a socket error
        errno = error;
        return -1;
    }

done:
    //put socket back in blocking mode
    if(fcntl(sock, F_SETFL, flags) < 0)
        return -1;

    return 0;
}

HTH

nodger 02-12-2004 07:49 PM

ill give that a try, Thanks.

nodger 02-12-2004 08:19 PM

im afraid that didnt work ,infamous41md. it compiled alright, but given a 10 second timeout it still waited < 1 second and didnt connect to a valid host im not sure whats wrong

infamous41md 02-12-2004 08:55 PM

well i use it everyday, so im pretty sure it works :D could i see how u used it? u say it returned right away? you should be checking the errror return for -1 and calling perror() if it is.

schmack 02-12-2004 11:09 PM

connect() will return an immediate failure if it is able to determine that it can't establish the connection. This is often the case when you are trying to connect to a socket on the same machine.

The function given above will wait _up to_ timeout seconds. In theory, you could change it to retry every now and then until your timeout value is exhausted.

JurajPsycho 09-04-2004 08:20 PM

:(
 
well, I did try your code infamous41md , and it compiles OK, but when I use it, the timeout comes after 333 sec, while when I used usuall connect, timeout came after 189 sec....
Code:


    s_in.sin_family = PF_INET;
    s_in.sin_port = htons(21);
    sprintf(ip,"147.232.153.5");  //just for testing purposes, it's NOT my IP
    s_in.sin_addr.s_addr=inet_addr(ip);
    con = conn_nonb(s_in,s,10);
    if(con==-1)
    {
            printf("%d - IP = %s - Connection failed\n",getpid(),ip);
            perror();
    }

What am I doing wrong? Thx for help.
J.

JurajPsycho 09-04-2004 08:22 PM

oh, I forgot:
Code:

    int s;
    s = socket(PF_INET, SOCK_STREAM, 0);
    if(s<0)
    {
        perror("socket");
    }


itsme86 09-04-2004 08:45 PM

I believe you can use setsockopt() with the SO_RCVTIMEO or SO_SNDTIMEO options. I'm not sure if those settings have any effect on connect(), but it should give you a place to look ;)

JurajPsycho 09-11-2004 06:35 PM

well, I want to do that under Linux...

infamous41md 09-11-2004 07:26 PM

add this:
ts.tv_usec = 0;

right below
ts.tv_sec = timeout

JurajPsycho 09-13-2004 07:01 PM

thx
 
:D thx, now it works fine
J.


All times are GMT -5. The time now is 07:49 AM.