【发布时间】:2013-03-20 22:12:28
【问题描述】:
事实
在 POSIX 文档中,我看不到任何阻止将 SO_REUSEADDR 套接字选项与 AF_UNIX 一起用于 UNIX 域套接字的内容。
但是,如果套接字节点已经存在,它总是在 bind 时间失败,并且似乎被忽略,并且似乎需要在调用 bind 之前首先取消链接文件系统上的套接字节点;简而言之,它不会重用地址。网上有很多关于这个问题的帖子,但没有一个解决方案。
问题
我不会坚持,如果它不起作用,它就不起作用(似乎至少在 BSD 和 Linux 系统上都是一样的),只是有一个问题:这是正常行为吗?是否有任何指针表明它应该被支持,或者相反,任何指针表明它不应该被支持?或者这是未指定的?请注意,该问题是在 POSIX 上下文中提出的,而不是在任何特定平台上下文中。
我欢迎任何关于此问题的 POSIX 参考。
额外:一个小小的 sn-p 不盲目unlink who-know-what
我在网上看到一些帖子,建议unlink 在bind 之前的任何预期名称的节点。我觉得这是不安全的,在这种情况下应该只取消链接已经是套接字节点的节点:例如。取消链接名为mysocket 的文本文件以重新创建同名的套接字节点可能是错误的。为此,这里有一个小小的 sn-p:
/* 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 … */
【问题讨论】:
-
要明确一点:您是要在 POSIX 规范中引用说明这种行为是否正确,还是要问常见的 POSIX 实现的行为方式?
-
我想知道常见的 POSIX 实现(至少是 Linux 和 BSD)是对还是错;所以是的,我会说我正在寻找类似 POSIX 的引用。注意我知道这可能只是未指定。附:我将在最初的帖子中添加一个我认为有用的小 sn-p。
-
我认为您应该再添加一个案例。如果文件存在并且是套接字,请尝试
connect()。如果失败,则没有服务正在侦听该套接字,因此可以安全地删除它。另外我认为删除不是套接字的文件不应该自动发生。那可能是一个重要的文件!