• ベストアンサー

同一ポート番号ソケットOPENの制限について

同一ポート番号で ソケットOPENできる制限について知りたいのですが ご教示いただけませんでしょうか。 接続される側の 対象OSが Windows7 32bit 対応言語は c++Ver6 接続しにくるのは Windows CEです。 よろしくお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

接続されるサーバ側で考えて見ます。 TCP/IPの仕様として、ザックリと簡単にいえば、一度に使えるポートは1つのみで、 すでに使用されているポートを排他する仕様があります。 たとえばWebサーバを作るとき、すでに別のアプリで80番ポートがリスナとして開かれていると、 そのポートに実際のセッション(接続状態)が無くてもエラーになったりします。 これは、そのポートを先に開いていた接続が閉じた後も待機状態にあるためで、 ただしクライアントが先に閉じると(FIN)、待機状態にはなりません。 この仕様によって、80番を使っている別のサーバを落としたのに、 同じ80番を使おうとしている自身のアプリでポートが開けたり開けなかったりすることが生じます。 しかし接続は閉じているのだから何とかして使いたいですよね。 この待機状態を自身のアプリで利用可能にするための方法があります。 サーバ側のアドレスをソケットにbindする前にSO_REUSEADDRオプションを設定すると、 同じポートを再利用可能にすることができます。 また、OSが提供するAPI上の制約もあります。 サーバ側では、listen (Win32ではプロバイダ側のWSPListen)に指定するバックログというパラメータがあります。 この値はリスニング中に待機させることができるキューのクライアント接続数です。 これを超える数のクライアント接続は失敗します。 Windowsでは仕様上はSOMAXCONN(128)が上限ですが、Windowsのバージョンやエディション、ネットワークドライバの仕様などによっては5以下に制限されることもあり、この値より大きい値は指定できません。 これでは制限がありすぎて使い物にならない、という気がしますね。 しかし、受諾したクライアントのソケットアドレス(アドレスとポート番号のペア)は、 実は二重化(コピー)して使うことができ、元の接続を閉じることができるのです。 このコピーを使用すると、クライアントとの送受信をスレッドとして分離して非同期に行うことができるので、受諾したソケットアドレスはコピーしてスレッドに引き渡したら、元のソケットハンドルを閉じて次のリスンを開始することができ、これによってバックログのサイズはごく小さくすることできます。 これらの手法を使うことによってサーバプロセスでは、 1つしかないポートを複数のプロセスやスレッドで分散し処理するしくみが作れるようになっています。 お役に立てれば幸いです。

athiro2
質問者

お礼

詳細なコメント、回答をありがとうございます。 参考になりました。

その他の回答 (1)

  • koi1234
  • ベストアンサー率53% (1866/3459)
回答No.1

理論的には接続数の制限はないはずですが サーバ側の負荷などの方が問題になってくるのではないかと思います Windows共有などは↑の理由で接続制限を付けているだけでしょう そんなものがあったら 一定接続されたホームページなどには 他の人がアクセスできないということになります (HTTPに限った話ではないが例としてわかりやすいと思うので)

athiro2
質問者

お礼

仕様的には、大丈夫という事ですね。 ご教示頂きありがとうございます。

関連するQ&A