由 select() 发出读信号,但 recv() 不返回数据并在非阻塞套接字上发出 EAGAIN 信号
我已经从 select() 中读取了有信号的套接字,但随后 recv call() 没有收到任何数据,而是返回 -1 且 errno==EAGAIN。
我可以保证没有其他线程接触套接字。
我认为这种行为是不正确的。如果随后发生来自另一端的关闭,我可以期望从recv返回值0(优雅关闭)或其他错误代码,但不是EAGAIN,因为我认为这意味着数据将在将来到达。
我在此处找到了一些关于该问题的先前线程,但没有解决方案。
我在 Ubuntu Linux Oneric 或其他最后的 Linux 发行版上发生了这种行为,然后从发布的链接中获取信息 here
对于 3.0.0 内核或最新的 2.6.x 来说,它将在内核中修复,这并不正确。
有人知道为什么会发生这种情况以及如何避免这种不需要的行为吗?
I have got signaled socket for read from select(), but then no data arrived by recv call(), instead it returns -1 with errno==EAGAIN.
I can grant that no other thread touch the socket.
I think that this behavior is not correct. If an subsequent close from other side occurs, I can expect return value 0 (graceful close) or other error code from recv, but not EAGAIN, because it means by my opinion that an data will arrive in the future.
I have found some previous thread about the problem here but without solution.
This behavior happens to me on Ubuntu Linux Oneric, or other last Linux distros, then info from link posted here
That it will be fixed in kernel is not true for 3.0.0 kernel or latest 2.6.x
Does anybody have an idea why it happens and how to avoid this unwanted behavior?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Select() 将套接字报告为可读并不意味着有东西可以读取;这意味着读取不会阻塞。读取可能返回 -1 或 0,但不会阻塞。
更新:
select 返回可读后:如果 read() 返回 -1,请检查 errno。
EAGAIN/EWOULDBLOCK 和 EINTR 是需要特殊处理的值:主要是通过重新发出 read() 来实现,但您可能会相信 select 循环下次会返回可读的值。
如果涉及多个线程,事情可能会变得更加困难。
Select() reporting a socket as readable does not mean that there is something to read; it implies that a read will not block. The read could return -1 or 0, but it would not block.
UPDATE:
After select returns readable: if read() returns -1, check errno.
EAGAIN/EWOULDBLOCK and EINTR are the values to be treated specially: mostly by reissuing the read(), but you might trust on the select loop returning readable the next time around.
If there are multiple threads involved, things may get more difficult.
我也遇到同样的问题,不过是用 epoll 的。我注意到,每当系统重用已关闭的套接字的 FD 号时,就会发生这种情况。
经过一些研究,我注意到这种行为是由于在对套接字进行 epolling 时关闭套接字引起的。尝试避免在关闭套接字时在套接字上运行 select - 这可能会有所帮助。
I'm getting the same problem but with epoll. I noticed, that it happens whenever the system is reusing the FD numbers of the sockets that are already closed.
After some research, I've noticed that this behavior is caused by closing the sockets while epolling on them. Try to avoid running select on a socket while closing it - that may help.