2011-07-15 11 views
2

C++ Linuxアプリケーションでは、socket()、bind()、およびlisten()を呼び出してサーバーソケットを作成しています。通常、アプリケーションが2回(同じサーバーポートで)起動された場合、2番目のプロセスでbind()は失敗し、EADDRINUSEエラーが発生します。しかし、今ではbind()が明らかに成功したが、それに続くlisten()コールがEADDRINUSEエラーをスローしたケースがあります...なぜbind()からではなくlisten()からEADDRINUSEを取得できますか?

これはおそらくまれな競合状態ですが、 2番目のbind()は成功するが、2番目のlisten()は成功しない場合があります。誰かがそのような事件についてもっと知っていますか?

これは32ビット版RHEL 5.3です。

答えて

3

ないLinuxについて確認が、Windows上を参照してください。 bind()を呼び出すときにIP(INADDR_ANYなど)が指定された場合、OSはその時点で使用するのが最適なネットワークインタフェースを決定する可能性が高いため、listen()またはconnect()が呼び出されるまで、 bind()はその状況でエラーを報告しません。

+0

ありがとう、それは説明のようです。明らかに、ルールは次のとおりです。 listen()はカーネル内のポートを実際に予約し、別のプロセスがlisten()を呼び出した場合はEADDRINUSEを送出します。 bind()はポートを予約しませんが、別のプロセスがポート上でlisten()を呼び出した場合はEADDRINUSEを送出します – oliver

1

setsockopt(.... SOL_SOCKET, SO_REUSEADDR, ...)で問題を解決する必要があります。

ワイルドカードならば、setsockopt(2)socket(7)

(第2 bindが実際に成功した理由として、全く分から...実際には、これはすでにあまりにも失敗するべきではありません)

+0

失敗した2番目のインスタンスは***良い***ものです。 –

+0

@Ben Voigt:確かに、私は思っていますが、「聞く」だけでは失敗するのではなく、すでにバインドしています。 Remy Lebeauの_delayed binding_についての理論はおそらく理由ですが、それはとにかく完璧な意味合いです。 – Damon

+0

私たちは同意してうれしいです。しかし、 'SO_REUSEADDR'は問題を解決していないので隠します。 –

関連する問題