【高度で実用的なソケットネットワークプログラミング】【注意事項】サーバー伝送最適化の詳細説明

序文

すでに学校に戻っていますが、まだ授業を始めていないので、履修したコース【ソケットネットワークプログラミング上級実戦】https://coding.imooc.com/class/286.htmlを勉強します。夏休み中に開催します。今日の午後、第7章を読んだ後、少し不快に感じました。頭をかみ、先生に続いてコードを入力しました。コードを入力するプロセスはかなりあいまいでした。第7章を入力した後、私は夕方に多くの時間を費やして第7章のコードを理解しました。

私は70%から80%を理解していると感じています。特定のアーキテクチャとパッケージはおそらく理解されており、まだ理解されていないコードの詳細がいくつかあります。

以下を見る前に、セレクターとチャンネルの関係をある程度理解しておく必要があります。参照できます:https//www.jianshu.com/p/10717976c67c

1.キークラスの紹介

IoArgs:ByteBuffer操作の単純なカプセル化であり、読み取りと書き込みの開始時と開始時のコールバックインターフェイスを定義します。

IoSelctorProvider:グローバルインスタンス(実装クラスのインスタンス)はデモで維持され、このインスタンスはグローバルセレクターを保持します(下の図を参照)。

2つの主な責任があります。

(1)SocketChannelをグローバルセレクターに登録し、セレクターが保持するチャンネル(セレクターに登録されているチャンネル)の監視を維持します。

(2)別のスレッドを開始して、Selctorが保持するすべてのチャネル(Selectorに登録されているチャネル)をポーリングします。チャネルが読み取り可能または書き込み可能である場合、対応するコールバック関数(Runnable)は、SelectionKeyを介してグローバルCallbackMapから取得され、スレッドプールによって実行されます。

SocketChannelAdapter:メッセージを非同期で送受信する機能があり、チャネルが読み取り可能または書き込み可能である場合のコールバックを定義します。このコールバックでは、IoArgsオブジェクトと対話し、処理されたIoArgsが外部コネクタにコールバックされます。

 

量。テキストを見るだけでも、非常に抽象的で淡い感じがします。しかし、私は一般化するために非常に一生懸命努力しました。

2.デモアーキテクチャ図とメインプロセス分析

写真はよりカジュアルで、表現しにくいものもあります。

ServerSocketは1つしかないので、とりあえず「サーバー」と比較します。TCPServerでは、ServerSockerChannelのACCEPTイベントはセレクターを介して監視されます。接続するクライアントがある場合は、クライアントに対応するSocketChannelを取得します(「client」と同様)。そして、ClientHandlerをビルドし、対応するClientHandlerをグローバルリストに配置します。


ClientHandlerの文字通りの意味は、理解しやすいです。クライアントプロセッサです。クライアント接続と同じ数のClientHandlerがあります。対応するクライアントの読み取りおよび書き込み操作を処理する責任があります。そのコンストラクターにはコネクターのセットアップ操作が含まれているため、オブジェクトの構築時にクライアントの登録と監視が開始されます。


IoSelectorProviderをもう一度見てみましょう。教師の第7章の終わりに、このクラスに関連する書き込みはまだ完了していません。以下では、このクラスを理解するために関連する読み取りについてのみ説明します。最初に強調する価値があるのは、IoSelectorProviderにはグローバルに1つのインスタンスしかないということです。

このインスタンスはグローバルReadSelectorを保持し、ReadSelectorはイベントを読み取るために保持するすべてのチャネル(ReadSelectorに登録されているすべてのチャネル)を担当します。

この例には、グローバルなinputCallbackMapもあります。これも重要な役割です。グローバルReadSelectorと各SocketChannelの間の関係(登録後に生成される関係)は、対応するSelectionKeyによって識別できることがわかっています。SocketChannelが読み取り可能である場合、対応するコールバック(HandleInputCallback)を実行する必要があります。したがって、SocketChannelが登録されると、各SocketChannelが読み取り可能になったときにトリガーされたコールバックがマップに保存されます。

SocketChannelが読み取り可能である場合、対応するコールバック(HandleInputCallback)を実行する必要があります。このコールバックは、統合実行のためにグローバルスレッドプールinputHandlePoolに渡されます。このHandleInputCallbackは、主にSocketChannelからIoArgsへのデータの読み取り、およびロードされたデータのIoArgsを外部コネクタにコールバックする役割を果たします。

3.コードと組み合わせたプロセス分析

上記では、基本的なアーキテクチャ図と組み合わせて、デモの主要なクラスの概要を示し、各クラスの役割と主要な実行プロセスを一般的に理解しています。以下は、コードと組み合わせたプロセス全体の分析です。コードを完全に理解した場合にのみ、デバッグして二次的な変更を加えることができます。

ここでは、第7章で変更されたコードについてのみ説明します。

サーバーのエントリクラスがServerであることは間違いありません。上のスクリーンショットのコードの機能は、新しいグローバルIoSelectorProviderインスタンスを作成し、それをグローバルコンテキストIoContextに配置することです。

 

ReadAndPrint操作は、TCPServerの上部の水平線から削除されます。これは、関連する責任が、対応するクライアントの読み取りおよび書き込み操作の処理を単独で担当するClientHandlerに引き継がれるためです。そのコンストラクターにはコネクターのセットアップ操作が含まれているため、オブジェクトの構築時にクライアント(SocketChannel)の登録と監視が開始されます。

 

ClientHandlerのコンストラクターも、主にコネクターとセットアップを構築するために上記で説明されています。

 

これを見ると、次のことがわかります。クライアントの数は、コネクタやSocketChannelAdaptersの数と同じ数のClientHandlerです。ここでreadNextMessageメソッド注目してくださいreadNextMessageメソッドは、コールバックインターフェイスechoReceiveListenerで実行されます (次の図を参照)。どうして?これは、IoSelectorProviderまでさかのぼる必要があります。

 

水平線の問題について考えてください。答えを以下に示します。

グローバルIoSelectorProviderが(コンストラクターで)作成されると、startReadメソッドが実行されます。このメソッドでは、別の個別のスレッド(優先度が高い)が有効になり、ReadSelectorが保持するすべてのチャネルをポーリングし、読み取り可能なイベントをリッスンします。上記の説明も記載されています。読み取り可能なチャネルがある場合、対応するHandleInputCallbackはSelectionKeyを介して取得され、グローバルスレッドプールinputHandlePoolによって実行されます。次に、コールバックHandleInputCallbackの実行中に、SocketChannelを監視する必要はありません。HandleInputCallbackは、チャネルからIoArgsにデータを読み取ることであり、SocketChannelが読み取られているため、読み取り可能かどうかを監視する必要がありますか?したがって、handleSelectionメソッドでは、チャネルの監視を一時的にキャンセルします。これにより、ポーリング全体の効率が向上します。

ここで監視をキャンセルしないと、バグが発生します。スレッドプールがビジーであるため、チャネル読み取り可能イベント(メッセージの到着時)がタイムリーに処理されないため、
処理されているがチャネルのポーリング(選択)時に完了していないチャネル読み取り可能イベントの処理が繰り返され、悪性度が発生します。ループして、スレッドプールをよりビジーにします。

では、SocketChannelの監視はいつ再開されますか?

次に、一連のコールバックをトレースする必要があります。

HandleInputCallbackは、SocketChannelからIoArgsにデータを読み取り、ロードされたデータのIoArgsを外部コネクタにコールバックします。コネクタはデータを出力し、readNextMessageを再度呼び出しますこのメソッドに戻ると、最終的にIoSelectorProviderのregietrSelectionメソッドで監視が復元されることがわかります。(下記参照)。

さて、コード全体の私の理解は私の能力の及ぶ限りでは表現されました。いくつかのコードの詳細(さまざまなロックなど)がありますが、私はまだそれを理解していません。エラーがあれば訂正してください。

おすすめ

転載: blog.csdn.net/qq_43290318/article/details/108395386