10

对于获取套接字系统调用(如recv)错误,哪个更好(在性能级别)?

  • 使用普通的旧errno
  • SO_ERROR用作getsockopt()optname ?

我认为errno__error()在我的系统上定义)更快,因为它不是系统调用。我对吗 ?

SO_ERROR 的优点是:获取后自动错误重置,并且我们确信错误只与我们的套接字有关。它更安全。

你觉得哪一个更好?两者之间真的存在性能差异吗?

4

2 回答 2

9

引用丹·伯恩斯坦的话

情况:您设置一个非阻塞套接字并执行一个返回-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.

于 2014-01-09T21:51:48.637 回答
1

引用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 是更好的选择,除非您想在数据完全获取之前立即出错。

于 2016-08-14T03:57:15.230 回答