我在使用 c++ 的 select
实现服务器同时连接多个客户端,出现的情况是有的时候 FD_ISSET
可以监测处哪些 socket 可读,有的时候虽然所有 socket 用 FD_ISSET
都返回 0,但是客户端是发送了数据过来的。如果读取 socket,是可以读到客户端发的内容,但是 FD_ISSET
和 select
函数并不会标记该 socket 为可读。
当我用多个客户端和服务器向服务器发信息的时候,一般是前几次所有 socket 都可以正常检测出可读的 socket,逐渐的,可检测出的可读 socket 越来越少,直到所有 socket 都被认为是不可读。
不知道有没有哪位大佬知道原因。我现在用 macOS 写代码,调用的并不是 FD_ISSET
而是 __DARWIN_FD_ISSET
,不知道和这个有没有关系。
顺便问一下,FD_ISSET
的值是什么时候更新的?我在读 socket 前后各返回了 FD_ISSET
,返回的是相同的值(该值表示 socket 可读)。所以是在执行 select
时候更新的吗?
1
togou 2021-03-23 18:37:20 +08:00
用 epoll 吧 select 虽然每个系统都有 但是 现在几乎不怎么用了
|
3
byaiu 2021-03-24 09:05:55 +08:00 via iPhone
这个 set 每次都要设置一下吧……是不是只在循环开始设置过?
|
4
vcfghtyjc OP @byaiu 你是指 `FD_SET` 吗?每次 `select` 之前都要重新设置吗?我没有重新设置,前面几次 `select` 都没什么问题,后面才出现的问题。
|
7
byaiu 2021-03-24 13:02:45 +08:00
效率并不低。这个是 bit pattern,印象里只有监听超过 1024 个 fd 的时候才会不够用。一般的程序用不到这么多的客户端。
传来传去的问题在 epoll 里得到了解决,但是也是得一个 fd 一个 fd 的 set 到内核里去,对于少量 fd ( 10 个的量级),select 还有可能是最高效的。 |