我应该断言 select() EBADF 失败吗?

gra*_*ski 2 c sockets tcp

我正在尝试修复调用select(). 当select()返回EBADF时,会记录一个错误,然后重新初始化fd集并再次调用select。这会导致日志记录的无限硬循环,在几秒钟内生成千兆字节的日志。

如果我的程序连接到的 TCP 服务器之一进行了不正常的断开连接(例如出现段错误),则会出现此错误。在这种情况下,我理想地希望我的程序删除该 fd 并继续运行(或者如果不可行则关闭)。

我的问题是, select() 是否应该返回 EBADF,或者这是否表明我的程序有错误?即我应该断言 EBADF 失败,否则我应该如何处理它?我会循环遍历 fd 集来查找“坏”文件描述符吗?

use*_*421 6

您的代码中有错误。修理它。在某个地方,您关闭了套接字,但没有将其从选择器使用的 FD 集中删除。否则,您刚刚编写了一个不是 FD 的 FD,并且正在 FD 集中使用它。

与此处的其他陈述相反,网络问题不会导致此错误。网络中断不会关闭套接字,这是它们失效的唯一方法。只有关闭它们才能做到这一点。如果您继续写入连接不工作的套接字,最终将导致 ECONNRESET。对等方已断开连接的套接字将变得可读,并且recv()其上的 a 将返回零。

  • @乔纳森莱因哈特。事实并非如此。套接字保持打开状态,您可以在其上调用“send()”而无需获取 EBADF。TCP 不会神奇地关闭你下面的套接字。 (2认同)