事実
POSIX のドキュメントでは、UNIX ドメイン ソケットでのSO_REUSEADDR
ソケット オプションの使用を妨げるものは何もありません。AF_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 … */