-   Programming (
-   -   connect() with timeout (

nodger 10-21-2006 02:19 PM

connect() with timeout
Im trying to put a timeout on a connect call, and it works fine if I try to contact on say port 81, but for some reason if I try to connect to an unopen port on or my router's IP, it succesds all the time.

The method I used is : first I set the socket to non-blocking, tried connecting with connect(), not bothering to check the return value because its always -1, then using select() to check if the socket could be written to.

heres my code:

bool TcpClient::Connect(        const char* host,
                                const unsigned short port,
                                const unsigned short timeOut)
        // get the IP address
        struct hostent* h=gethostbyname(host);
        if (!h) return false;

        // create socket and set it to non-blocking

        // set up address structure

        // attempt to connect
        connect(sockfd,(struct sockaddr*)&remoteAddr,sizeof(struct sockaddr));

        // set up file descriptor set

        // set up timeval struct

        // monitor the socket
        if (select(sockfd+1,NULL,&fds,NULL,&tv)<=0)
                return false;

        return true;

Thanks for any help.

nodger 10-21-2006 02:34 PM

hmm.. i think Ive found a solution. if I just call send(sockfd,0,0,0) and I get a return value of 0, then its connected.

_john_i_ 10-21-2006 07:58 PM

A method I have used before is to create a signal handler function for SIGALRM, and before calling connect call alarm(timeout); and after the connect call alarm(0);

When the alarm goes off and your signal handler returns, connect will exit, and you just turn off the alarm with the alarm(0).

paulsm4 10-21-2006 10:14 PM

Hi -

There are several ways for a sockets client to "connect() with timeout":


1. Timeout with "select()"
I really wouldn't recommend this one for your situation. At best, if I was using UDP "sendto()" and "recvfrom ()", I might use "select()" to verify that the socket became writeable or readable within a specific time before I used it.

2. Sigalarm
_john_i_'s suggestion is a good one. For example:

  /* Adapted from W. Richard Stevens, "Unix Network Programming" */
  oldsigfunc = signam (SIGALRM, mynewfunc);
  if (alarm (nsec) != 0) {
    printf ("WARNING: Alarm already set!\n");

  /* Try to connect */
  iretval = connect (sockfd, &sa, slen);
  if (iretval  < 0) {
    close (sockfd);
    if (errno == EINTR)
      printf ("WARNING: timeout occurred...\n");

  /* Clear Alarm/reset original SIGALRM handler */
  alarm (0);
  signal (SIGALRM, oldsigfunc);

  /* ... continue or not, based on "iretval" ... */


3. "setsockopt (SO_RCVTIMEO)"
This is the best option of all ... if your stack supports it.

My version of Stevens (the 2nd Edition, 1998) states that you CANNOT use "setsockopt(SO_RCVTIMEO)" to set a connect timeout. This is no longer true on most OS's, and it has been available on Linux since kernel 2.3.41.
<= If at all possible, I'd encourage you to consider SO_RECVTIMEO
'Hope that helps .. PSM

Here are some links:

All times are GMT -5. The time now is 09:05 AM.