LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   nonblocking select() + socket() (https://www.linuxquestions.org/questions/programming-9/nonblocking-select-socket-757604/)

phsythax 09-24-2009 06:24 PM

nonblocking select() + socket()
 
I would like to use the following example to timeout a connection attempt, made by a TCP socket:

Code:

/*
** select.c -- a select() demo
*/

#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

#define STDIN 0  // file descriptor for standard input

int main(void){
    struct timeval tv;
    fd_set readfds;

    tv.tv_sec = 2;
    tv.tv_usec = 500000;

    FD_ZERO(&readfds);
    FD_SET(STDIN, &readfds);

    // don't care about writefds and exceptfds:
    select(STDIN+1, &readfds, NULL, NULL, &tv);

    if (FD_ISSET(STDIN, &readfds))
        printf("A key was pressed!\n");
    else
        printf("Timed out.\n");

    return 0;
}

my socket function looks like this:

Code:

int checkprt(int port, char *ip){
  int test = 0;
  int sockfd;
  struct sockaddr_in servaddr;
  sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if(sockfd < 0) {
      printf("error. cannot creat socket\n");
      return ERROR;
    }
  servaddr.sin_family = AF_INET;
  servaddr.sin_addr.s_addr = inet_addr(ip);
  servaddr.sin_port = htons(port);
  test = connect(sockfd, (struct sockaddr_in *)&servaddr, sizeof(servaddr));
  if(test == -1){
    close(sockfd);
    return CLOSED;
  }
  close(sockfd);
  return OPEN;
}

As you probably have guessed I am in the middle of learning socket programming. Any help here on how to use the select() example to timeout a connect attempt would be appreciated.

orgcandman 09-24-2009 11:37 PM

You can't do it the way you're thinking.

There's a non-portable (read LINUX) way of doing something similar:

The socket option TCP_SYNCNT. It's defaulted to 5, which corresponds to 180 seconds. However, you could easily make this number.. say.. 2. And your connect will time out much more quickly.

chrism01 09-24-2009 11:55 PM

This may be worth a read http://www.beej.us/guide/bgnet/

phsythax 09-25-2009 01:55 AM

Quote:

Originally Posted by orgcandman (Post 3696370)
You can't do it the way you're thinking.

There's a non-portable (read LINUX) way of doing something similar:

The socket option TCP_SYNCNT. It's defaulted to 5, which corresponds to 180 seconds. However, you could easily make this number.. say.. 2. And your connect will time out much more quickly.

I've found out that on my system (gentoo updated), its defaulted to 7.
What would the best method of altering this value be without doing it permanently?

orgcandman 09-25-2009 08:44 AM

man setsockopt

Just set the TCP_SYNCNT socket option. This has the advantage of working the way you expect on any linux machine (but other systems probably will fail).

ta0kira 09-25-2009 07:04 PM

Quote:

Originally Posted by orgcandman (Post 3696772)
man setsockopt

Just set the TCP_SYNCNT socket option. This has the advantage of working the way you expect on any linux machine (but other systems probably will fail).

This can probably be averted with #ifdef TCP_SYNCNT /*...*/ #endif around the corresponding code. Those without Linux will just be out of luck!
Kevin Barry

jork 06-25-2010 12:33 AM

Much more easy and standard way for this. Put the socket in non-blocking mode and call the connect after that. Connect will return immediately with EINPROGRESS. Now you call the select again for this socket, with the desired timeout. Now the select will wake up once the socket gets connected or it will timeout.

This is the standard async socket programming way and I hope this is the way you wanted to follow.

-jork


All times are GMT -5. The time now is 02:19 AM.