WSAAsyncSelect 异步I/O模型

WSAAsyncSelect(s, hwnd, WM_SOCKET, FD_CONNECT | FD_READ | FD_WRITE | FD_CLOSE);
这样一来,我们的应用程序以后便可在套接字 s上,接收到有关连接、发送、接收以及套接字关闭这一系列网络事件的通知。特别要注意的是,多个事件务必在套接字上一次注册!另外还要注意的是,一旦在某个套接字上允许了事件通知,那么以后除非明确调用c l o s e s o c k e t命令,或者由应用程序针对那个套接字调用了 W S A A s y n c S e l e c t,从而更改了注册的网络事件类型,否则的话,事件通知会永远有效!若将 l E v e n t参数设为0,效果相当于停止在套接字上进行的所有网络事件通知。
若应用程序针对一个套接字调用了W S A A s y n c S e l e c t,那么套接字的模式会从“锁定”自动变成“非锁定”,我们在前面已提到过这一点。这样一来,假如调用了像W S A R e c v这样的Wi n s o c kI / O函数,但当时却并没有数据可用,那么必然会造成调用的失败,并返回W S A E W O U L D B L O C K错误。为防止这一点,应用程序应依赖于由W S A A s y n c S e l e c t的u M s g参数指定的用户自定义窗口消息,来判断网络事件类型何时在套接字上发生;而不应盲目地进行调用。

表8-3   用于W S A A s y n c S e l e c t函数的网络事件类型
事件类型 含 义
F D _ R E A D 应用程序想要接收有关是否可读的通知,以便读入数据
F D _ W R I T E 应用程序想要接收有关是否可写的通知,以便写入数据
F D _ O O B 应用程序想接收是否有带外(O O B)数据抵达的通知
F D _ A C C E P T 应用程序想接收与进入连接有关的通知
F D _ C O N N E C T 应用程序想接收与一次连接或者多点j o i n操作完成的通知
F D _ C L O S E 应用程序想接收与套接字关闭有关的通知
F D _ Q O S 应用程序想接收套接字“服务质量”(Q o S)发生更改的通知
F D _ G R O U P _ Q O S 应用程序想接收套接字组“服务质量”发生更改的通知(现在没
什么用处,为未来套接字组的使用保留)
F D _ R O U T I N G _ I N T E R FA C E _ C H A N G E 应用程序想接收在指定的方向上,与路由接口发生变化的通知
F D _ A D D R E S S _ L I S T _ C H A N G E 应用程序想接收针对套接字的协议家族,本地地址列表发生变化的通知

w P a r a m参数指定在其上面发生了一个网络事件的套接字。假若同时为这个窗口例程分配了多个套接字,这个参数的重要性便显示出来了。在 l P a r a m参数中,包含了两方面重要的信息。其中, l P a r a m的低字(低位字)指定了已经发生的网络事件,而 l P a r a m的高字(高位字)包含了可能出现的任何错误代码。

 

WSAAsyncSelect 服务器示范代码

  1. #define WM_SOCKET WM_USER+1
  2. #include < windows.h >
  3. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  4.                                 LPSTR lpCmdLine, int nCmdShow)
  5. {
  6.   SOCKET Listen;
  7.   HWND Window;
  8.   //Create a window and assign the ServerWinProc below to it
  9.   Window = CreateWindow(...);
  10.   //Start Winsock and create a socket
  11.   WSAStartup(...);
  12.   Listen = Socket();
  13.   //Bind the socket to port 5150 and begin listening for connections
  14.   InternetAddr.sin_family = AF_INET;
  15.   InternetAddr.sin_addr.s_addr = htonl(INADDR_ANY);
  16.   InternetAddr.sin_port = htons(5150);
  17.   bind(Listen, (PSOCKADDR) &InternetAddr, sizeof(InternetAddr));
  18.   //Set up window message notification on the new socket 
  19.   //using the WM_SOCKEt define above
  20.   WSAAsyncSelect(Listen, Window, WM_SOCKET, FD_ACCEPT | FD_CLOSE);
  21.   listen(Listen, 5);
  22.   // Translate and dispatch window messages until the application terminates
  23. }
  24. BOOL CALLBACK ServerWinProc(HWND hDlg, WORD wMsg, WORD wParam, DWORD lParam)
  25. {
  26.   SOCKET Accept;
  27.   switch(wMsg)
  28.   {
  29.     case WM_PAINT:
  30.       // Process window paint messages
  31.       break;
  32.     case WM_SOCKET:
  33.       // Determine whether an error occurred on the
  34.       // socket by using the WSAGETSELECTERROR() macro
  35.       if(WSAGETSELECTERROR(lParam))
  36.       {
  37.         //Display the error and close the socket
  38.         closesocket(wParam);
  39.         break;
  40.       }
  41.       // Determine what event occurred on the socket
  42.       swith(WSAGETSELECTEVENT(lParam))
  43.       {
  44.         case FD_ACCEPT:
  45.           // Accept an incoming connection
  46.           Accept = accept(wParam, NULL, NULL);
  47.           // Prepare accepted socket for read, write, and close notification
  48.           WSAAsyncSelect(Accept, hwnd, WM_SOCKET, FD_READ | FD_WRITE | FD_CLOSE);
  49.           break;
  50.         case FD_READ:
  51.           // Receive data from the socket in wParam
  52.           break;
  53.         case FD_WRITE:
  54.           // The socket in wParam is ready for sending data
  55.           break;
  56.         case FD_CLOSE:
  57.           // The connection is now closed
  58.           closesocket(wParam);
  59.           break;
  60.       }
  61.       break;
  62.   }
  63.   return TRUE;
  64. }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
WSAAsyncSelect模型是一种Windows Socket编程模型,它采用异步通信方式,可以实现异步接收和发送数据。其工作原理如下: 1. 在使用WSAAsyncSelect模型之前,需要调用WSAStartup函数初始化Winsock库。 2. 调用socket函数创建一个套接字,并使用WSAAsyncSelect函数注册一个异步消息事件。该函数指定了套接字、窗口句柄、消息类型等参数。 3. 当套接字事件发生时,Winsock库会向指定的窗口发送一个异步消息,通知程序有数据可读或可写。 4. 在窗口过程中,根据接收到的消息类型,调用recv或send函数进行数据的异步接收或发送。 WSAAsyncSelect模型的优点是: 1. 异步通信方式,可以实现在数据传输过程中,程序不被阻塞,提高程序的执行效率。 2. 采用事件驱动方式,程序可以响应多个套接字事件,实现多路复用。 3. 可以通过窗口消息机制,实现程序间的通信。 WSAAsyncSelect模型的缺点是: 1. 编程复杂度较高,需要熟悉Windows消息机制。 2. 在多线程编程中,需要实现线程之间的消息传递,程序设计和调试难度较大。 3. 需要频繁地调用recv和send函数进行数据的异步接收和发送,程序运行效率较低。 总的来说,WSAAsyncSelect模型适用于需要同时处理多个套接字事件的程序,例如服务器程序,但是在编程复杂度和程序执行效率方面,都需要付出一定的代价。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值