对于获取套接字系统调用(如recv
)错误,哪个更好(在性能级别)?
- 使用普通的旧
errno
- 或
SO_ERROR
用作getsockopt()
optname ?
我认为errno
(__error()
在我的系统上定义)更快,因为它不是系统调用。我对吗 ?
SO_ERROR 的优点是:获取后自动错误重置,并且我们确信错误只与我们的套接字有关。它更安全。
你觉得哪一个更好?两者之间真的存在性能差异吗?
对于获取套接字系统调用(如recv
)错误,哪个更好(在性能级别)?
errno
SO_ERROR
用作getsockopt()
optname ?我认为errno
(__error()
在我的系统上定义)更快,因为它不是系统调用。我对吗 ?
SO_ERROR 的优点是:获取后自动错误重置,并且我们确信错误只与我们的套接字有关。它更安全。
你觉得哪一个更好?两者之间真的存在性能差异吗?
引用丹·伯恩斯坦的话:
情况:您设置一个非阻塞套接字并执行一个返回-1/EINPROGRESS 或-1/EWOULDBLOCK 的connect()。您 select() 用于可写性的套接字。只要连接成功或失败,它就会返回。(例外:在某些旧版本的 Ultrix 下,select() 在 75 秒超时之前不会注意到失败。)
问题:select() 返回可写性后怎么办?连接失败了吗?如果是这样,它是如何失败的?
如果连接失败,原因将隐藏在套接字中名为 so_error 的内容中。现代系统让你看到 so_error 与 getsockopt(,,SO_ERROR,,) ...
他继续讨论了getsockopt(,,SO_ERROR,,)
一个现代发明,它不适用于旧系统,以及如何在这些系统上获取错误代码。但是,如果您正在为过去 15 年发布的 Unix/Linux 系统编程,您可能不需要担心这一点。
Linux 手册页connect
描述了SO_ERROR
.
因此,如果您在套接字上执行异步操作,您可能需要使用SO_ERROR
. 在任何其他情况下,只需使用errno
.
引用Unix 网络编程:
如果当进程调用 read 并且没有数据要返回时 so_error 非零,read 将返回 –1 并将 errno 设置为 so_error 的值(TCPv2 的第 516 页)。so_error 的值然后重置为 0。如果有数据排队等待套接字,则该数据由 read 而不是错误条件返回。如果在进程调用 write 时 so_error 不为零,则返回 –1 并将 errno 设置为 so_error 的值(TCPv2 的第 495 页),并将 so_error 重置为 0。
因此,errno 是更好的选择,除非您想在数据完全获取之前立即出错。