I/O 完成端口中的 select() 等效

Ami*_*mir 3 c sockets winapi winsock winsock2

我正在 Windows 中使用 WinSock 2.0 开发代理服务器。如果我想在阻塞模型中开发它, select() 是等待客户端或远程服务器从中接收数据的方式。是否有任何适用的方法可以使用 I/O 完成端口来做到这一点?

我曾经使用 I/O 完成端口为两个方向的数据提供两个上下文。但是有一个 WSARecv 挂起无法从远程服务器接收任何数据!我找不到问题所在。

提前致谢。

编辑。是当前开发的 I/O 完成端口上的 WorkerThread 代码。但我问的是如何实现 select() 等效性。

Len*_*ate 5

I/O 完成端口指示 I/O 操作何时完成,但不指示何时可以启动操作。在许多情况下,这实际上并不重要。大多数情况下,如果您假设始终可以启动操作,那么重叠 I/O 模型将工作得很好。在大多数情况下,底层操作系统只会做正确的事情并为您排队数据,直到可以完成操作。

但是,在某些情况下,这并不理想。例如,您始终可以使用重叠 I/O 发送到套接字。即使远程对等方未读取并且 TCP 堆栈已开始使用流量控制并已填满 TCP 窗口时,您也可以执行此操作...这只是以完全不受控制的方式使用本地计算机上的资源(并非完全不受控制,但是由对等方控制,这是不理想的)。我在这里写这个,在许多情况下,您确实需要通过跟踪您有多少未完成的 I/O 写入请求并将其用作“准备发送”的指示来主动管理此类事情。

同样,如果您想要“准备接收”指示,您可以在套接字上发出“零字节”读取。这是使用零长度缓冲区发出的读取。当有数据要读取但没有数据返回时,读取返回。这会给您指示连接上有要读取的数据,但恕我直言,除非您遇到非常不可能的I/O 页锁定限制情况,否则您可能会在以下情况下读取数据它变得可用,而不是强制多个内核到用户模式转换。

总而言之,您实际上并不需要回答您的问题。您需要查看 API 的工作原理并编写代码来使用它,而不是试图强制 API 以您熟悉的其他 API 的方式工作。