12

特定の実装の詳細について (まだ) 尋ねているわけではなく、何が起こっているのかについての一般的な概要を尋ねているだけです。ソケットの背後にある基本的な概念を理解しており、プロセス全体を明確にする必要があります。私の(おそらく非常に間違った)理解は現在これです:

ソケットは、(独自のスレッドで) 接続したいクライアントを常にリッスンしています。接続が発生すると、別のスレッドを生成して接続プロセスを実行するイベントが発生します。接続プロセス中に、クライアントにはサーバーと通信するための独自のソケットが割り当てられます。次に、サーバーはクライアントからのデータを待ち、データが到着するとイベントが発生し、ストリームからデータをバッファーに読み取るスレッドが生成されます。

私の質問は次のとおりです。

私の理解はどのように外れていますか?

各クライアント ソケットは、データをリッスンするために独自のスレッドを必要としますか?

データはどのように正しいクライアント ソケットにルーティングされますか? これは、TCP/UDP/カーネルの内臓によって処理されますか?

このスレッド化された環境では、通常、どのような種類のデータが共有されていますか?また、競合のポイントは何ですか?

明確化と追加の説明をいただければ幸いです。

編集:

どのデータが一般的に共有されているか、および競合のポイントに関する質問に関しては、これは接続の受け入れとデータの送受信の一般的なプロセスに関する質問ではなく、実装の詳細であることに気付きました。いくつかの実装 (SuperSocket と Kayak) を調べたところ、セッション キャッシュや再利用可能なバッファー プールなどの同期がいくつかあることに気付きました。この質問は無視して構いません。皆様のフィードバックに感謝いたします。

4

2 に答える 2

16

接続ごとに 1 つのスレッドは悪い設計(スケーラブルではなく、過度に複雑) ですが、残念ながらあまりにも一般的です。

ソケット サーバーは、多かれ少なかれ次のように動作します。

  • リスニング ソケットが接続を受け入れるようにセットアップされ、ソケットセットに追加されます。
  • ソケット セットのイベントがチェックされます
  • リッスンしているソケットに保留中の接続がある場合、接続を受け入れることによって新しいソケットが作成され、ソケット セットに追加されます。
  • 接続されたソケットにイベントがある場合、関連する IO 関数が呼び出されます
  • ソケット セットのイベントが再度チェックされます

これは 1 つのスレッドで発生し、接続された何千ものソケットを 1 つのスレッドで簡単に処理できます。スレッドを導入してこれをより複雑にする正当な理由はほとんどありません。

while running
    select on socketset
    for each socket with events
        if socket is listener
            accept new connected socket
            add new socket to socketset
        else if socket is connection
            if event is readable
                read data
                process data
            else if event is writable
                write queued data
            else if event is closed connection
                remove socket from socketset
            end
        end
    done
done

IP スタックは、どのパケットがどの「ソケット」にどの順序で送信されるかのすべての詳細を処理します。アプリケーションの観点から見ると、ソケットは信頼性の高い順序付けられたバイト ストリーム (TCP) または信頼性の低い順序付けられていないパケットのシーケンス (UDP) を表します。

編集:更新された質問への回答。

あなたが言及したライブラリのどちらも知りませんが、あなたが言及した概念について:

  • 通常、セッション キャッシュはクライアントに関連付けられたデータを保持し、このデータを複数の接続で再利用できます。これは、アプリケーション ロジックが状態情報を必要とする場合には理にかなっていますが、実際のネットワーク エンドよりも上位のレイヤーです。上記のサンプルでは、​​セッション キャッシュは「プロセス データ」部分で使用されます。
  • バッファー プールは、トラフィックの多いサーバーの最適化としても簡単で、多くの場合効果的です。この概念は非常に簡単に実装できます。読み取り/書き込みデータを格納するためのスペースを割り当て/割り当て解除する代わりに、事前に割り当てられたバッファーをプールからフェッチし、それを使用してからプールに返します。これにより、(時には比較的高価な) バックエンドの割り当て/割り当て解除メカニズムが回避されます。これはネットワーキングとは直接関係ありません。たとえば、ファイルのチャンクを読み取って処理するものにバッファ プールを使用することもできます。
于 2011-03-11T00:25:23.963 に答える
1

私の理解はどのように外れていますか?

かなり遠い。

各クライアント ソケットは、データをリッスンするために独自のスレッドを必要としますか?

いいえ。

データはどのように正しいクライアント ソケットにルーティングされますか? これは、TCP/UDP/カーネルの内臓によって処理されますか?

TCP/IP はプロトコルの層の数です。それに「カーネル」はありません。それはピースであり、それぞれが他のピースへの個別の API を備えています。

IP アドレスはその場で処理されます。

ポート番号は別の場所で処理されます。

IP アドレスは、特定のホストを識別するために MAC アドレスと照合されます。ポート番号は、TCP (または UDP) ソケットを特定のアプリケーション ソフトウェアに結び付けるものです。

このスレッド化された環境では、通常、どのような種類のデータが共有されていますか?また、競合のポイントは何ですか?

どのスレッド環境?

データ共有?何?

競合?物理チャネルは、最大の争点です。(たとえば、イーサネットは衝突検出に依存します。)その後、コンピュータ システムのすべての部分は、複数のアプリケーションによって共有される希少なリソースであり、競合のポイントになります。

于 2011-03-11T00:25:45.050 に答える