質問

こんにちは...作成した、さまざまな運転条件に対してサーバーを使用I/Oポート終了、winsock.また、助手、ソケット取扱いに完成。があまりないと思いますかパスユーザー定義のデータ構造のwrokerスレッド...

何を出したこれまで通過したユーザーの構造 (ULONG_PTR)&structure as の完了キーの協会-コール CreateIoCompletionPort() りませんでした。

また定義を自分の多重構造を用いCONTAINING_RECORD()このように http://msdn.microsoft.com/en-us/magazine/cc302334.aspxhttp://msdn.microsoft.com/en-us/magazine/bb985148.aspx.その働きません。(取得しまquot値の内容pHelper)

このような中、私の質問はどのようにしていただくためにデータをワークスレッドを使用WSARecv(),GetQueuedCompletionStatus()のパケットの重なり-構造?

編集:どのようにうまくいった送信"量接続-データ"なのですか。...うたのが、そのような説明は、上記リンク)が間違っている。

ここが私のコード:あり、その醜い、その試作-コード)

struct helper
    {
        SOCKET m_sock;
        unsigned int m_key;
        OVERLAPPED over;
    };


///////

SOCKET newSock = INVALID_SOCKET;
    WSABUF wsabuffer;
    char cbuf[250];
    wsabuffer.buf = cbuf;
    wsabuffer.len = 250;
    DWORD flags, bytesrecvd;


    while(true)
    {
        newSock = accept(AcceptorSock, NULL, NULL);
        if(newSock == INVALID_SOCKET)
            ErrorAbort("could not accept a connection");

        //associate socket with the CP
        if(CreateIoCompletionPort((HANDLE)newSock, hCompletionPort, 3,0) != hCompletionPort)
            ErrorAbort("Wrong port associated with the connection");
        else
            cout << "New Connection made and associated\n";

        helper* pHelper = new helper;
        pHelper->m_key = 3;
        pHelper->m_sock = newSock;
        memset(&(pHelper->over), 0, sizeof(OVERLAPPED));
        flags = 0;
        bytesrecvd = 0;

        if(WSARecv(newSock, &wsabuffer, 1, NULL, &flags, (OVERLAPPED*)pHelper, NULL) != 0)
        {
            if(WSAGetLastError() != WSA_IO_PENDING)
                ErrorAbort("WSARecv didnt work");
        }
    }

    //Cleanup
    CloseHandle(hCompletionPort);
    cin.get();
    return 0;
}

DWORD WINAPI ThreadProc(HANDLE h)
{
    DWORD dwNumberOfBytes = 0;
    OVERLAPPED* pOver = nullptr;
    helper* pHelper = nullptr;
    WSABUF RecvBuf;
    char cBuffer[250];
    RecvBuf.buf = cBuffer;
    RecvBuf.len = 250;
    DWORD dwRecvBytes = 0;
    DWORD dwFlags = 0;
    ULONG_PTR Key = 0;

    GetQueuedCompletionStatus(h, &dwNumberOfBytes, &Key, &pOver, INFINITE);

    //Extract helper
    pHelper = (helper*)CONTAINING_RECORD(pOver, helper, over);


    cout << "Received Overlapped item" << endl;
    if(WSARecv(pHelper->m_sock, &RecvBuf, 1, &dwRecvBytes, &dwFlags, pOver, NULL) != 0)
        cout << "Could not receive data\n";
    else
        cout << "Data Received: " << RecvBuf.buf << endl;

    ExitThread(0);
}
役に立ちましたか?

解決

独自の特別な目的データを完成ポートに送信できます postqueuedcompletionstatus.

I/O完了パケットは、GetQueuedCompletionStatus関数への未払いの呼び出しを満たします。この関数は、PostqueuedCompletionStatusへの呼び出しの2番目、3番目、および4番目のパラメーターとして渡された3つの値で戻ります。システムはこれらの値を使用または検証しません。特に、lpoverlappedパラメーターは、重複する構造を指す必要はありません。

他のヒント

合格おstructこのようなので作業は、イブレア城、イブレア:

helper* pHelper = new helper;
CreateIoCompletionPort((HANDLE)newSock, hCompletionPort, (ULONG_PTR)pHelper,0);
...


helper* pHelper=NULL;
GetQueuedCompletionStatus(h, &dwNumberOfBytes, (PULONG_PTR)&pHelper, &pOver, INFINITE);

編集を加えたIOデータ

を頻繁に虐待の特徴は、非同期のapiではないコピーに重なった構造体は、単に利用されている-そのために重なった構造体から返されたGetQueuedCompletionStatusのたstruct.い:

struct helper {
  OVERLAPPED m_over;
  SOCKET     m_socket;
  UINT       m_key;
};

if(WSARecv(newSock, &wsabuffer, 1, NULL, &flags, &pHelper->m_over, NULL) != 0)

更に、再度、オリジナルのサンプルだったでご鋳造が間違っている。(重複*)pHelperった手へのポインタのヘルパー構造体、その重なり部分に宣言されていた。私はしたものに変更するためのアドレスは実際の重なり部分のコードを編集なしでキャストを可能にしてくれ 私は、正しいものです。いもの移動に重なった構造体の会員のstruct.

キャデータの:

OVERLAPPED* pOver;
ULONG_PTR key;
if(GetQueuedCompletionStatus(h,&dw,&key,&pOver,INFINITE))
{
  // c cast
  helper* pConnData = (helper*)pOver;

こちら側に特に重要であることの重なった構造体の会員のヘルパー構造体、容易にするキャストの重なり※apiく、ヘルパー※実際のです。

オーバーラップ構造の使用を可能にするため、I/Oの作成/破壊/書き込みファイルのために、標準ソケットルーチン(ソケット、クローズソケット、バインド、受け入れ、接続...)を使用します。

ソケットが受け入れたり接続された後、ITサービスのセッションコンテキストに関連付ける必要があります。次に、ソケットをIOCPに関連付け、(3番目のパラメーターで)セッションコンテキストへの参照を提供します。 IOCPは、この参照が何であるかを知らず、そのことについても気にしません。リファレンスは使用するためのものであるため、GetQueuedCompletionStatusを介してIOCを取得すると、パラメーター3で指摘された変数が参照に記入され、ソケットイベントに関連付けられたコンテキストをすぐに見つけてイベントのサービスを開始できます。私は通常、ソケット宣言、重複した構造、および他のセッション固有のデータを含む(とりわけ)を含むインデックス構造を使用します。パラメーター3でcreateioCompletionportに渡す参照は、ソケットを含む構造メンバーのインデックスになります。

getqueuedcompletionstatusが完了またはタイムアウトを返したかどうかを確認する必要があります。タイムアウトを使用すると、インデックス構造を実行して(たとえば)、そのうちの1つがタイムアウトまたは何か他のものがあるかどうかを確認し、適切なハウスキーピングアクションを実行できます。

また、I/Oが正しく完了したことを確認するには、重複した構造も確認する必要があります。

IOCPにサービスを提供する関数は、個別のマルチスレッドエンティティである必要があります。システムにコアがあるのと同じ数のスレッド、またはシステムリソースを無駄にするため、少なくともそれ以上のスレッドを使用します(システム内のコアの数よりもイベントにサービスを提供するためのリソースはありませんよね?) 。

IOCPSは本当にすべての世界で最高(真実ではないほど良い)であり、「1つのソケットごとに1つのスレッド」または「1つの関数で複数ソケットリストを待つ」と言う人は誰でも話していることを知らない。前者はあなたのスケジューラを強調し、後者は投票であり、投票は常に非常に無駄です。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top