c-SO_错误与错误号



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

  • 使用普通的旧errno
  • 或者使用SO_ERROR作为getsockopt()optname

我认为errno(在我的系统中定义为__error())更快,因为它不是系统调用。我说得对吗?

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

你认为哪一个更好?这两者的表现真的有什么不同吗?

引用Dan Bernstein的话:

情况:您设置了一个非阻塞套接字并执行connect(),返回-1/EINPROGRESS或-1/EWOULDBLOCK。您可以选择()套接字进行写入。一旦连接成功或失败,就会返回此消息。(例外:在一些旧版本的Ultrix中,select()在75秒超时之前不会注意到失败。)

问题:select()返回可写性后,你会怎么做?连接失败了吗?如果是,它是如何失败的?

如果连接失败,原因会隐藏在套接字中名为so.error的内容中。现代系统允许您使用getsockopt(,,so_error,,)查看so.error。。。

他接着讨论了getsockopt(,,SO_ERROR,,)是一项现代发明,它不适用于旧系统,以及如何在这些系统上获得错误代码。但如果你为过去15年发布的Unix/Linux系统编程,你可能不需要担心。

connect的Linux手册页描述了SO_ERROR的相同用法。

因此,如果您在套接字上执行异步操作,可能需要使用SO_ERROR。在任何其他情况下,只需使用errno

报价Unix网络编程:

如果进程调用read时so_error为非零,并且没有要返回的数据,读取返回–1,errno设置为so_error的值(TCPv2第516页)。CCD_ 14的值随后被重置为0。如果有是排队等待套接字的数据,该数据通过读取返回错误条件的。如果进程调用时so_error为非零write,返回–1,errno设置为so_error的值(第495页TCPv2的)并且CCD_ 18被重置为0。

因此,errno是更好的选择,除非您希望在数据完全提取之前立即得到错误。

相关内容

  • 没有找到相关文章

最新更新