V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
vcfghtyjc
V2EX  ›  问与答

[求助] c++ 使用 "select" 不能监测到可读的 socket

  •  
  •   vcfghtyjc · 2021-03-23 13:33:31 +08:00 · 1014 次点击
    这是一个创建于 1342 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我在使用 c++ 的 select 实现服务器同时连接多个客户端,出现的情况是有的时候 FD_ISSET 可以监测处哪些 socket 可读,有的时候虽然所有 socket 用 FD_ISSET 都返回 0,但是客户端是发送了数据过来的。如果读取 socket,是可以读到客户端发的内容,但是 FD_ISSETselect 函数并不会标记该 socket 为可读。

    当我用多个客户端和服务器向服务器发信息的时候,一般是前几次所有 socket 都可以正常检测出可读的 socket,逐渐的,可检测出的可读 socket 越来越少,直到所有 socket 都被认为是不可读。

    不知道有没有哪位大佬知道原因。我现在用 macOS 写代码,调用的并不是 FD_ISSET 而是 __DARWIN_FD_ISSET,不知道和这个有没有关系。

    顺便问一下,FD_ISSET 的值是什么时候更新的?我在读 socket 前后各返回了 FD_ISSET,返回的是相同的值(该值表示 socket 可读)。所以是在执行 select 时候更新的吗?

    9 条回复    2021-03-25 00:09:38 +08:00
    togou
        1
    togou  
       2021-03-23 18:37:20 +08:00
    用 epoll 吧 select 虽然每个系统都有 但是 现在几乎不怎么用了
    vcfghtyjc
        2
    vcfghtyjc  
    OP
       2021-03-23 23:39:42 +08:00
    @togou 谢谢,我试试。主要是 epoll 在 mac 上没有,就用了 select
    byaiu
        3
    byaiu  
       2021-03-24 09:05:55 +08:00 via iPhone
    这个 set 每次都要设置一下吧……是不是只在循环开始设置过?
    vcfghtyjc
        4
    vcfghtyjc  
    OP
       2021-03-24 09:10:05 +08:00
    @byaiu 你是指 `FD_SET` 吗?每次 `select` 之前都要重新设置吗?我没有重新设置,前面几次 `select` 都没什么问题,后面才出现的问题。
    byaiu
        5
    byaiu  
       2021-03-24 10:12:06 +08:00
    @vcfghtyjc 这个还是要重新设置的。你可以试试看。
    vcfghtyjc
        6
    vcfghtyjc  
    OP
       2021-03-24 12:14:20 +08:00
    @byaiu 嗯,解决了,没太想懂为什么每次都要 set,感觉这里效率有点低,代码有些冗长。
    byaiu
        7
    byaiu  
       2021-03-24 13:02:45 +08:00
    效率并不低。这个是 bit pattern,印象里只有监听超过 1024 个 fd 的时候才会不够用。一般的程序用不到这么多的客户端。

    传来传去的问题在 epoll 里得到了解决,但是也是得一个 fd 一个 fd 的 set 到内核里去,对于少量 fd ( 10 个的量级),select 还有可能是最高效的。
    byaiu
        8
    byaiu  
       2021-03-24 13:05:04 +08:00
    @vcfghtyjc 系统层面的编程,需要的是用户层适配,而不是质疑系统层面的 API 设计。这些历史遗留问题也不是现在就能解决掉的了。

    好在,这种问题只需要解决一次,真正的价值还是用户层的程序实现的。
    vcfghtyjc
        9
    vcfghtyjc  
    OP
       2021-03-25 00:09:38 +08:00
    @byaiu 学到了,多谢!
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1636 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 16:41 · PVG 00:41 · LAX 08:41 · JFK 11:41
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.