私はLinux用のUnixドメインソケットサーバーを作成しています。プロセスがUnixドメインソケットにバインドされているかどうかを知るには?
Unixドメインソケットの特色私はすぐにリスニングUnixソケットを作成すると、一致するファイルシステムエントリが作成され、ソケットを閉じることでそれを削除しないことが分かりました。さらに、手動でファイルシステムのエントリを削除するまでは、bind()
は、bind()
のパスがファイルシステムに既に存在する場合にはEADDRINUSE
で失敗します。
したがって、サーバの再起動時にEADDRINUSE
が発生しないように、ソケットのファイルシステムエントリをサーバシャットダウン時にunlink()
にする必要があります。ただし、これはいつでも行うことはできません(サーバークラッシュなど)。ほとんどのFAQ、フォーラムの投稿、Q &私が見つけたウェブサイトは、対応策としてbind()
を呼び出す前にunlink()
ソケットにのみ助言してください。しかし、この場合、プロセスがこのソケットにバインドされているかどうかを知ることが望ましくなり、それがunlink()
の前に行われます。
実際には、プロセスが依然としてバインドされている間にUnixソケットを作成してから、リスニングソケットを再作成してもエラーは発生しません。しかし、その結果、古いサーバープロセスはまだ実行されていますが、到達不能です。古いリスニングソケットは新しいソケットによって「マスク」されます。この動作は避けなければなりません。
理想的には、Unixドメインソケットを使用すると、ソケットAPIは、TCPソケットまたはUDPソケットをバインドする際に公開される「相互排除」と同じ動作を提供する必要があります。 "ソケットSをアドレスAにバインドしたい、プロセスが "残念ながら、これはそうではありません...
この「相互排除」の動作を強制する方法はありますか?いいえ、このアドレスにバインドしてください。または、ファイルシステムのパスを指定すると、からソケットAPIを介して、システム上のプロセスにこのパスにバインドされたUnixドメインソケットがあるかどうかを知る方法がありますか?ソケットAPI(flock()
、...)の外部に同期プリミティブを使用する必要がありますか?または私は何かを逃していますか?
ご意見ありがとうございます。
注:Linuxの抽象名前空間unlink()
へのファイルシステムのエントリがないため、UNIXソケットはこの問題を解決するようです。しかし、私が書いているサーバーは、一般的なものを目指しています。リスンアドレスを選択する責任はないので、両方の種類のUnixドメインソケットに対して堅牢でなければなりません。
あなたの答えをありがとう。従来のロックファイルシステムを使用することは、最も安全な方法です。また、サービスディスカバリシステムが過不足であるかどうかに関しては、皮肉なことに、このサーバはサービスディスカバリシステムの一部であることが計画されています(サービスの「登録」システムが適切でしょう)。これはあなたの質問に答える必要があります;-) –