0

IOCP サーバーを作成しようとしています。基本的に、新しい接続を受け入れるようにしています。テストの目的で、127.0.0.1 を実行して接続しています。

AcceptEx() を呼び出す前に、疑似ソケットを作成します。接続が受け入れられると、新しい疑似ソケットが通信に使用されます。この新しいソケットは io 完了ポート [CreateIoCompletionPort] に関連付けられ、[SO_EXCLUSIVEADDRUSE] と [SO_CONDITIONAL_ACCEPT] といういくつかのオプションを割り当て、WSARecv() を呼び出して着信データを受け入れます。

問題は、リモート接続がサーバーに接続すると、データは送信されますが、そのデータが受信されないことです。データを受信して​​いない理由について誰かがアイデアを提供できるかどうか疑問に思っていますか? 私の論理が間違っているのではないでしょうか?コードを数回実行しました。エラーは記録されません。

編集:文言を修正しました。AcceptEx() 呼び出しの前にソケットを作成します。

私のコードの基本的なロジック:

// Create socket, associate with IOCP
WSASocket(af, type, proto, lpProtoInfo, g, dwFlags);
HANDLE hIOCP = GetPool()->GetQueueHandle();
CreateIoCompletionPort(hSource, hIOCP, 0, 0) != NULL;

// Server bind and listen
bind(m_shSocket, pAddr, nAddrLen);
listen(m_shSocket, nBacklog);

// Creation of the pseudo socket
SOCKET s = ::WSASocket(m_iSocketAf, m_iSocketType, m_iSocketProto, m_pWpi, m_SocketGroup, m_dwSocketFlags);

DWORD dwBytes;
BOOL bRet = m_fnAcceptEx(m_shSocket, s, chOutput, 0, sizeof(SOCKADDR_STORAGE) + 16, sizeof(SOCKADDR_STORAGE) + 16, &dwBytes, m_pcbAccept);

// ... New Connection comes in, it's accepted ...

// Associate new pseudo socket with IOCP
HANDLE hNewIOCP = GetPool()->GetQueueHandle();
CreateIoCompletionPort((HANDLE) s, hNewIOCP , 0, 0) != NULL;

// ... Remote socket sends ...
// ... Remote socket and Pseudo socket call WSARecv ...
// ... Pseudo socket does not receive ...

注: 疑似ソケットからリモート ソケットに送信しようとしましたが、データを逆に送信するのと同じ問題がありました。

4

3 に答える 3

1

コードを投稿する必要がありますが、説明が意味をなしません。これは、AcceptEx()ベースサーバーの動作方法ではありません。

ベースサーバーでは、AcceptEx()を投稿する前に、受け入れられたソケットを作成しますAcceptEx()AcceptEx()次に、リスニングソケットと新しいソケット、およびリモートアドレスとオプションでデータを受信できるようにするバッファを使用して投稿します。

したがって、元の質問でコードを説明している場合は、コードが間違っているか、を使用していませんAcceptEx()。私は現在、分析するコードがなくても現在のところさらに混乱しているため、ミックスに投入する「いくつかのオプション」を無視しています。

私の無料のIOCPベースのサーバーフレームワークをダウンロードすることに興味があるかもしれません。これには、動作中AcceptEx()の従来Accept()のベースのサーバーコードが含まれています。ここから入手できます:http ://www.serverframework.com/products---the-free-framework.html

于 2010-12-22T08:31:25.923 に答える
0

私はそれを考え出した。私はアホです。ゼロバイトを送信していました。

于 2010-12-22T13:34:11.783 に答える
0

データを取得するためにGetQueuedCompletionStatusを呼び出していますか?

自分で学習するためだけにこれを行っていない場合は、boost::asioを使用することもお勧めします。これは、io 完了ポートを処理するための面倒なコードを他の人に任せることができる優れたライブラリです。

于 2010-12-21T23:30:47.507 に答える