TCP IOCP 在acceptex 之后不会接收
我正在尝试编写一个 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 ...
注意:我尝试从伪套接字发送到远程套接字,与以相反方式发送数据相同的问题。
I'm trying to write an IOCP server. Basically, I have it accepting new connections. For the purpose of my testing, I'm running and connecting to 127.0.0.1.
I create the pseudo socket prior to calling AcceptEx(). Once a connection is accepted, the new pseudo socket is used for communication. This new socket is associated with an io completion port [CreateIoCompletionPort], I then assign it a few options, [SO_EXCLUSIVEADDRUSE] and [SO_CONDITIONAL_ACCEPT], and then I call WSARecv() to accept incoming data.
The problem is that once my remote connection connects to the server, it sends data, but that data is never received. I'm wondering if someone could offer some ideas as to why it's not receiving data? Perhaps my logic is flawed? I stepped through my code several times. no errors are recorded.
EDIT: Fixed the wording. I create the socket before AcceptEx() call.
Basic logic in my code:
// 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 ...
NOTE: I tried sending from the pseudo socket to the remote socket, same problem as sending data in the reverse way.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您需要发布一些代码,但您的描述没有意义。这不是基于
AcceptEx()
的服务器的运行方式。使用基于
AcceptEx()
的服务器,您可以在发布AcceptEx()
之前创建接受的套接字。然后,您将AcceptEx()
与侦听套接字和新套接字以及允许您接收远程地址和(可选)数据的缓冲区一起发布。因此,如果您在原始问题中描述您的代码,那么您的代码是错误的,或者您没有使用
AcceptEx()
。我目前忽略了您添加到混合中的“少数选项”,因为它们只是进一步混淆了目前的情况,而没有任何代码可供分析。您可能有兴趣下载我的基于免费 IOCP 的服务器框架,其中包括有效的
AcceptEx()
和传统的基于Accept()
的服务器代码。您可以从这里获取它: http://www.serverframework.com/产品---the-free-framework.htmlYou need to post some code but your description doesn't make sense. That's NOT how
AcceptEx()
based servers operate.With an
AcceptEx()
based server you create your accepted socket before you post theAcceptEx()
. You then post theAcceptEx()
with the listening socket and the new socket and a buffer which allows you to receive the remote address and, optionally, data.So if you are describing your code in your original question then your code is wrong or you're not using
AcceptEx()
. I'm currently ignoring the 'few options' that you throw into the mix as they simply further confuse things at present without any code to analyse.You might be interested in downloading my free IOCP based server framework, which includes working
AcceptEx()
and traditionalAccept()
based server code. You can get it from here: http://www.serverframework.com/products---the-free-framework.html您是否正在调用 GetQueuedCompletionStatus 来获取数据?
如果您这样做不仅仅是为了自学,我还建议您使用 boost::asio - 一个优秀的库,允许您让其他人执行处理 io 完成端口的繁琐代码。
Are you calling GetQueuedCompletionStatus to get the data?
In case you are not doing this just to learn for yourself, I would also recommend that you use boost::asio - an excellent library that allows you to let someone else do the tedious code for handling the io completion ports.
我想通了。我是个白痴。我发送了零字节。
I figured it out. I'm an idiot. I was sending zero bytes.