Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I have a problem with this code:

FD_ZERO(&cset);
FD_SET(s, &cset);

tval.tv_sec = TIMEOUT; 
tval.tv_usec = 0; 

n = select(FD_SETSIZE, &cset, NULL, NULL, &tval);

if (n==-1) {
    printf(" select() failed \n");
    exit(-1);
}
if (n>0) {
    check_control = connect(s,(struct sockaddr*)
    &indirizzo_remoto,sizeof(indirizzo_remoto));

    if (check_control == -1) {
        printf("Errore connect()\n");
    }

}else{
    printf("Timeout. I'll shutdown the client");
    exit(-1);
}

I want insert a timeout for the connect but it doesn't work:

I use the right IP address and port number of the Server but the connection goes to timeout.

Thank you very much for the help.

share|improve this question
    
Yes, with telnet it works! –  user2467899 Jun 12 '13 at 17:15
    
Is this wrong? Because I want that is the Server is down when the client try to connect with it if it takes 30 seconds the client stop and close the socket –  user2467899 Jun 12 '13 at 17:20
    
(sorry for the English) ....: I want that if the Server / when the client try to connect to it –  user2467899 Jun 12 '13 at 17:22
1  
select() is not going to connect() the socket for you. If you want to connect() with a timeout you need to 1. Set the socket to non-blocking mode. 2. call connect() 3. call select(). Have you done step 1 and step 2 ? We only see the code for step 3. –  nos Jun 12 '13 at 17:22
    
I thought that only this piece of code realized the desired result. How can I accomplish steps 1 and 2? –  user2467899 Jun 12 '13 at 17:27

1 Answer 1

up vote 2 down vote accepted

You are using select() to check if a given socket is in a readable state before calling connect() on that same socket. That will never work. An unconnected TCP socket will never be in a readable state, and cannot be used with select() until connect() has been called on it first.

The only way to implement a timeout for a connect() call is to put the socket into non-blocking mode first (sockets are blocking by default), then call connect() (which returns an EINPROGRESS error if the socket is attempting to connect), and then use select() to wait for the socket to enter a writable state, indicating the connection was successful, or an error state, indicating the connection failed.

Try this:

fcntl(s, F_SETFL, O_NONBLOCK);

Or:

flags = 1;
ioctl(s, FIOBIO, &flags);

Depending on your platform.

Then:

check_control = connect(s, (struct sockaddr*) &indirizzo_remoto, sizeof(indirizzo_remoto));
if (check_control == -1)
{
    if (errno != EINPROGRESS)
    {
        printf("Errore connect()\n");
        exit(-1);
    }

    FD_ZERO(&wset);
    FD_SET(s, &wset);

    FD_ZERO(&eset);
    FD_SET(s, &eset);

    tval.tv_sec = TIMEOUT; 
    tval.tv_usec = 0; 

    n = select(s+1, NULL, &wset, &eset, &tval);
    if (n == -1)
    {
        printf(" select() failed \n");
        exit(-1);
    }

    if (n == 0)
    {
        printf("Timeout. I'll shutdown the client");
        exit(-1);
    }

    if (FD_ISSET(s, &eset))
    {
        printf("Cannot connect. I'll shutdown the client");
        exit(-1);
    }

    int err = -1;
    getsockopt(s, SOL_SOCKET, SO_ERROR, &err, sizeof(err));
    if (err != 0)
    {
        printf("Cannot connect. I'll shutdown the client");
        exit(-1);
    }
}

// connected...
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.