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

您是否正在调用GetQueuedCompletionStatus来获取数据?

如果您不是为了自己学习而这样做,我还建议您使用boost::asio - 一个优秀的库,它允许您让其他人完成繁琐的代码来处理 io 完成端口。

于 2010-12-21T23:30:47.507 回答
0

我想到了。我是个白痴。我正在发送零字节。

于 2010-12-22T13:34:11.783 回答