【问题标题】:WSAEventSelect, one event, multiple socketsWSAEventSelect,一个事件,多个套接字
【发布时间】:2013-11-12 17:38:51
【问题描述】:

我正在我的软件中重写代码以支持多个连接,直到现在,我使用 select。为了让我的软件更便携,我改用 WSAPoll。在 WSAPoll 中发现 Microsoft 无法解决的错误后,我想更改为建议的 WSAEventSelect。由于 WSAWaitForMultipleEvents 最多仅支持 64 个事件,并且出于节省资源的原因,我想将一个 hEvent 连接到多个套接字。我现在的问题是,是

rc = WSAEventSelect(s1, hEventObject1, FD_READ);
rc = WSAEventSelect(s2, hEventObject1, FD_READ);

合法操作?请仅在您有确凿的事实而不是意见的情况下回答。或者你自己以前用过这种方式。另外,出于某些原因,我不想使用 boost(例如,1.52 在套接字部分有一个错误(有趣的是,这与 WSAPoll 几乎相同的错误))。也请不要“你为什么不......”

【问题讨论】:

  • 事实:如果您设置一对多映射,您将失去唯一标识对象的能力。我想知道您希望通过问题中发布的代码 sn-p 实现什么目标。
  • @IInspectable 你当然是对的。我必须使用 WSAEnumNetworkEvents 遍历所有套接字,即使它们没有发出任何信号。我只是尝试将内容保存在单个线程中,因为我重构的其余代码目前不是线程安全的。

标签: c++ sockets winapi


【解决方案1】:

单个等待事件不应与多个套接字相关联。每个套接字都应该使用它自己的单独事件。否则,如果多个套接字要使用同一个事件,当该事件发出信号时,您将不知道哪个套接字满足了等待。即使可以,当调用WSAEnumNetworkEvents() 来获取事件数据时也会出现竞争条件,因为它会重置可能已经由另一个套接字设置的事件。所以你可能会丢失事件。

要绕过 64 个句柄的限制,请按照 WaitForMultipleObjects() 文档中的说明执行操作:

要等待超过 MAXIMUM_WAIT_OBJECTS 个句柄,请使用以下方法之一:

• 创建一个线程以等待 MAXIMUM_WAIT_OBJECTS 个句柄,然后在该线程和其他句柄上等待。使用此技术将句柄分成 MAXIMUM_WAIT_OBJECTS 组。

• 调用RegisterWaitForSingleObject 以等待每个句柄。线程池中的等待线程等待 MAXIMUM_WAIT_OBJECTS 个注册对象,并在对象发出信号或超时间隔到期后分配一个工作线程。

否则,请改用WSAAsyncSelect(),并让它在任何给定套接字满足请求条件时通过窗口消息通知您。

【讨论】:

  • 我建议一个替代方案,即使用 IO 完成端口。它们有点痛苦,但允许您等待单个对象而不会失去辨别插槽的能力。
  • 我知道这一点。它是关于一种 hack,将单线程的东西作为我必须使用的代码的一部分(还不是线程安全的)。我承担了损失,并会使用 WSAEventSelect 遍历套接字。这比建立一种最终导致相同效果的队列系统更容易。像这样,我知道这是一种特殊的踩踏方式。不幸的是,微软帮助中没有描述这种方式。
  • @Hasturkun 是的,但我没有找到一个包含多个套接字的简单教程。我读到的关于 IO 完成端口的内容看起来非常复杂。对于 linux/Mac OS,使用 poll() 非常容易。我不想学习下一个微软自己的做事方式,所以我尽量接近我现在已经掌握的东西,即 WSA 的东西。
  • @MartinSchlott:I/O 完成端口不是新的,它们已经存在了很长时间,并且在 2.0 首次发布时被添加到 WinSock。详情见 MSDN:Windows Sockets 2.0: Write Scalable Winsock Apps Using Completion Ports。您可以将多个套接字与单个 IOCP 相关联,并且无论何时发出信号,您都可以使用用户定义的上下文信息来了解每次触发了哪个套接字。
  • @MartinSchlott:您不需要(但应该)将工作线程与 IOCP 一起使用,您可以在管理套接字的同一线程中使用 GetQueuedCompletionStatus() 轮询 IOCP 状态信息。跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-25
  • 2015-10-30
  • 2012-05-17
  • 1970-01-01
  • 2012-12-16
  • 1970-01-01
相关资源
最近更新 更多