如何映射 POSIX 的 select 和 Windows WSAEventSelect 的事件
Posted
技术标签:
【中文标题】如何映射 POSIX 的 select 和 Windows WSAEventSelect 的事件【英文标题】:How to map events of POSIX's select and Windows WSAEventSelect 【发布时间】:2016-01-27 16:54:52 【问题描述】:POSIX 的 select 允许确定 3 个事件:
阅读 写 错误Window 的 WSAEventSelect 有 10 个:
FD_READ FD_WRITE FD_OOB FD_ACCEPT FD_CONNECT FD_CLOSE FD_QOS FD_GROUP_QOS FD_ROUTING_INTERFACE_CHANGE FD_ADDRESS_LIST_CHANGE如何将这些 Windows 事件映射到 POSIX 事件?
编辑
很遗憾,由于multiple providers restriction,我无法使用Windows 的select
实现。
【问题讨论】:
如果您不需要使用 WSAEVENT 等待网络事件,您也可以使用select(..)
...它在 winsock2.h 中定义
@LukasThomsen 我不能使用select
,因为它不允许混合来自不同提供商的套接字。
【参考方案1】:
select()
和 WSAEventSelect()
之间的映射如果您阅读文档并不难弄清楚。
select function
WSAEventSelect function
select()
报告套接字在以下情况下是可读的:
-
套接字正在侦听,并且有等待接受的待处理入站连接 (
FD_ACCEPT
)
套接字有等待读取的待处理数据 (FD_READ
)。如果在套接字上启用了SO_OOBINLINE
选项,则这包括带外数据。
套接字已被对等方正常关闭(FD_CLOSE
,它也处理一些不正常的关闭)。
select()
报告套接字在以下情况下是可写的:
-
非阻塞
connect()
已成功连接到侦听端口(@987654334@,错误代码为零)
套接字在被接受后有缓冲区空间来接受出站数据 (FD_WRITE
),或者在之前的非阻塞发送后将不再阻塞。
select()
在以下情况下报告套接字异常:
-
非阻塞
connect()
失败(FD_CONNECT
带有非零错误代码)。您可以使用getsockopt(SOL_SOCKET, SO_ERROR)
获取错误代码。
如果在套接字 (FD_OOB
) 上禁用了 SO_OOBINLINE
选项,则套接字有等待读取的未决带外数据。
出现各种套接字错误。
其余的 WSA 事件没有 select()
等效项,因为它们是与 POSIX/BSD 套接字 API 无关的严格的 WinSock 特定扩展。
因此,您将使用WSAEventSelect()
设置所需的FD_...
事件,然后使用WSAWaitForMultipleEvents()
等待事件。当事件发出信号时,使用WSAEnumNetworkEvents()
获取关联的错误代码并清除事件状态以等待下一次等待。
【讨论】:
如何确定连接失败并显示错误代码? 这个映射的来源是什么? @Kentzo:MSDN 文档。 每个事件都可能因错误而失败,但您只提到了FD_CONNECT。为什么不提其余的? @Kentzo:select()
不会区分特定事件的错误,而 WSAEventSelect()
会。至少对于connect()
,如果连接尝试成功,select()
报告可写,否则报告异常状态,因此您可以区分(您必须使用getsockopt(SOL_SOCKET, SO_ERROR)
来获取实际的错误代码)。我确实说过“当一个事件发出信号时,使用 WSAEnumNetworkEvents() 来获取相关的错误代码”。您问如何将 WSAEventSelect()
事件映射到 select()
,而不是反过来。以上是关于如何映射 POSIX 的 select 和 Windows WSAEventSelect 的事件的主要内容,如果未能解决你的问题,请参考以下文章
Linux 中的 select()、posix 消息队列和多线程
有人用过Posix pthread win32库,dll文件
在 Win32/MFC 和 POSIX 中,线程会自行清理吗?
mingw-w64线程模型:posix vs win32(posix允许使用c++11的std:: thread,但要带一个winpthreads,可能需要额外dll)