我有来自select()的已发信号的套接字,但是后来没有数据通过recv call()到达,而是返回-1,其中errno == EAGAIN。
我可以授予没有其他线程触及套接字。
我认为这种行为不正确。如果从其他方面发生后续关闭,我可以期待返回值0(正常关闭)或来自recv的其他错误代码,但不是EAGAIN,因为这意味着我认为数据将来会到达。
我找到了一些关于问题here的先前帖子但没有解决方案。
在Ubuntu Linux Oneric或其他最新的Linux发行版上,我发生了这种情况,然后发布了here
链接的信息它将在内核中修复,对于3.0.0内核或最新的2.6.x
是不正确的有人知道它为什么会发生以及如何避免这种不必要的行为吗?
答案 0 :(得分:5)
选择()将套接字报告为可读并不意味着有东西要读;它意味着读取不会阻止。读取可以返回-1或0,但它不会阻止。
更新:
select后返回可读:如果read()返回-1,请检查errno。 EAGAIN / EWOULDBLOCK和EINTR是要特别处理的值:主要是通过重新发出read(),但是你可能会相信下一次返回可读的select循环。
如果涉及多个线程,事情可能会变得更加困难。
答案 1 :(得分:0)
我遇到同样的问题,但有epoll。我注意到,只要系统重新使用已经关闭的套接字的FD号,就会发生这种情况。 经过一些研究,我注意到这种行为是由于在插上套接字时关闭套接字引起的。尝试避免在关闭套接字时在套接字上运行select - 这可能会有所帮助。