親プロセスが を完了しsocket/bind/accept
、そのソケットを開いた状態で子プロセスをフォークして通信できるようにし、親プロセスは接続の受け入れを継続するとします。その後、その親プロセスは強制終了されます。
別のプロセスが、同じポートで親プロセスがバインドされた同じアドレスにバインドしようとしますが、EADDRINUSE エラーを受け取ります。
しかし、このプロセスを で完了するとsshd
、sshd
は閉じられたポートに再バインドできますが、再起動ウィンドウ中 (sshd 親プロセスが実行されていない) には、別のプログラム (別のユーザーとして実行) が EADDRINUSE を取得します。
この背後にあるセマンティクスは何ですか? なぜsshd
再バインドできるのに、他のユーザーのプロセスはできないのですか?
netstat -a | grep PORT
さらに、子プロセスのみが実行中の間 (他のプロセスが実行できない場合bind
) の出力では、接続はESTABLISHED
1 つだけであり、状態は none であることが確認できますLISTEN
。
答え1
すべてのセマンティクスを理解しているわけではありませんが (間違った場所を調べているか、ドキュメントが不足しています)、接続を閉じた後の一定時間は (おそらく によって設定されていますSO_LINGER
)、設定されていない限り、どのプロセスも同じ詳細で新しいソケットを開くことはできないとSO_REUSEADDR
考えます。
これは、接続が閉じられてから 1 秒後に誰かが再接続し、プロセスが前のプロセス用のパケットを処理しなければならないことを防ぐためだと私は理解しています。
man 7 socket
このことが文書化されていないため、SO_REUSEADDR
この回答を理解するのが困難になっています。