Twisted包含a reactor implemented on top of MsgWaitForMultipleObjects
。显然,反应堆在TCP连接何时结束时可靠地注意到,至少在对等体发送一些字节然后快速关闭连接的情况下。似乎发生的事情是:
MsgWaitForMultipleObjects
with some socket handles and QS_ALLINPUT
. MsgWaitForMultipleObjects
。MsgWaitForMultipleObjects
永远不再表示句柄处于活动状态。 TCP实现永远不会再次查看套接字,因此它永远无法检测到连接已关闭。这使得MsgWaitForMultipleObjects
似乎是边缘触发的通知机制。 MSDN documentation说:
Waits until one or all of the specified objects are in the signaled state
or the time-out interval elapses.
这听起来不像是边缘触发。这听起来像是水平触发。
MsgWaitForMultipleObjects
实际上是边缘触发的吗?或者它是否被水平触发,这种不当行为是由其行为的其他方面引起的?
附录 The MSDN docs for WSAEventSelect解释了这里发生了什么,包括指出FD_CLOSE
基本上是一次性事件。在发出一次信号之后,你再也不会得到它了。这在某种程度上解释了为什么Twisted有这个问题。考虑到这种限制,我仍然有兴趣听听如何有效地使用MsgWaitForMultipleObjects
。
答案 0 :(得分:1)
要使用WSAEventSelect
并区分活动,您需要致电WSAEnumNetworkEvents
。确保您正在处理报告的每个事件,而不仅仅是第一个。
WSAAsyncSelect
可以轻松确定原因,并且通常与MsgWaitForMultipleObjects
一起使用。
因此,您可以使用WSAAsyncSelect
代替WSAEventSelect
。
另外,我认为你对边缘触发和水平触发之间的区别有一个根本的误解。你的推理似乎与自动重置和手动重置事件有关。