在接受后 TCP IOCP 不会收到

Posted

技术标签:

【中文标题】在接受后 TCP IOCP 不会收到【英文标题】:TCP IOCP won't receive after acceptex 【发布时间】:2010-12-21 22:40:14 【问题描述】:

我正在尝试编写一个 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 ...

注意:我尝试从伪套接字发送到远程套接字,与以相反方式发送数据的问题相同。

【问题讨论】:

你需要发布你的代码来得到答案 是的...请发布您的代码...听起来您正坐在防火墙后面或未接电话或未绑定到您服务器上的知名端口...或忘记打电话GetQueuedCompletionStatus 【参考方案1】:

您需要发布一些代码,但您的描述没有意义。这不是基于 AcceptEx() 的服务器的操作方式。

使用基于AcceptEx() 的服务器,您可以在发布AcceptEx() 之前创建您接受的套接字。然后,您将AcceptEx() 与侦听套接字和新套接字以及允许您接收远程地址和可选数据的缓冲区一起发布。

因此,如果您在原始问题中描述您的代码,那么您的代码是错误的,或者您没有使用AcceptEx()。我目前忽略了您混入其中的“少数选项”,因为它们只会进一步混淆目前没有任何代码可分析的事情。

您可能有兴趣下载我的free IOCP based server framework,其中包括基于AcceptEx() 和传统Accept() 的服务器代码。你可以从这里得到它:http://www.serverframework.com/products---the-free-framework.html

【讨论】:

【参考方案2】:

你是打电话给GetQueuedCompletionStatus来获取数据吗?

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

【讨论】:

【参考方案3】:

我想通了。我是个白痴。我发送的字节数为零。

【讨论】:

这是迄今为止最好的答案。 :)

以上是关于在接受后 TCP IOCP 不会收到的主要内容,如果未能解决你的问题,请参考以下文章

并发程序设计6:IOCP

WinSock IOCP 模型总结(附一个带缓存池的IOCP类)

发送后如何正确关闭套接字(使用 IOCP)?

IOCP:如果操作立即返回错误,我还能收到完成通知吗?

分享我写的IOCP:源码+思路(转载)

使用 IOCP 的 TCP/IP 服务器。接收缓冲区中的偶尔数据损坏