【发布时间】:2015-05-15 10:54:01
【问题描述】:
在 OSX 上,在绑定和侦听套接字上调用 accept() 后,我不断收到 316 的套接字错误。 我得到了一个有效的套接字返回,我相信我可以很好地使用它,(虽然我可能不是,我需要仔细检查,因为我随时接受数百个连接)但 errno 已设置。
我试图了解 the documentation on the unix accept(2) man pages 的哪些注释(顺便说一下,apple's accept() documentation 中缺少这些注释)
Linux accept()(和 accept4())传递已经挂起的网络错误 在新套接字上作为来自 accept() 的错误代码。这种行为 不同于其他 BSD 套接字实现。可靠运行 应用程序应检测为 accept() 之后的协议,并通过重试将它们视为 EAGAIN。
现在,316 与 ETIMEDOUT(60) 的结果为 256 OR'd。所以,我很好奇我应该如何处理这个问题;
- 如果在accept() 之后设置了任何错误,我应该再次accept() 吗?
- 我应该 close() 接受 DID 返回的 SOCKET 吗?
- 是 unix errno 代码的 8 位? (我看到的所有代码都
- 这个错误是否意味着我刚刚从堆栈中弹出的连接超时...本身和操作系统断开了它们,或者我没有足够快地接受()?
【问题讨论】:
-
这个“...如何在绑定和侦听套接字上调用accept() 后继续收到316 的套接字错误。我得到一个有效的套接字返回,”工作?如果
accept()返回了-1,您只想检查errno,而这又不是有效的套接字描述符。 -
这是我最初的想法,但引用的文档说“在新套接字上传递已经挂起的网络错误”。这里的新插座意味着......我现有的插座?还是它生成的新套接字?
-
不过,我在调用
accept()之前刚刚弹出了所有错误,而且我觉得这毕竟只是一个旧的错误代码,所以在其他一些调用之后我不会检查错误... -
Hmhmja,Linux 手册页还继续列出检查 TCP/IP 的代码。所以我要做的(对于Linux)是在调用
accpet()之前将errno设置为0,然后在accept()返回一个值>=0之后只测试errno和ENETDOWN,@987654334 @、ENOPROTOOPT、EHOSTDOWN、ENONET、EHOSTUNREACH、EOPNOTSUPP和ENETUNREACH,如所列。请注意,此行为仅记录在案。在 OSX 上不需要这样做。 -
OS X 网络基于 BSD,因此不会表现出 Linux 的怪异。在 OSX 上,
ELAST是最大的 errno,在 10.9 上是 106。正如@alk 所说,不要检查errno,除非accept()返回-1。