2011-01-14 4 views
8

パッシブとアクティブソケット<a href="http://www.freesoft.org/CIE/Course/Section4/6.htm">this socket tutorial</a>から引用

ソケットは、主に次の2つの種類があります。 アクティブなソケットがオープンデータ 接続を介して遠隔アクティブソケットに接続されている...受動ソケットが接続されていない あり、むしろ 接続が一旦 新しいアクティブソケットを起動します 着信接続を待ちます各ポートは、ポートのオープン 接続に対応 着信接続、及び 複数のアクティブソケット、各 を待って、単一の受動 ソケットがそれにバインドさ有することができる

...設立。工場労働者が到着する新しい メッセージを待っている かのように(彼が パッシブソケットを表す)だと、1つの メッセージは、新たな送信者から到着したとき、彼 は 委譲することで、それらに対応( 接続)を開始しますパケット を実際に読み取って、 が必要な場合は送信者に返信する他の人(アクティブ ソケット)。これにより、工場 の労働者は新しい パケットを無料で受け取ることができます。

...

そしてチュートリアルは、接続が確立された後には残りのバイトが存在しなくなるまで、アクティブソケットがデータを受信し続けることを説明し、その後、接続を閉じます。

私が理解できなかったことは次のとおりです。ポートへの着信接続があり、送信者が20分ごとに小さなデータを送信したいとします。残りのバイトがないときにアクティブなソケットが接続を閉じると、送信者はデータを送信するたびにポートに再接続する必要がありますか?一度確立された接続を長期間維持するにはどうすればよいですか?私がここで逃していることを教えてくれますか?

私の2番目の質問は、誰が同時に動作しているアクティブなソケットの制限を決定するのですか?

+1

あなたはその記事の言い方を変えて、記事のさまざまなセクションの小片を取っています。文脈は異なっている。最後のセクションでは、著者は自分のプログラムについて説明しています。ソケットはデフォルトではそのように動作しません。実際にソケットを閉じるのを忘れてしまって、悪いことが起こる可能性があります。最後のバイトが受信されると、ソケットは自動的に閉じません。 – SRM

+0

OK、私はそれが大会だと思って、私がここで何が欠けているのか尋ねました。私はコンセプトが初めてだから、理解しにくいものはすべて質問したいのです。 – aslisabanci

+0

問題はありません。ソケットを明示的に閉じる必要があることを理解したかっただけです。それは、ソケットが閉じなかった理由を理解しようと頭を傷つけているときに、いくつかの頭痛を軽減するかもしれません:)。 – SRM

答えて

6

送信者は、接続を維持するために定期的にKEEPALIVEパケットを送信する必要があります。 KEEPALIVEの形式はプロトコルによって異なります。これは、TCPデータセグメント内の単一のNULLと同じくらい小さい場合があります。

2番目の質問については、I/Oによって異なります。 I/Oがブロックされている場合は、コンピュータ上で実行されているスレッドの数だけが必要なため、多くのクライアントを持つことはできません。ノンブロッキングであれば、より多くのクライアントを持つことができます。プログラミング言語は、ブロッキングI/OとノンブロッキングI/Oの両方をサポートする必要があります。 (私はJavaがそうしていることを知っています)。

これは、帯域幅、クライアントごとのデータ転送、メモリ、クロック速度などによっても変わりますが、ブロッキングではないブロックとブロッキングでは大きな違いがありますあなたが受け入れることができるクライアントの数。おそらく、サーバがクラッシュせずに5〜10台以上のクライアントをブロックすることはできませんが、ブロックしていない場合は、何千ものクライアントを持つことができます。

+0

毎回接続を再確立するよりも安価な操作で、これらのキープアライブパケットを20分間連続して送信していますか?再接続のオーバーヘッドを逃れること以外に、接続を維持する利点は何ですか? – aslisabanci

+1

実際にたくさんのクライアントを接続し、各リクエストが素早く(あなたの言ったように20秒間)行われるなら、リクエスト/レスポンスタイプのパターンを使用するのが最善です。 64kポートしか使用できません。つまり、ソケットが閉じられていない限り、ポートが枯渇する前に64kソケットだけをIPで受け入れることができます。それは本当にあなたのアプリケーションに依存します。たとえば、MMOを作成する場合は、永続的な接続が必要です。 HTML5を利用しているのでなければ、永続的な接続を必要としません(そして、避けようとしますが、それは別の話です)。 – SRM

+2

クライアントの観点から見ると、単一のサーバーに対する単純なキープアライブは多くの作業ではありません。インターネットに接続しているときには、おそらくすでに半分のキープアライブを定期的に送るでしょう。サーバーの観点からは、I/Oパフォーマンスを向上させるために、ソケットリスト内のソケット数を最小限に抑えることが有効です。データ転送の待機時間が20分の場合は、毎回新しい接続を作成します。それはクライアントにとってはごくわずかですが、サーバにとってはごくわずかです。 – ktm5124

0

最初の質問: はい、ソケットが閉じられると、オープンを実行して通信を再開する必要があります。

第2質問: があります。もしあなたが望むなら、あなたのサーバーへの64k接続を作成し、ポートの疲弊を被ります(私はそれをお勧めしません)。 ktm5124のように、すべてあなたのアプリケーションに依存します。非同期I/Oやスレッドプールを使用してクライアント要求を処理するなど、サーバーをスケーラブルにする方法はいくつかあります。

+0

してくださいWillの答えを参照してくださいhttp://stackoverflow.com/a/2332756/1418457多分あなたはTCPについて何かを誤解している – onmyway133

+0

さて、TCP/IPポートの疲労がクライアント側のものだけの場合(クライアントあたりの64kの制限サーバーあたりのポート枯渇の現実的な問題はなぜですか?タプルのすべての値を使い切ってもかまいません - 64kの数値が間違っているかもしれませんが、タプルが保持できる組み合わせの数には厳しい制限があります。組み合わせを使い果たした場合、アドレスを再利用しない限り、アドレスがなくなり(実際には一意のタプル)、接続が割り当てられず、接続は拒否されます。 – SRM

3

TCP/IP実装によって送信された実際のパケットと、プログラムとTCP/IPを実装するライブラリとのやり取りとを混同しないでください。

ソケットは、TCP/IP実装(ライブラリまたはカーネルOS)によってプログラムに提示される単なる抽象です。ソケットをパイプへの接続として可視化することができます(localIP:port-remoteIP:port)。あなたのプログラムはソケットを開き、ソケットを介してデータを通信し、リソースを解放するために必要がなくなったらソケットを閉じるかもしれません。これは正常な流れです。しかし、TCP/IP実装は、それ自体の正当な理由からソケットを閉じるかもしれません。それらの理由のいくつか:ネットワークアクセスケーブルの切断、ネットワークルーティングエラー、サーバがダウンしたなど。したがって、あなたのプログラムは、TCP/IPソケットを閉じなかったとしてもそれを見つけるかもしれない。

あなたの最初の質問は、私のプログラムが長いポーズで小さなデータセグメントを送信するとどうしますか?答えは、休止の時間と相手があなたに耳を傾けるプログラムによって決まります。ほとんどのTCP/IP実装では、信頼性の低い実際のネットワーク上で信頼できる接続を抽象化するための接続タイムアウトの概念があります。したがって、あなたのプログラムがtcp/ip timeoutよりも長く一時停止した場合、あなたのソケットはライブラリによって閉じられていて、ソケットを再オープンする必要があります。これはまた、あなたがもう一度通信を再開させる原因になるかもしれません、tcp/ip接続パイプの反対側であなたを聞くプログラムに依存します。

tcp/ipタイムアウトを増加させ、それを生き続ける方法があります。これらの設定は、ネットワーク構成の一部、サーバソフトウェアの設定、またはtcp/ipライブラリ呼び出しでKEEPALIVEパラメータを設定してソケットをオープンにしておくことを明示的に求めて行うことができます。それはまだ開いているかどうかに依存しますか? tcp/ipがソケットをオープンに保つ方法の詳細は、あなたのコードとは関係がないので、あなたを混乱させてはいけません。 TCP/IPには、多くの設定と異なるタイムアウトがあり、プログラムに安定した信頼性の高い接続を提供します。良い部分は、あなたがそれを悪用しない限り、あなたのプログラムコードから隠されています。数秒で一時停止する:)タイムアウトの設定は、信頼できるローカルネットワーク内の小さなアプリケーションではうまくいく可能性があり、高負荷アプリケーションや大陸間接続では機能しません。それぞれの特定の状況には、独自の解決策があります。

「このデータを20分ごとに送信する」というこの特定の質問では、通信ごとにソケット接続を閉じて開くようお勧めします。 1つを開く時間は1秒未満であり、コミュニケーションに影響を与えるべきではありません。その代わりに、通信プロトコルの複雑さを軽減します。レシーバーは常に新しいソケット接続で新しく始まり、必要でないときは20分かけてtcp/ip通信で両方のシステムがtcp/ip通信で自由なリソースを利用できます。

関連する問題