【问题标题】:Spurious recv() EAGAIN on OSX?OSX上的虚假recv()EAGAIN?
【发布时间】:2011-03-28 03:12:35
【问题描述】:

编辑:问题已解决,我之前在服务器套接字上错误地调用了 fcntl(sock, F_SETFL, FD_CLOEXEC)。这不知何故被映射到包含 O_NONBLOCK 的掩码,因为 FD_CLOEXEC 用于 F_SETFD,而不是 F_SETFL,并且也被继承到客户端套接字。

你好,

我正在 Mac OS X 10.4 上开发网络应用程序。这里发生了一些奇怪的事情:有时 - 非常定期且可靠地 - 阻塞 TCP 套接字上的 recv() 操作返回 -1,并将 errno 设置为 EAGAIN。

这很奇怪,因为如前所述,它是一个阻塞套接字。我也没有设置任何接收超时 - 作为文档状态,这也可能导致 EAGAIN 返回。我使用 getsockopt() 来验证没有超时。如果我打一个 usleep() 并再次调用 recv() ,那么我得到下一个数据就好了。

以前有人在 OSX 上或其他系统上遇到过这种情况吗?

这个应用程序非常简单。它是单线程的,不使用信号,没有异步 I/O。

【问题讨论】:

标签: macos


【解决方案1】:

手册页内容如下:

[EAGAIN] 套接字标记为非阻塞,并且接收 操作将阻塞,或已设置接收超时,并且在数据被发送之前超时已过期 收到了。

注意“超时”部分。

【讨论】:

  • 就像我说的,没有设置超时。就像我说的,我使用 getsockopt() 验证了这一点。看起来毕竟设置了 O_NONBLOCK 但我没有在任何地方请求 O_NONBLOCK。
【解决方案2】:

我发现了我的错误:

我调用了 fcntl(fd, F_SETFL, FD_CLOEXEC);当我应该为这个标志使用 F_SETFD 时:-(

我不知道这到底是如何映射到包含 O_NONBLOCK 的掩码的——因为它们有不同的值——但就是这样。

感谢您的宝贵时间。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-08
    • 1970-01-01
    • 1970-01-01
    • 2014-04-15
    • 2019-04-22
    • 2014-10-01
    相关资源
    最近更新 更多