tags:

views:

198

answers:

2

take for instance the following code snippet, the creation of the socket, listening and acceptance of a new socket works fine. The non-blocking mode is also working, however the pselect (or even replacing with select) is not recognizing any IO requests ready on the FDset. so the return value is always 0 (timed out).

I was wondering if I need to set anything else further before going into pselect() so that it recognizes the IO activity.

.....
 // Create the socket
        *m_pSockFD = socket(AF_INET, SOCK_STREAM, 0);
        if( *this->m_pSockFD == -1 ){
            throw ....
        }

        // Set the socket address information
        m_pSockAddr->sin_family = AF_INET;
        m_pSockAddr->sin_port =  htons( 6001 );
        m_pSockAddr->sin_addr.s_addr = INADDR_ANY;

        if( bind(*m_pSockFD, (struct sockaddr *) m_pSockAddr, sizeof(*m_pSockAddr) ) != 0 ){
                .....
        }

        // Listen on this socket using a block queue of 5 - default Block Size
        if( listen( *m_pSockFD, 5) != 0 )
                ........


        // change function control to non blocking file descritor for I/O operations
        long fcntlArg;
        if( (fcntlArg = fcntl( *m_pSockFD, F_GETFL, NULL ) ) < 0 ){
               ...........
        }

        fcntlArg |= O_NONBLOCK;
        if( fcntl( *m_pSockFD, F_SETFL, fcntlArg ) <0 ){
              ...........
        }

        //.........

        int newFD = -1;
        socklen_t salen = sizeof(*m_pSockAddr);


        // loop selecting for a I/O operation ready on the file descriptor then go into accept mode
        struct timespec timeOut;
        timeOut.tv_sec = 1;
        timeOut.tv_nsec = 0;

        fd_set fdset;
        FD_SET( *this->m_pSockFD, &fdset );

        while( !m_bShutDownFinished ){

            // TODO pselect is not registering the activity on the socket
            if( pselect( *this->m_pSockFD, &fdset, NULL , NULL , &timeOut,  NULL ) > 0 ){
                cout << "hello client" << endl;
                break;
            }

            // re-initialize the time struct
            timeOut.tv_sec = 1;
            timeOut.tv_nsec = 0;
        }


        // application is shutting down do not try to accept a new socket
        if( m_bShutDownFinished ) return -1;

        newFD = accept(*m_pSockFD, (struct sockaddr *) m_pSockAddr, &salen);
        if( newFD > -1 ){
            ................
        }

        return newFD;
A: 

First argument of pselect should be *this->m_pSockFD + 1, shouldn't it?

Ryan Graham
Thanks, I did change that but unfortunately the return value from pselect is always 0. meaning the timeout was reached. I played with the value making it larger and smaller but no difference was found.
Signal9
+2  A: 

You have to re-initialize the fdset parameters before each call to select().

Each of readfds, writefds, and exceptfds is an input/output parameters. On return, they have been modified to have ones only for the fds that, respectively, are readable, writeable, or have an exceptional condition of some sort.

for (;;) {
    fd_set rfds;
    FD_ZERO(&rfds);
    FD_SET(&rfds, sock);
    /* code to set up timeout omitted */
    n = select(sock + 1, &rfds, 0, 0, &timeout);
    /* check n, and if sock is present in rfds */
}

The way you've written the code, you'll only detect an incoming connection if it arrives during the very first call to pselect(). Also, given that you're not using the sigmask argument of pselect(), you might as well just call select().

Dale Hagglund