Twisted包含a reactor implemented on top of MsgWaitForMultipleObjects
。显然,至少在对等方发送一些字节然后迅速关闭连接的情况下, react 堆在可靠地通知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
。 最佳答案
为了使用WSAEventSelect
和区分事件,您需要调用WSAEnumNetworkEvents
。确保您正在处理报告的每个事件,而不仅仅是第一个。WSAAsyncSelect
易于确定原因,通常与MsgWaitForMultipleObjects
一起使用。
因此,您可以使用WSAAsyncSelect
而不是WSAEventSelect
。
另外,我认为您对边缘触发和电平触发之间的区别有基本的误解。您的推理似乎与自动重置与手动重置事件更相关。