【问题标题】:select() system call will not unblockselect() 系统调用不会解除阻塞
【发布时间】:2016-04-01 18:15:20
【问题描述】:

我无法让 select() 系统调用解除阻塞。我正在尝试从一组 3 个套接字多路复用数据输入。我在称为 sock[] 的整数数组中为每个接口创建一个套接字。如果我取消注释第一个块,我可以毫无问题地在每个套接字上接收数据。使用 cmets,我永远不会通过对 select() 的调用。你能看到我在 select() 设置和调用方面做错了什么吗?

//This block will receive data from sock[0], sock[1], and sock[2] when left uncommented
   /*n = recvfrom(sock[2], buf, 1500,0,(struct sockaddr*)&recvaddr, &recvaddrlen);
    printf("\nrecieved\n");
    print_buf(buf);*/

    fd_set sockets;
    FD_ZERO(&sockets);
    for(i=0; i<3; i++){
        FD_SET(sock[i], &sockets);
    }


    select(3, &sockets, NULL, NULL, NULL);
    printf("\nSocket selected\n");
    for(i=0; i<3; i++){
        //Check for connected sockets
        if(FD_ISSET(i, &sockets)){
            printf("\nSocket %d", i);
            n = recvfrom(sock[i], buf, 1500,0,(struct sockaddr*)&recvaddr, &recvaddrlen);
        }
    }

【问题讨论】:

  • 我强烈建议切换到poll 而不是select。这确实是一个糟糕的功能。
  • @SergeyA - 不幸的是,我认为select 仍然是最便携的,所以在某些情况下使用它可能是合理的。也就是说,poll 是我的简单用法。 epoll 更强大,但更难使用且仅限 Linux。
  • @BrianMcFarland,我不知道有任何现代系统有select,但没有poll。你有具体的例子吗? epoll 当然是特定于 Linux 的。
  • 唯一立即想到的是轻量级/备用 TCP/IP 堆栈,例如lwIP 和类似的商业解决方案。虽然有点谷歌搜索,但听起来所有主要操作系统在大约 10 年前都支持它(Win Vista 和 OSX 10.4),这意味着运行仍然受支持的操作系统版本的系统很少(如果有的话?)问题。

标签: c sockets networking


【解决方案1】:

您为 nfds 参数传递了错误的值。

http://linux.die.net/man/2/select

"nfds 是三组中编号最高的文件描述符,加 1。"

你想要的是类似的东西

int maxsock =0;
for(i=0; i<3; i++){
    FD_SET(sock[i], &sockets);
    if (sock[i] > maxsock) maxsock = sock[i]
}


select(maxsock+1, &sockets, NULL, NULL, NULL);

【讨论】:

    猜你喜欢
    • 2020-11-11
    • 1970-01-01
    • 2013-04-26
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 2017-10-03
    • 2017-04-14
    • 2013-09-08
    相关资源
    最近更新 更多