【问题标题】:Timed out recv producing both EAGAIN and ETIMEDOUT?生成 EAGAIN 和 ETIMEDOUT 的 recv 超时?
【发布时间】:2018-07-12 08:00:45
【问题描述】:

对于通过setsockopt 设置SO_RCVTIMEO 的阻塞recvEAGAINETIMEDOUT 有什么区别?

我有一个阻塞recv,它偶尔会失败,但它会以不同的方式失败(返回-1),具体取决于连接到我的服务器的客户端。一个客户端产生“资源暂时不可用”,另一个产生“连接超时”。 socket 手册页说

如果没有数据被传输并且已经达到超时时间,那么 返回 -1 并将 errno 设置为 EAGAIN 或 EWOULDBLOCK

没有提到 ETIMEDOUT。我猜其中一个客户端仍在生产 TCP keepalive,但我找不到任何关于此的文档。我在 Linux 3.10、Centos 7.5 上。

【问题讨论】:

  • 客户端必须运行在不同的平台上。它们是什么?
  • @EJP:不知道——这是一个邮件服务器。一个是垃圾邮件发送者,另一个正在运行损坏的软件:)
  • 所以这些消息出现在服务器上?在这种情况下,ETIMEDOUT 意味着返回客户端的路径不起作用,它应该出现在send() 上或之后。如您所述,EAGAIN/EWOULDBLOCK 发生在 recv() 上。
  • @EJP:日志输出是在recv 返回-1 时创建的,所以它们都肯定会收到。我已经为 EAGAIN 客户端附加了gdb,没有超时,并确认它挂在recv 中。不过,没有尝试过 ETIMEDOUT 案例。
  • 是的,当记录 recv 所做的事情时,两条消息都出现在服务器上

标签: sockets glibc


【解决方案1】:

ETIMEDOUT 几乎可以肯定是对之前send() 的回应。 send() 是异步的。如果它不返回 -1,则意味着数据已传输到本地套接字发送缓冲区。它是异步发送或不发送的,如果该过程中出现错误,它只能通过下一个系统调用传递:在这种情况下,recv()

不清楚这里有什么问题需要解决

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-17
    • 1970-01-01
    • 2015-05-31
    相关资源
    最近更新 更多