【问题标题】:Handling asynchronous sockets in WinSock?在 WinSock 中处理异步套接字?
【发布时间】:2011-02-18 05:05:52
【问题描述】:

我正在使用消息窗口和 WSAAsyncSelect。如何使用一个消息窗口跟踪多个套接字(客户端)?

【问题讨论】:

    标签: c windows sockets winsock2


    【解决方案1】:

    Windows 支持多种套接字操作模式,您需要明确自己使用的是哪一种:

    • 阻塞套接字。发送和接收块。
    • 非阻塞套接字:send 和 recv 返回 E_WOULDBLOCK,并且 select() 用于确定哪些套接字已准备就绪
    • 异步套接字:WSAAsyncSelect - 套接字将事件通知发布到 HWND。
    • EventSockets:WSAEventSelect - 套接字信号事件。
    • 重叠的套接字:WSASend 和 WSARecv 通过传入 OVERLAPPED 结构与套接字一起使用。 Overlapped Sockets 可以与 IOCompletionPorts 结合使用并提供最佳的可扩展性。

    为了方便,异步套接字比较简单,MFC CAsyncSocket 类支持。

    事件套接字很难使用,因为可传递给 WaitForMultipleObjects 的最大对象数为 64。

    使用 IO CompletionPorts 的重叠套接字是处理套接字的最具可扩展性的方式,它允许基于 Windows 的服务器扩展到数万个套接字。


    根据我的经验,在使用异步套接字时,会想到以下几点:

    • 通过窗口消息处理 FD 事件可以处理“大量”套接字,但性能将开始受到影响,因为所有事件处理都在一个线程中完成,并通过可能忙于处理 UI 事件的消息队列进行序列化如果在单线程 GUI 应用中使用。

    • 如果您将 GUI 窗口或计时器托管在与许多套接字相同的线程上:WM_TIMER 和 WM_PAINT 消息的优先级较低,只有在消息队列为空时才会生成。因此,非常繁忙的套接字会导致 GUI 绘制或基于 SetTimer 的计时失败。

    • 如果托管 GUI 可以解决这些问题,请创建一个专用的工作线程来处理您的套接字。鉴于工作线程将有一个消息循环,您可以使用消息队列进行线程间通信 - 只需将 WM_APP 消息发布到线程。

    • 将 FD 回调映射到套接字对象的最简单方法是为每个将接收消息的 HWND 创建一个 SocketObjects 数组,然后在每次调用 WASAsyncSelect 时使用 WM_USER+index 作为消息 ID。然后,当您收到 WM_USER 到 WM_USER+(数组大小)范围内的消息时,您可以快速提取相应的状态对象。 WM_USER 为 0x400,WM_APP 为 0x8000,因此您可以使用此方法为每个消息窗口索引多达 31744 个套接字。

    • 不要使用静态范围数组。您需要将数组与窗口相关联,因为您可能希望在多个线程上创建套接字。每个线程都需要自己的消息循环和消息窗口。

    • HWND_MESSAGE 是你的朋友

    【讨论】:

    • 我的目标是异步套接字,我不知道使用事件会限制我。所以我将创建一个消息窗口。我将如何处理不同的套接字(例如:多个连接)。 PS:为了清楚起见,我编辑了帖子。
    • 关于异步选项的更多信息
    • MAXIMUM_WAIT_OBJECTS 定义为 64 而不是 32
    • 详尽列出所有可能模式的好答案,这非常有用!
    【解决方案2】:

    您告诉WSAAsyncSelect() 发送的窗口消息的wParam 参数将指定触发消息的套接字。这在WSAAsyncSelect()documentation中有明确说明:

    当提名网络之一 事件发生在指定的套接字上 s、应用程序窗口hWnd 接收消息 wMsg。 wParam 参数标识上的套接字 发生了网络事件。 lParam 的低位字指定 发生的网络事件。这 lParam 的高位字包含任何错误 代码。错误代码是任何错误 在 Winsock2.h 中定义。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多