1. アーキテクチャの説明 現在のプロトコルには次の特徴があります。
1) クライアントはサーバーにリクエストを送信します。各リクエストの長さは最初の INT で指定されます。
2) 通常、各サーバーは複数のクライアントにサービスを提供します。たとえば、TS は CP と NP に同時にサービスを提供する必要があります。
CP は NP および他の CP にサービスを提供し、他の CP、TS、および SP のクライアントでもあります。
3) 各サーバーがクライアントにサービスを提供する場合、通常は長時間にわたり、複数回の要求と応答のやり取りが発生します。
このような構造は、主に多数のクライアントの同時接続をサポートするように設計されています。同時クライアントの接続数が多い場合、スレッドまたはプロセスのどちらを使用しても効率的なサービスを提供できないため、select を使用する必要があります。
ポーリングモード。
2. 基本的なデータ構造の説明: 各クライアントについて、現在の CPnew.c、SPnew.c に対応するいくつかの情報を保存する必要があります。
これは基本的に TSnew.c のコア データ構造と同じであり、Session、
これは、SessionCluster (TSnew.c 内) または ServerDesc (CPnew.c および SPnew.c) で構成されます。
このうち、Session は各クライアントに関するデータであり、SessionCluster (または ServerDesc) は各サービスに関する情報であり、サービスに関連する各 Session へのポインタを持ちます。
このデータ構造は、クライアント要求があるときに動的に割り当てられるのではなく、最初の初期化時に割り当てられます。新しいクライアント要求が来ると、サーバーはこれらの事前に割り当てられたセッションを検索し、いくつかのアイドル状態のセッションを見つけて使用します。アイドル時間がない場合はエラーを報告します。
TS と CP(SP) の最大の違いは、TS は UDP プロトコルを使用するのに対し、CP と SP は TCP プロトコルを使用することです。両者の違いは次のとおりです。
1) TCP プロトコル クライアントの場合、各クライアントは異なるソケットを使用するため、選択後、各クライアントの fd_set が設定されているかどうかを確認するだけで済みます。UDP クライアントの場合は、TS が使用する対応するクライアントを見つける必要があります。検索によって生じるオーバーヘッドを軽減するためのいくつかの措置。
2) TCP プロトコルでは、送信されるデータはストリーム形式であるため、メッセージをブロックに分割する必要がある場合、1 回の読み取りで 2 つのメッセージを読み取るか、メッセージを何度も読み取る必要がある場合があります。したがって、各セッションには、読み取られたがまだ処理されていないメッセージを保存するために使用される buf、rstart、および rlen があります。
同様に、書き込み処理中も一度に書き込みが完了しない可能性があることを考慮する必要があるため、wbuf、wstart、wlen もセッションごとに保持する必要があります。これは UDP のプロトコルで異なります。実装では、各 UDP パケットに含まれるメッセージがすべて完了していると想定されているため、これらの項目は含まれません。
SessionCluster (または ServerDesc) は、いくつかの主要な部分で構成されるサービスを記述します。
1) ソケット: 使用されるソケットを説明します。
2) cur: 現在のクライアントの数
3) max: 収容できるクライアントの最大数
4) head: セッションの先頭、head[0] は最初のセッション、head[max-1] は最後のセッション
5) init: このサービスの各セッションで実行する必要がある初期化操作 (関数ポインター)。
6) process: 本サービスにおけるメッセージの処理機能
7) クロージャ: このサービスに必要なデストラクタ
3. 主な構造の説明
process_child: main 関数。この関数は主に、socks と wsocks を設定するために使用されます。SP および CP の場合、wsocks はセッションの wlen > 0 の場合にのみ設定されます。
選択します。
各 ServerDesc (または SessionCluster) の process_type
SP および CP では、PUSHLIST 操作をサポートするために、各サイクルの前に processJob を実行する必要があります。
CP では、TS 内の期限切れの接続をクリアするために periodCheck も定期的に実行され、期限切れの顧客接続をクリアするために periodLog も定期的に実行されます。
プロセスの種類:
セッションごとに、読み取り可能かどうかを確認し、読み取り可能な場合は、完全なメッセージがあるかどうかを確認します。
*(unsigned int *)(rbuf+rstart) <= rlen
完了メッセージが表示されなくなるまで対応するプロセスを呼び出して書き込み可能かどうかを確認し、書き込み可能で wlen>0 の場合は書き込みます。
4. その他の重要なモジュール
1) 設定モジュール 設定モジュールは主に struct NamVal、read_config、free_config で構成されます。NamVal 構造体では、
Name は cfg ファイル内の名前、ptr はストレージへのポインタ、type はデータのタイプです。 現在、次のタイプがサポートされています。
d: 整数型、ptr は整数ポインタ
s: 文字列型、ptr はポインタへのポインタ、(char **)
b: 文字列バッファ型。ptr は char * です。この型を使用する場合は注意が必要です。s 型の場合、
read_config は val にメモリ (malloc) を割り当てますが、タイプ b の場合、ptr は割り当てられたメモリを指す必要があります。
2 つの重要な機能は次のとおりです。
read_config のパラメータは、ファイル名、構造体 NamVal *、構造体 NamVal の項目数です。
free_config、パラメータは read_config と同じ struct NamVal * と項目数です
2) mysqlモジュール
mysql モジュールは主に MYSQL *local_mysql と 3 つの関数で構成されます。これらの 3 つの関数は次のとおりです。
init_mysql、mysql を初期化し、MYSQL * を返します。通常、local_mysql を初期化するために使用されます。
query_mysql、mysql ステートメントを実行します。形式は query_mysql (local_mysql、"mysql ステートメント、
形式は printf と同じです (%s から削除するなど)。"、必須の値)
query_mysql_select、mysql select ステートメントを実行します。上記とは異なり、
MYSQL_RES *.
3) ネットワークソートモジュールは、主にネットワーク構造、readNETBLOCK 関数、getnetwork 関数、compareNet 関数で構成されます。
readNETBLOCK は、ネットワーク構成ファイルを読み取り、グローバル変数 NETBLOCKS を初期化するために使用されます。
MAX_NET 項目を含むネットワーク構造の配列。
getnetowrk は、IP アドレスに最も近いネットブロックを見つけるために使用されます。
CompareNet は、同じネットワーク内の NPPeer が最初にランク付けされるように、見つかった NPPeer を並べ替えるために qsort で使用される関数です。
4) グラフ管理 現在の CP、SP、NP では、CP は同時に複数のチャネルに参加でき、NP も複数のリソースを持つことができます。この構造を説明するために、各エッジ (Edge) の概念が導入されています。 ) が格納されます NP へのポインタ、Channel へのポインタ、
TS では、このセッションの各インターバルをこのチャネルに保存する必要もあります。各チャネルはエッジを通過します。
cnext はリンク リストに連結され、このリンク リストの先頭はチャネル構造の PeerHead であり、各セッションです。
Edge の enext もリンク リストに連結されており、このリンク リストの先頭がセッション構造のヘッダーになります。
関連する機能は次のとおりです。
newEdge: 新しいエッジを追加します。パラメータは Channel *、Session * です。TS の場合、Edge の情報を初期化するために ChannelInfo が必要です。
delEdge: エッジを削除します。パラメータは Edge * です。
5) チャネルモジュール
Channel モジュールの主な機能は次のとおりです。
TS は NEED_PEERS の処理に使用され、SP はチャネル データの保存と検索も必要であり、チャネルはグラフ構造を使用して管理されます。
チャネル検索では効率上の理由からハッシュを使用します。ChannelHash は文字列を使用します。
hash_str に示されているハッシュ。
TS のチャネルは比較的単純ですが、SP および CP のチャネルも、ファイルの形式でハードディスク上の /var/tmp/ ディレクトリに保存されます。関連情報ごとに、
BlockData によって保存される BlockData の firstsampl、message_size、message_id、および offset は、それぞれ firstsampl 情報、ブロック長、ブロック ID、およびオフセットをファイルに保存します。
SP と CP の処理は異なります。CP の場合、ブロックはハッシュ モードで保存されます。一方、ブロック ID は 1000 です。
max_queue が 100 の場合、SP の場合、リソースが CS によって送信されたチャネルの場合、保存場所は 1000%100=0 になります。
循環キューとなっており、各ブロックはキューの末尾に達すると、キューの先頭から順番に格納されます。リソースがファイルの場合、BlockData 情報は保存されません。元のファイルは blockID に従って直接配置されます。
チャネルに関連する関数は数多くあります (locate_by_id、locate_order_by_id、newChannel、
freeChannel、saveBlockなど
6) Berkeley DB モジュールは SP にのみ関与し、主に DB ファイルを開き、特定の md5 の場所をクエリします。
openDB と openMedia の 2 つの関数
openDB: パラメータは DB ファイルの名前です。
openMedia: パラメータは md5 と整数ポインタで、FILE * と整数ポインタ内のファイルの長さを返します。
7) ジョブモジュール
Job モジュールは CP および SP で PUSHLIST を処理するために使用され、PUSHLIST メッセージはジョブ リストをリセットできます。
ジョブを追加したり、ジョブを削除したりすることもできます。これには、job.c の関数と、JobDes 構造体の Session * および Channel * が、ジョブが属するセッションとチャネルを識別するために使用されます。 num はダウンロードする必要がある BlockID の数を表し、job は整数へのポインタ、mask も整数へのポインタです。
job[i] はダウンロードする必要がある BlockID です。mask[i] が 0 の場合はダウンロードする必要があり、1 の場合はダウンロードする必要はありません。
addJob: ジョブを追加するとき、そのジョブがすでにリストに存在するかどうかはチェックされませんが、ジョブを直接生成し、リンクされたリストに追加します。
deleteJob: ジョブを削除するときは、ジョブ リスト内のすべてのジョブで同じセッションとチャネルを持つジョブを確認します。
次に、削除する必要があるブロック ID の対応するマスクを 1 に設定します。
processJob: cur から始まる各ジョブについて、process_P2P_REQUEST_real を使用して、マスク 0 で最初のブロックを送信します。それらがすべて 1 の場合は、ジョブを削除します。
freeJob: JobDes を削除します。
freeJobList: セッションのすべての JobDe を削除します。通常はセッションが終了するときに使用されます。
8) インターバルモジュール
間隔モジュールは、NP 上のすべての高速間隔を表すために TS で使用されます。現在、ブロック間隔は開始フィールドと長さフィールドによって識別されます。間隔の主な操作はマージと削除です。
元の間隔リストと新しい間隔リストを結合しますが、削除では元の間隔リストから新しい間隔リストが削除されます。
マージ: バッファー間隔リスト tmp を使用するアルゴリズムは次のとおりです。
if (old[i] < new[j]) tmp[k] = old[i];
それ以外の場合は tmp[k] = new[j];
次に、新旧どちらを tmp[k] とマージできるかを調べます。
delete: はより複雑です。次の状況を考慮してください。
old[i] の始まりが new[j] の終わりより大きい
old[i] の終わりは new[j] の始まりより前にあります
old[i] と new[j] には共通部分があり、
old[i] は new[j] に含まれます
new[j]はold[i]に含まれ互いに含まず、new[j]は前のものに含まれ互いに含まず、old[i]は前のものに含まれます。
5. いくつかの高速アルゴリズム
1) UDP を使用する TS では、クライアントが初めてログインするときに、アイドル状態のセッションを見つける必要があります。また、この場合、クライアントは LOGIN メッセージを繰り返し送信する可能性があります。第三に、クライアントはメッセージを送信するときに、対応するセッションを見つける必要があります。
これらのクエリを回避するために、それぞれ以下の方法が使用されます。
まず、Hash テーブルを作成します。最初は、すべての空きセッションが Hash[0] にリンクされます。このため、新しいクライアントが来るたびに、セッションが Hash[0] に関連付けられます。ハッシュによって取得される値を 0 にすることはできません。0 の場合は、可能な最大の ハッシュ ID が返されます。
送信元ポートと IP アドレスに基づいてセッションをクエリする場合も、このハッシュ テーブルが使用されます。
クライアントはメッセージを送信するときに、検証に使用される 7 バイトのうちの最初の 3 バイトを使用し、これらの 3 バイトを使用してセッションを識別します。
これにより、クエリのオーバーヘッドが回避されます。
2) maxid を使用して検索数を減らします。
TCP ではハッシュは使用されません。maxid 項目は、セッション内の最大の ID を記録するために使用されます。
初期化中に、最小の ID を持つアイドル状態のセッションが検索されるため、セッションは比較的コンパクトであると考えることができます。
SP および CP は TS よりもはるかに少ないクライアントをサポートするため、この扱いは許容されます。
顧客が終了すると、maxid の更新が必要になる場合があります。この更新は Clientclosure によって完了します。
Clientclosure は maxid を更新し、対応するデストラクターを呼び出します。
3) 長期アイドル接続のタイムアウト処理 タイムアウト処理では、システム リソースを節約するためにリスト全体をスキャンする必要があります。
また、IDLE には時間がかかります。また、システム統計は定期的に報告する必要があるため、適時性が求められます。
一般に、periodLog または periodCheck は、2 つの操作のどちらを実行するかを決定します。
4) CPPeer をクエリするとき、現在 GCP のみがサポートされていることを考慮して、GCPCHOICE が直接使用され、現在の負荷が最も小さい GCP に設定され、GCP がレポートするか、GCP がログインおよびログアウトするときに更新されます。
6. メッセージ処理
1) TSメッセージ処理
NP2TS_LOGIN: NP は TS にログインし、送信元 IP アドレスと報告された npport に従ってハッシュします。NP2TS_LOGIN メッセージが最後に送信されてからの時間が SILENCE_TIME 未満の場合は、直接戻ります。それ以外の場合は、WELCOME メッセージが送信されます。
NP2TS_REPORT: レポート間隔情報。refresh が true の場合、リセットされます。それ以外の場合は、最初に追加されてから削除されます。
NP2TS_NEED_PEERS: ピア情報をクエリします。findCPPeer を使用して適切な CP を見つけます。findNPPeers を使用します。
適切な NP を検索します。NP を検索する場合、結果が見つかった後、同じネットワーク内のものが最初にランクされるようにネットワークごとに並べ替えられます。
NP2TS_LOGOUT: 終了
NP2TS_RES_LIST: 現在の NP のすべての RESOURCE を送信し、処理に addSession を使用します。このエッジがまだ存在しない場合は追加します。
NP2TS_REQ_RES: RES を追加し、ピアを返します
NP2TS_DEL_RES: RESの削除
CP2TS_REGISTER: ログインします。CP は TS にログインし、送信元 IP アドレスと報告された npport に従ってハッシュします。
前回 CP2TS_REGISTER が送信されてから ILENCE_TIME が経過している場合は直接戻り、それ以外の場合は送信します
ようこそメッセージ。
CP2TS_UPDATE: CP 負荷のレポート
CP2TS_NEED_PEERS: ECP クエリに使用されますが、まだ使用されていません
2) SPメッセージ処理
P2P_HELLO: チャンネルに参加し、
チャネルが存在する場合、それがメディア ファイルの場合: このチャネルの最小および最大のブロック ID を示す SPUPDATE を返します。
それ以外の場合: このチャネルが終了している場合は、終了情報を返します。チャネルが存在しない場合、メディア ファイルの場合は、このチャネルの最小および最大の blockID を示す SPUPDATE を返します。それ以外の場合は、SPUPDATE を返します。エラーを示します。
P2P_PUSHLIST: タスク リストをリセットまたは追加または削除します。リセットする場合は、最初に関連するタスクをすべて削除してから、追加または削除します。
CS2SP_REGISTER: チャネルの作成
CS2SP_UPDATE: チャネル情報を更新します
CS2SP_BLOCK: 送信データブロック
3) CP メッセージ処理
P2P_HELLO: チャネルに参加し、指定された SP アドレスに基づいて対応する接続を確立します。
P2P_PUSHLIST: タスクリストのリセットまたは追加および削除
P2P_SPUPDATE: SP によって送信された SPUPDATE がメディア ファイルの場合、NP には転送されません
P2P_RESPONSE: SP によって送信されたデータ ブロック。
さらに、CP も TS に登録する必要があります。
現在、1 種類の GCP のみが使用されています。
拡大する