SO_ERROR vs. errno

时间:2014-01-09 21:37:49

标签: c sockets unix errno getsockopt

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

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

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

SO_ERROR的优点是:获取后自动错误重置,我们确信该错误仅涉及我们的套接字。它更安全。

您认为哪一个更好?这两者之间的性能真的不同吗?

2 个答案:

答案 0 :(得分:4)

引用Dan Bernstein

  

情况:您设置了一个非阻塞套接字并执行一个返回-1 / EINPROGRESS或-1 / EWOULDBLOCK的connect()。您选择()套接字是否可写。连接成功或失败后立即返回。 (例外:在某些旧版本的Ultrix下,select()在75秒超时之前不会注意到失败。)

     

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

     

如果连接失败,原因会隐藏在套接字中名为so_error的内容中。现代系统让你看到so_error与getsockopt(,, SO_ERROR ,,)......

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

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

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

答案 1 :(得分:0)

引用 Unix网络编程

  

如果so_error在进程调用read时为非零,则没有   要返回的数据,读取返回-1,并将errno设置为so_error的值   (TCPv2的第516页)。然后将so_error的值重置为0.如果存在   是为套接字排队的数据,而是由read返回的数据   错误条件。如果进程调用so_error为非零   写入,返回-1,并将errno设置为so_error的值(p.495   TCPv2)和so_error重置为0。

所以,errno是更好的选择,除非你想在完全提取数据之前立即得到错误。