8

同じポートをリッスンするように構成された Windows 7 で stunnel の 2 つのインスタンスを実行していますが、両方とも同じポートで正常にリッスンしているようです (socket()/bind()/listen() を使用するだけです)。両方のインスタンスがすべての呼び出しで成功したように見え、netstat に表示されます。

C:\>netstat -ano | grep 8000
  TCP    0.0.0.0:8000           0.0.0.0:0              LISTENING       5828
  TCP    0.0.0.0:8000           0.0.0.0:0              LISTENING       5852

最初にリッスンするものは、すべての受信リクエストを取得します。

これは私のすべての期待とはかなり反対です。(ポートがビジー状態であることを EADDRINUSE が知らせてくれることを期待していました。) それで....

  1. なぜ/どのように機能するのですか? この動作は、何らかの状況で役に立ちますか?
  2. 別のアプリケーションが着信要求をキャッチしようとしている場合、インスタンスを正常に実行したくありません... ポートを排他的にするにはどうすればよいですか?
4

1 に答える 1

7

これは、ソケットがフラグSO_REUSEADDRで開かれた場合に実現できます。これは、TCP ソケット アプリケーションでは珍しいことではありません。

通常、SO_REUSEADDR は次の 2 つのいずれかに使用されます。

  1. プロセスがクラッシュしたり、強制終了されたり、ソケットを閉じる機会がないまま強制的に再起動されたりした場合。または、プロセスは終了しましたが、ソケット (または子接続ソケット) がまだ FIN_WAIT または FIN_WAIT2 状態です。2 番目のプロセスは、「既に使用中」のエラー コードを取得せずにソケットを開くことができます。これがTCPソケットのベストプラクティスであることを示唆するSOに関するいくつかの投稿を読みました。

  2. 同じサーバー プログラムが同時に複数回 fork または実行されました。これにより、サーバー プログラムがスレッドを使用するように記述されていなくても、負荷分散が可能になります。通常、ソケットをリッスンしているプログラムの「他のインスタンス」は、最初のインスタンスが別の接続でビジー状態である間に着信接続を受け入れます。

2 番目の質問に関して、最も簡単な方法は SO_REUSEADDR を使用しないことです。SO_REUSADDR を使用しようとする不正なアプリの可能性が懸念される場合は、アプリで SO_EXCLUSIVEADDRUSE を使用できます。(基本的に「他のアプリが SO_REUSEADDR で同じポートを開くことを許可しない」というフラグ。)

于 2012-09-10T15:48:41.873 に答える