如何使用MsgWaitForMultipleObjects可靠地检测断开连接的TCP套接字?

2024-09-27 00:13:22 发布

您现在位置:Python中文网/ 问答频道 /正文

Twisted includesa reactor implemented on top of ^{}。显然,reactor无法可靠地注意到TCP连接何时结束,至少在对等端发送一些字节然后快速关闭连接的情况下。似乎发生的是:

  1. The reactor calls ^{} with some socket handles and ^{}.
  2. 调用完成并指示处于此状态(即有字节等待读取且已被对等方关闭)的套接字句柄处于活动状态。在
  3. The reactor dispatches this notification to the common TCP implementation.
  4. TCP实现从套接字读取可用字节。有一些,它们被传递到应用程序代码中。在
  5. 控制权返回给reactor,它最终再次调用MsgWaitForMultipleObjects。在
  6. 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。在


Tags: orofthe字节ontwisted句柄边缘
1条回答
网友
1楼 · 发布于 2024-09-27 00:13:22

为了使用WSAEventSelect并区分活动,需要调用WSAEnumNetworkEvents。确保您正在处理报告的每个事件,而不仅仅是第一个事件。在

WSAAsyncSelect使确定病因变得容易,并且经常与MsgWaitForMultipleObjects一起使用。在

所以您可以使用WSAAsyncSelect而不是WSAEventSelect。在

另外,我认为你对边缘触发和水平触发的区别有一个根本的误解。你的推理似乎与自动复位和手动复位事件有关。在

相关问题 更多 >

    热门问题