2010-11-21 25 views
3

私は単純なWebサーバーを作成しています。私は、ユーザがサーバが聞いているポートを に設定するようにしたいと思いますが、ユーザの入力が既に使用されているかどうかはどうすればわかりますか?(すでに使用されているとわかっていれば、もう1つ)Linux上のポートですでにポートが使用されているかどうかを検出するにはどうすればよいですか?

答えて

8

ポートにbindを単に入力し、失敗した場合はをerrnoにチェックしてください。これは唯一の方法です。正しいものであるためには、そのようなチェックはアトミックでなければなりません。別のチェックを行ってポートが使用されていないことを確認した後でバインドしようとすると、その間に別のプロセスがポートにバインドされ、再度失敗する可能性があります。同様に、別のチェックを行い、すでに使用中のポートが見つかった場合は、そのポートを使用していたプロセスが、途中でポートを閉じたり、終了したり、クラッシュしたりして、結果を不正確にする可能性があります。

すべての点(私が短い答えではなく長い答えを書いた理由)は、「そういうことをすることができますか?ほとんどいつもにそれをしようとすると、と失敗を確認してください。他の方法では競合状態に陥る可能性があり、多くの場合競合状態(おそらくあなたのものではない)は競合状態がセキュリティ上の脆弱性です。

5

bind()は失敗します:

成功し

、ゼロが返されます。エラーの場合、-1が返され、errnoが適切に設定されます。

EADDRINUSE 指定されたアドレスはすでに使用されています。

+0

しかし、このように私はサーバーソケットを作成しなければなりません... bind()...それを閉じます..そこにはもっと簡単な方法がありますか? – wong2

+2

いいえ、それは唯一の正しい方法です。とにかくそれを閉じたいのはなぜですか?すでにバインドしているかどうかを聞くために単に使用してください。その間に別のプロセスがそのポートにバインドしている可能性があるかどうかは分かりません。 – ThiefMaster

+0

@ wong2:私の答えを読んでください。ポートをバインドして、使用準備が整うまでポートをバインドしない限り、問題を解決する方法はありません(「ポートはすでに使用されていますか?」)。事前にチェックして(そしてそれを解放する)間違った答えが出されることがあります。 –

0

もう1つの方法:localhostのポートに接続してみます。

+1

これは悪い考えで、このテストが失敗する可能性がある理由をいくつか追加してください。答えは価値があるかもしれません... –

+1

a)実行中のサーバが特定のインターフェースをlistenし、 'localhost'への接続がそれをチェックしません; b)タイムアウト。 c)この方法を使用して、TCPサーバーを別のプロセスとして開始するようにポートをチェックしました(失敗時に適切なエラーコードが返されないため、チェックするしかありません)。 – khachik

+0

ちなみに、ポートをバインドして原子的にテストしても、(a)は問題になります。 0.0.0.0:portで接続が成功したとしても、すでに他のプロセスがaaa.bbb.ccc.ddd:port(外部ネットワークアドレスのIP)にバインドしている可能性があります。 –

0

bind()が何らかのエラーを表示する場合

0

ソケットを作成してbind()を呼び出すだけです。 bind()が成功した場合はlisten()に進みます。そうしないと、デフォルトのポートに切り替えたり、エラーメッセージを表示したり、対話を待つか、少なくともログアウトして終了するなど、何らかのエラー処理手順を実行する必要があります。

関連する問題