【发布时间】:2018-07-12 08:00:45
【问题描述】:
对于通过setsockopt 设置SO_RCVTIMEO 的阻塞recv,EAGAIN 和ETIMEDOUT 有什么区别?
我有一个阻塞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所做的事情时,两条消息都出现在服务器上