In Luasocket, under which conditions can an accept call block even after select tells it is safe to read?
Luasocket 的选择函数应该告诉何时可以无阻塞地读取套接字。它显然也可以用来判断服务器套接字何时准备好接受新连接,但是文档给出了以下警告:
Another important note: calling select with a server socket in the receive parameter before a call to accept does not guarantee accept will return immediately. Use the settimeout method or accept might block forever.
在什么情况下即使select告诉它可以安全读取也可以接受块?出于测试目的,有没有办法强制发生此问题?
我不知道他们从哪里得到这个想法。在 20 多年的网络编程中从未见过它。
如果您有多个 select() 线程,当然会发生这种情况,但如果这是预期的,我希望文档会这样说。
这是从已故 W.Richard Stevens 的"Unix 网络编程"第 461-463 页的第三版的第 16.6 节(非阻塞
虽然你可能认为
连接到服务器;
在连接的套接字上设置
立即关闭套接字。因为已设置
现在,让我们假设服务器正在运行,但在负载很重的机器上。修改后的 echo 客户端运行。 TCP 连接导致
但是,在执行
所以当服务器代码开始
上述行为实际上可能不会发生。 POSIX 希望
In Section 5.11, we noted that when the client aborts the connection before the server calls `accept`, Berkeley-derived implementations do not return the aborted connection to the server, while other implementations should return `ECONNABORTED` but often return `EPROTO` instead.
史蒂文斯的源代码可在此发布者的网站上获得;修改后的客户端是
我不相信 FreeBSD 或 Linux 不再表现出伯克利派生的行为,尽管我很确定我记得它发生在 FreeBSD 上(那可能是十多年前,而且我不再有FreeBSD 盒子可以方便地对其进行测试。)OpenBSD 似乎已在 1999 年进行了修补以解决该问题(请参阅 2.4 的补丁);可能其他伯克利衍生物后来也做了类似的改变。我不知道 MacOSX(尽管它可能与 FreeBSD 相同)或 Windows。很可能没有现代系统表现出这种行为,尽管在 Stevens 编写 UNP 时它肯定是可以观察到的。
无论如何,史蒂文斯的建议很简单,小心一点总不会有坏处。他的建议是:
当你在其上使用
如果