【问题标题】:select() on TCP socket works only the first loopTCP 套接字上的 select() 仅适用于第一个循环
【发布时间】:2015-12-12 01:51:52
【问题描述】:
void async_socket_rcv(int clientfd);

int main(int argc, char *argv[])
{
    //Configure buffer to output immediately
    setvbuf(stdout, 0, _IONBF, 0);

    //Mysql version
    printf("MySQL client version: %s\n", mysql_get_client_info());

    //Initialize the FDs for the sockets
    int socketfd, clientfd;

    //Initialize the list of FDs to monitor for input
    fd_set fd_monitor;
    int select_res;
    FD_ZERO(&fd_monitor);

    struct timeval select_timeout;
    select_timeout.tv_sec = 3;
    select_timeout.tv_usec = 0;


    //Initialize the thread id
    pthread_t thread;

    ...

    //Create the listen socket
    socketfd = create_inet_server_socket("0.0.0.0", "5671", LIBSOCKET_TCP, LIBSOCKET_IPv4, 0);

    if(socketfd < 0){
        printf("Error creating listen socket!");
        return -1;
    }else{
        printf("Listening...");
    }

    FD_SET(socketfd, &fd_monitor);
    //FD_SET(STDIN_FILENO, &fd_monitor);

    while(1)
    {
        select_res = select(sizeof(fd_monitor) * 8, &fd_monitor, NULL, NULL, &select_timeout);

        if(FD_ISSET(socketfd, &fd_monitor))
        {
            clientfd = accept_inet_stream_socket(socketfd,0,0,0,0,0,0);
            pthread_create(&thread, NULL, async_socket_rcv, clientfd);
        }
        select_timeout.tv_sec = 3;
        select_timeout.tv_usec = 0;
    }

    return 0;

}

大家好

我正在尝试使用select() 函数在客户端连接时调用函数,而不必阻塞accept() 函数。我需要能够在不中断服务器的情况下接受stdin

我上面的代码有效,但只有一次。当我单步执行代码时,如果我在 select()first 迭代中连接到服务器,我可以看到 select_res 是 1 only。之后,什么也没有发生。

我相信你们中的某个人会发现我的一些小错误,但对于我的一生,我看不出我做错了什么......

【问题讨论】:

    标签: c multithreading sockets select tcp


    【解决方案1】:

    select 改变传入的fd_sets,设置有活动的描述符并取消设置没有活动的描述符。由于您没有在循环中重置fd_monitor,因此您使用了更改后的fd_set

    FD_ZEROFD_SET 调用移动到循环的开头。

    【讨论】:

    • 谢谢先生!我一定读了 20 遍……“在返回时,每个输入集都被修改以指示准备好的描述子集。”对不起,它没能买到老瓜:)
    【解决方案2】:

    虽然上面的答案是 100% 正确的,但它实际上说明了为什么使用 select() 现在闻起来像 18 世纪。有一个很棒的 poll(),当你使用它时,可以让你摆脱所有的麻烦!

    【讨论】:

    • 我不记得在哪里,但我似乎记得读过那个民意调查比选择更昂贵。真的?该服务器将在树莓派上运行
    • 我从未听说过 poll 比 select 更昂贵。有一个怪癖, select 允许以纳秒(通过 timeval)指定超时,但 poll 只给你毫秒。但这不是延迟,这是最大等待超时。除此之外,我不知道选择优于民意调查的任何好处。
    • 您是否知道 poll over select 除了简单之外还有什么好处?
    • @MatthewGulart 据我所知,select 是一个较旧的接口,也不能扩展,这导致了poll 的创建。另见What are the differences between poll and select?
    • @MatthewGoulart,您的整个问题清楚地表明了其中之一:) 由于 poll() 将受影响的描述符与订阅的描述符分开返回,因此您不需要重新初始化它们,上面的问题根本不会发生!想象一下在调试上节省的时间。
    猜你喜欢
    • 2016-04-05
    • 2018-08-19
    • 2016-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-28
    • 2019-05-22
    • 2018-03-04
    相关资源
    最近更新 更多