在获取套接字系统调用(如 recv
)错误时,哪种方式更好(在性能方面)?
- 使用老旧的
errno
- 或者作为
getsockopt()
optname 使用SO_ERROR
?
我认为 errno
(在我的系统上定义为 __error()
)更快,因为它不是一个系统调用。我对吗?
SO_ERROR 的优点是:在获取后会自动重置错误,并且我们确信该错误仅涉及我们的套接字。它更安全。
你认为哪一个更好?这两者之间真的有性能差异吗?
在获取套接字系统调用(如 recv
)错误时,哪种方式更好(在性能方面)?
errno
getsockopt()
optname 使用 SO_ERROR
?我认为 errno
(在我的系统上定义为 __error()
)更快,因为它不是一个系统调用。我对吗?
SO_ERROR 的优点是:在获取后会自动重置错误,并且我们确信该错误仅涉及我们的套接字。它更安全。
你认为哪一个更好?这两者之间真的有性能差异吗?
引用丹·伯恩斯坦的话:
情况:您设置了一个非阻塞套接字并执行 connect(),返回 -1/EINPROGRESS 或 -1/EWOULDBLOCK。然后,您将套接字选择为可写状态。这将在连接成功或失败时立即返回。(例外情况:在某些旧版 Ultrix 中,select() 在 75 秒超时之前无法注意到连接失败。)
问题:select() 返回可写性后该怎么办?连接是否失败?如果失败了,它是如何失败的?
如果连接失败,原因会隐藏在套接字中的 something called so_error 中。现代系统可以使用 getsockopt(,,SO_ERROR,,) 查看 so_error...
他继续讨论了 getsockopt(,,SO_ERROR,,)
是一个现代发明,不适用于旧系统,并介绍了如何在这些系统上获取错误代码。但如果您正在为发布在过去15年内的Unix/Linux系统编程,那么您可能不需要担心这个问题。
Linux 的 connect
手册描述了 SO_ERROR
的同样用法。
因此,如果您在套接字上执行异步操作,则可能需要使用SO_ERROR
。在任何其他情况下,只需使用errno
。
exceptfds
呢?微软表示:https://msdn.microsoft.com/en-us/library/windows/desktop/ms740141(v=vs.85).aspx "如果一个套接字正在处理连接调用(非阻塞),则连接尝试失败将在exceptfds中指示(应用程序必须随后调用getsockopt SO_ERROR来确定错误值)" - 这个exceptfds行为是仅适用于Windows还是*nix系统也可以使用? - JustAMartinexceptfds
报告非阻塞connect()
失败的系统。 - Remy Lebeau
select()
)并且可能会设置errno
,它仍然安全地储存在套接字数据中。 - user207421