0

過去数日間、私は自分が直面している問題の 1 つを解決する方法を考えていました。そのトピックについて調査しようとしましたが、何ができるか本当にわかりません。

同じ構造体に 2 つのソケットがあり、両方とも同じ完了ポートを持っています。問題は、両者が異なるプロトコルを使用していることです。どのソケットがトリガーされたかを確認する方法はありますか? 呼び出された game_socket と client_socket

サンプルコードは次のようになります...

while (true) {
error = GetQueuedCompletionStatus(CompletionPort, &BytesTransfered, (PULONG_PTR)&Key, &lpOverlapped, 0);
srvc = CONTAINING_RECORD ( lpOverlapped, client , ol );
if ( error == TRUE ) {
cout << endl << "SOCKET: [" << srvc->client_socket << "] TRIGGERED - WORKER THREAD" << endl;
cout << endl << "BytesTransfered: [" << BytesTransfered << "]" << endl;

if ( srvc->game_client triggered ) {
// .. this code
} else {

// .. this code
}

アイデアや助けをいただければ幸いです:)

4

2 に答える 2

4

IOCP を使用する場合、非同期操作ごとに使用できるユーザー データの項目が 2 つあります。

1 つ目は、「接続ごと」のデータである完了キーであり、ソケット/ファイル ハンドルと既存の完了ポートを使用して CreateIoCompletionPort() を呼び出して、ファイル ハンドルまたはソケットを完了ポートに関連付けると設定されます。この値は、特定の接続で GetQueuedCompletionStatus() を呼び出すたびに返されます。

2 つ目は、「操作ごと」のデータである「拡張オーバーラップ」構造です。各同時操作には、固有のオーバーラップ構造が割り当てられている必要があります。

上記の設計では、接続を識別するために「接続ごと」のデータを使用する必要があります。リンクされた 2 つの接続 (ソケット) があるので、接続の両側に 1 つずつ、2 つのリンクされたクラスがあります。クラス (C++ ではなく C を使用している場合は構造体) は、ソケット、接続の残りの半分へのポインター、および接続の種類を示すフラグを保持します。C++ を使用している場合、これら 2 つのクラスは共通の基本クラスから派生するため、メンバー関数を呼び出して、完了キーが表す接続の種類を判別できます。C を使用している場合は、判別共用体を使用します。

次に、完了キーをベースにキャストし、どの接続タイプを使用しているかを判断し、正しいクラス/構造体にキャストするだけです。これで、操作が実行された接続がわかります。接続クラスは、そのプロトコルを実行するステート マシンのすべての状態を格納できます。

Criagが言及しているように、オーバーラップした各構造は「操作ごとに一意」であり、私のIOCPコードでは、操作のデータバッファへのアクセスと、操作が何であったかを示すフラグ(読み取り/書き込み/受け入れ/接続など)を許可する傾向があります)。

潜在的な複雑さの 1 つは、それを使用するすべての未処理の操作が完了するまで、操作ごとおよび接続ごとのデータを維持することです。個人的には、接続ごとのデータと操作ごとのデータの両方の参照カウントを好みますが、他の方法があると確信しています。

これらの概念を使用する IOCP のサンプル コードがあります (ただし、「2 つの接続」の例は提供されていません)。ここからダウンロードできます: http://www.serverframework.com/products---the-free-フレームワーク.html

于 2012-09-05T08:21:35.650 に答える
2

使用しているオーバーラップされた拡張構造は、特定の接続インスタンスに最適です。たとえば、その構造には、操作が実行されているソケットだけでなく、アクションも含まれている必要があります。たとえば、読み取りまたは書き込みが可能なソケットでのIO完了は、IO要求が開始されたときに存在していた状態を反映する必要があります。IOCPベースのクライアント/サーバーコードのほとんどの例は、この一般的なイデオロギーを証明します。

あなたの場合、2つの潜在的に独立したアクションを持つ2つの異なるソケットに同じOVERLAPPED構造を使用するべきではありません。ソケットがある意味で「関連」している場合は、OVERLAPPED構造の外部で追跡および保守する必要があります。それぞれが、独自のIO補完のために独自の構造を持つ必要があります。他の何かは正直に頭痛を求めています。

そうは言っても、あなたのユースケースは、私が説明していることに対応するために現在のスキームを変換することから遠く離れているようには見えません。私は自分で聞くのがまったく嫌いなので、「そのようにすべきではない」と答えるのはいつも気が進まないが、それでもこの場合は正当化される可能性が高い。

ではごきげんよう。

于 2012-09-03T03:54:53.770 に答える