【问题标题】:select and some clients选择和一些客户
【发布时间】:2011-05-03 06:21:27
【问题描述】:

我很困惑我有一个通过 select() 的服务器。我可以接受一些客户。 但我只是在最后连接服务器时才从客户端读取信息。 例如:A、B、C 的客户端依次连接服务器。服务器只打印 来自 C 的数据。

当我 gdb 时,它一直阻塞在 select() 中。 你能告诉我为什么吗?谢谢。 主要代码是:


谢谢你,我已经更新了问题,我把代码改成了http://www.gnu.org/s/hello/manual/libc/Server-Example.html

但问题还是来了。 我仍然只从最后一个获取数据。我无法获取数据 从前一个。

主要代码是:

int read_from_client(int 文件)
{ 字符缓冲区[MAXMSG];
int nbytes;

    nbytes = read( filedes, buffer, MAXMSG );

    if ( nbytes < 0 )
    {
            /* Read error */
            perror( "read" );
            exit( EXIT_FAILURE );
    }
    else if ( nbytes == 0 )
    /* End-of-file. */
            return -1;
    else
    {
            /* Data read. */
            fprintf( stderr, "Server: got message: '%s'\n", buffer );
            return 0;
    }

}

int ts_server_poll( struct tcp_server *server, struct timeval *timeout ) {
无符号整数 i;
int nready, sockfd, k, j;

    <br>//reset the fd set
    _server_set_fd( server );

    printf( "maxfd is %d\n", maxfd );
    FD_SET( server->fd, server->fd_set );

    while ( 1 )
    {
            /* Block until input arrives on one or more active sockets. */
            server->fd_readset = server->fd_set;

            if ( select( FD_SETSIZE, server->fd_readset, NULL, NULL, NULL ) < 0 )
            {
                    perror ( "select" );
                    exit( EXIT_FAILURE );
            }



            /* Service all the sockets with input pending */
            for ( i = 0; i < FD_SETSIZE; ++i )
                    if ( FD_ISSET( i, server->fd_readset ) )
                    {
                            if ( i == server->fd )
                            {
                                    /* Connection request on original socket. */
                                    int new;
                                    new = (int)accept( server->fd, 0, 0 );

                                    if ( new < 0 )
                                    {
                                            perror( "accept" );
                                            exit( EXIT_FAILURE );
                                    }

                                    FD_SET( new, server->fd_set );
                            }
                            else
                            {
                                    /* Data arriving on an already-connected socket. */
                                    if ( read_from_client( i ) < 0 )
                                    {
                                            close( i );
                                            FD_CLR( i, server->fd_set );
                                    }

【问题讨论】:

  • 谁教你使用这种缩进的?您的代码很难阅读。如果您希望社区帮助您,请让社区更轻松。
  • 我已经编辑了那里的内容以使其可读,但我不确定我能猜出一个问题。
  • 这里没有接受新连接或将它们添加到读取集中的代码。
  • 一般来说,在您的服务器中的select 之后,您希望遍历所有客户端的文件描述符。
  • @Brian Roach 我更新了问题,但我看起来并不漂亮,

标签: c linux networking


【解决方案1】:

您的代码缺少几件事……接受新连接,并遍历读取集中的所有描述符。

这是一个如何在服务器中使用 select 的完整示例:

http://www.gnu.org/s/hello/manual/libc/Server-Example.html

【讨论】:

【解决方案2】:

您应该循环执行此操作。我的意思是,检查 FD_ISSET 从 0 到 maxfd + 1,然后是所有爵士乐。

for(sockfd = 0; sockfd < maxfd + 1; sockfd++) {
    if(FD_ISSET(sockfd, server->fd_readset)) {
        /* there is an event on sockfd */
    }
}

我有一段时间没用过select,但你应该没问题。此外,您可能希望跳过描述符 0、1、2,但这会很丑陋。

【讨论】:

  • 谢谢你,我已经更新了它,但它仍然无法工作。我是否使用非阻塞功能?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-23
  • 2011-05-02
  • 2015-04-06
  • 1970-01-01
  • 2021-02-23
  • 2013-02-16
相关资源
最近更新 更多