事实
在 POSIX 文档中,我看不到任何阻止将SO_REUSEADDR
套接字选项与AF_UNIX
UNIX 域套接字一起使用的东西。
但是,如果套接字节点已经存在,它总是会失败bind
,并且似乎被忽略了,并且似乎需要在调用之前先取消链接文件系统上的套接字节点bind
;简而言之,它不会重用地址。网上有很多关于这个问题的帖子,但没有一个解决方案。
问题
我不会坚持,如果它不起作用,它就不起作用(似乎至少在 BSD 和 Linux 系统上都是一样的),只是有一个问题:这是正常行为吗?是否有任何指针表明它应该被支持,或者相反,任何指针表明它不应该被支持?或者这是未指定的?请注意,该问题是在 POSIX 上下文中提出的,而不是在任何特定平台上下文中。
我欢迎关于此事的任何 POSIX 参考。
额外:一个小片段,不盲目unlink
谁知道什么
我在网上看到了一些线程,建议unlink
在bind
. 我觉得这是不安全的,在这种情况下应该只取消链接已经是套接字节点的节点:例如。取消链接名为的文本文件以mysocket
重新创建同名的套接字节点可能是错误的。为此,这里有一个小片段:
/* Create the socket node
* ----------------------
* Note `SO_REUSEADDR` does not work with `AF_UNIX` sockets,
* so we will have to unlink the socket node if it already exists,
* before we bind. For safety, we won't unlink an already existing node
* which is not a socket node.
*/
status = stat (path, &st);
if (status == 0) {
/* A file already exists. Check if this file is a socket node.
* * If yes: unlink it.
* * If no: treat it as an error condition.
*/
if ((st.st_mode & S_IFMT) == S_IFSOCK) {
status = unlink (path);
if (status != 0) {
perror ("Error unlinking the socket node");
exit (1);
}
}
else {
/* We won't unlink to create a socket in place of who-know-what.
* Note: don't use `perror` here, as `status == 0` (this is an
* error we've defined, not an error returned by a system-call).
*/
fprintf (stderr, "The path already exists and is not a socket node.\n");
exit (1);
}
}
else {
if (errno == ENOENT) {
/* No file of the same path: do nothing. */
}
else {
perror ("Error stating the socket node path");
exit (1);
}
}
/* … invoke `bind` here, which will create the socket node … */