6

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

4

2 回答 2

15

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

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

在方便方面,异步套接字很简单,并且由 MFC CAsyncSocket 类支持。

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

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


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

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

  • 如果您将 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 是你的朋友

于 2011-02-18T05:34:43.107 回答
0

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

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

于 2011-02-18T19:34:41.833 回答