How to use select() on sockets properly?

28,525

Read several times syscalls(2), select(2), select_tut(2), poll(2), errno(3) (BTW, you should prefer poll(2) to the obsolete select, which don't handle file descriptors bigger than __FD_SETSIZE, i.e. 1024 on my Linux/Debian/x86-64 system).

Then:

fd_set read_fds;
FD_ZERO(&read_fds);
int fdmax = listenfd;
FD_SET(listenfd, &read_fds);

should go inside the while(1) loop, before calling select. BTW, I recommend using poll instead of select

Read also about the C10k problem

Don't forget that select is changing its given fd_set-s (and usually wants them to be non-empty)...

Perhaps use strace(1) and gdb(1). If you compile with GCC, invoke it as gcc -Wall -Wextra -g to get more warnings and debug info. If you compile your C code with Clang, consider using the Clang Static Analyzer.

Read also Advanced Linux Programming (it is a free book that you could also read on paper, or download from several other places, e.g. this etc...)

Share:
28,525
Benjamin Lindqvist
Author by

Benjamin Lindqvist

Updated on January 13, 2021

Comments

  • Benjamin Lindqvist
    Benjamin Lindqvist over 3 years

    I'm trying to wrap my head around calling select on sockets and I can't understand what I'm doing wrong.

    setup_server_socket calls bind and listen and sets the socket to nonblocking mode.

    The following code blocks on the select call it seems, not moving forward to FD_ISSET. I tried connecting a client and it seems to succeed but select never returns anything.

    What's the proper way to do this?

    ...
    int listenfd = setup_server_socket( serverPort );
    
    if( -1 == listenfd )
        return 1;
    
    fd_set read_fds;
    FD_ZERO(&read_fds);
    int fdmax = listenfd;
    
    
    // loop forever
    while( 1 )
    {
        if (select(fdmax+1, &read_fds, NULL,NULL,NULL) == -1){
            perror("select");
            exit(4);
        }
    
        for (int i = 0; i<= fdmax; i++){
            printf("Testing: %d, %d\n", i, FD_ISSET(i,&read_fds));
    
        }return 0;
    ...
    
  • Benjamin Lindqvist
    Benjamin Lindqvist over 8 years
    Sorry, do you mean I should just refer to the man pages? I've done that to the best of my ability :(
  • Benjamin Lindqvist
    Benjamin Lindqvist over 8 years
    I mean I'm convinced those are nice links but I'm trying to walk before I run here... Also, broken link on Advanced Linux Programming
  • Basile Starynkevitch
    Basile Starynkevitch over 8 years
    It used to be a working link, and it is a book that you might read on paper.