0

我遇到了一个相当奇怪的问题:

我使用select()它来确定套接字是否变得可读。但是,每当客户端连接时,当我调用FD_ISSET()检查给定的套接字是否存在于fd_set.

/* [...] */

while( /* condition */ ){

    timeout.tv_sec = 0;
    timeout.tv_usec = SELECT_TIMEOUT;

    //this simply fills sockets with some file descriptors (passed in by clients - both parameters are passed by reference)
    maxfd = this->build_fd_set( clients, sockets );

    //wait until something relevant happens
    readableCount = select( maxfd + 1, &sockets, (fd_set*)NULL, (fd_set*)NULL, &timeout );

    if( readableCount > 0 ){
        //Some sockets have become readable

         printf( "\nreadable: %d, sockfd: %d, maxfd: %d\n",
                readableCount, this->sockfd, maxfd );

        //Check if listening socket has pending connections
        // SEGFAULT OCCURS HERE
        if( FD_ISSET( this->sockfd, &sockets ) ) {

            DBG printf( "new connection incoming" );

            this->handle_new_connection( clients );

            /* [...] */
        }else {
            // Data is pending on some socket
            /* [...] */
        }
    }else if( readableCount < 0 ) {
        //An error occured
        /* [...] */
        return;
    }else {
        // select has timed out
        /* [...] */
    }

}

编辑: 是的,抱歉信息稀少:我已经更新了代码。

this->sock_fd设置为监听套接字的描述符,使用创建this->sockfd = socket( AF_UNIX, SOCK_STREAM, 0 );然后通过listen( this->sockfd, ACCEPT_BACKLOG ).

build_fd_set:

int SvcServer::build_fd_set( const vector<int>& clients, fd_set& sockets ) {

    //build up the socket set
    FD_ZERO( &sockets );
    FD_SET( this->sockfd, &sockets ); //listening socket is always part of the set

    int maxfd = this->sockfd;
    //Add all currently connected sockets to the list
    for( vector<int>::const_iterator it = clients.begin() ; it != clients.end() ; ++it )     {
        FD_SET( *it, &sockets );
        maxfd = max( maxfd, *it );
    }

    return maxfd;
}

它实际上是什么并不重要clients,它只是空的并且意味着一旦客户端连接就被填充,这不会发生,因为整个事情在第一个传入连接上出现段错误。

此外,这里有一些示例输出:

readable: 1, sockfd: 3, maxfd: 3
Segmentation fault

我可以在这里得出的结论是:

  • 调用select()工程,readable设置正确
  • 也是有效的描述符sockfdmaxfd

恐怕我无法为您提供任何调试信息(例如 gdb),因为我正在交叉编译并且 gdb 在我正在编译的平台上不可用。

4

1 回答 1

0

没关系,我想通了。*愚蠢的我*

事实证明,段错误实际上从未发生在可疑位置,段错误之前的最后一个 printf 从未显示,因为它没有刷新标准输出。实际的段错误发生得稍晚一点,并且(当然)是我的错误。

不过谢谢

于 2012-08-28T11:34:10.477 回答