ConnectEx 与 IOCP 问题

Posted

技术标签:

【中文标题】ConnectEx 与 IOCP 问题【英文标题】:ConnectEx with IOCP problem 【发布时间】:2010-06-26 07:12:47 【问题描述】:

我使用 IOCP 制作了一个简单的虚拟服务器/虚拟客户端程序,用于某些测试/分析目的。 (我还想指出,我是异步网络编程的新手)

看起来服务器与原始客户端运行良好,但是当虚拟客户端尝试使用 ConnectEx 函数连接到服务器时,IOCP Worker 线程仍然被 GetQueuedCompletionStatus 函数阻塞,并且在服务器成功接受连接时从不返回结果.

问题和/或原因是什么,我应该如何解决这个问题?

【问题讨论】:

请显示更多代码。无论如何,当您尝试远程登录您的服务器时它会做什么? (telnet localhost ,作为一个简单的tcp客户端非常有用)。 很抱歉我不能给你看实际代码,因为它是基于我们公司自己的库,但客户端的骨架可以描述如下: WSAstartup -> Create IOCP -> Initiate Worker Thread -> Get ConnectEx 与 IOCtl -> 绑定套接字 -> 调用 ConnectEx -> 将套接字分配给 IOCP。我得到“套接字已经连接”。当我尝试重复连接到服务器时出现 WSAGetLastError 错误。明天我会尝试远程登录我的服务器。谢谢! 似乎在新线程上调用 ConnectEx 仅用于连接目的时它可以正常工作,但我仍然不知道这个问题的确切原因是什么。 【参考方案1】:

我想你用你的评论回答了你自己的问题。

您的事件顺序不正确,您说您绑定、连接、关联到 IOCP。

您应该绑定,将套接字与 IOCP 关联,然后调用 ConnectEx。

【讨论】:

【参考方案2】:

即使您将接受的套接字关联到 IOCP,您的工作线程仍将在 GetQueuedCompletionStatus 上保持阻塞状态,直到您发布“解锁”完成事件。 除非您“解锁”新套接字,否则系统不会发送接收/写入操作的完成事件。 详情请查看Push Framework的源代码http://www.pushframework.com,它是一个使用IOCP的C++网络应用框架。 “IOCPQueue”类中存在“解锁”技巧。

【讨论】:

有趣的代码...恕我直言,您创建的 IOCP 不正确,因为您创建用于创建 IOCP 的虚拟套接字不是为重叠使用而创建的,因为您使用的是 socket()而不是WSASocket()WSA_FLAG_OVERLAPPED 请参阅msdn.microsoft.com/en-us/library/aa363862(VS.85).aspx 的文档关于套接字的“为重叠I/O 完成打开”要求。其次,如果您使用第一个套接字只是为了创建 IOCP,那么您可以简单地传递NULL。第三,我从来没有发现在使用 IOCP 时需要任何“解锁”,就像文档建议的那样。 关于 Len 上面的评论,根据:msdn.microsoft.com/en-us/library/ms740506%28v=vs.85%29.aspx 在备注部分:“创建的套接字将默认具有重叠属性”

以上是关于ConnectEx 与 IOCP 问题的主要内容,如果未能解决你的问题,请参考以下文章

没有 ConnectEx 的 Windows 上的非阻塞套接字连接

将非 IOCP 客户端与 IOCP 服务器连接

无法连接服务器: dial tcp [::1]:8080: connectex: No connection could be made because the target machine主动拒绝

WSASocket() 应该与 IOCP 一起使用吗?

Mono 和 C# IOCP:这是个好主意吗?

IOCP 是不是创建自己的线程?