获取套接字系统调用(如recv
)错误,哪个更好(在性能级别)?
errno
SO_ERROR
作为getsockopt()
optname?我认为errno
(在我的系统上定义为__error()
)更快,因为它不是系统调用。我是对的吗?
SO_ERROR的优点是:获取后自动错误重置,我们确信该错误仅涉及我们的套接字。它更安全。
您认为哪一个更好?这两者之间的性能真的不同吗?
答案 0 :(得分:4)
情况:您设置了一个非阻塞套接字并执行一个返回-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是更好的选择,除非你想在完全提取数据之前立即得到错误。