Windows的异步选择机制

来源:互联网 发布:2016网络流行语 绿萝 编辑:程序博客网 时间:2024/05/21 08:01

发现书上已经写得很清楚了,就懒得再写了,直接从书里摘出来。以下内容摘自《windows sockets网络程序设计大全》。

1、Unix下sockets异步事件的获得是通过调用select函数来进行查询,通常形式都是在循环内部使用select函数来进行选择。而windows sockets的异步选择函数提供了消息机制的网络事件选择:当使用它登记的网络事件发生时,windows应用程序相应的窗口函数将收到一个消息,消息中指示了发生的网络事件,以及与事件相关的一些信息。

2、用来注册异步消息的函数是WSAAsyncSelect函数,其函数原型如下:

int WSAAsyncSelect(SOCKET s, HWND hWnd, unsigned int wMsg, long lEvent);

它请求Windows Sockets DLL在检测到套接字s上发生的网络事件lEvent时,向窗口hWnd发送一个消息wMsg。它自动地设置套接字处于非阻塞工作方式,参数lEvent由下列事件的一个或多个组合而成:

值 含义

FD_READ 期望在套接字s收到数据(即读准备好)时接到通知。

FD_WRITE 期望在套接字s可发送数据(即写准备好)时接到通知。

FD_OOB 期望在套接字s上有带外数据到达时接到通知

FD_ACCEPT 期望在套接字s上有外来连接时接到通知

FD_CONNECT 期望在套接字s连接建立完成时接到通知

FD_CLOSE 期望在套接字s关闭时接到通知

3、需要注意的是,为一个套接字发布的WSAAsyncSelect()函数调用将取消在它之前发布的WSAAsyncSelect()函数调用的作用。在上面的例子里,使用下面的代码不会做所期望的工作:第二次调用将取消第一次调用的作用,只有FD_WRITE事件发生时会用消息wMsg2来报告。

rc = WSAAsyncSelect(s, hWnd, wMsg1, FD_READ);

rc = WSAAsyncSelect(s, hWnd, wMsg2, FD_WRITE);

根据这一特性,我们为了注销对套接字s上发生的网络事件的消息发送,就可以将参数lEvent设为0来调用它:

rc = WSAAsyncSelect(s, hWnd,0,0);

4、Windows Sockets DLL在一个网络事件发生后,它只给相应的应用程序发送一个消息。但是当应用程序使用函数调用隐式地允许重新发送此网络事件的消息时,应用程序的窗口函数又可能再次收到相应的消息。这些事件有:FD_READ、FD_OOB、FD_ACCEPT。

对于FD_CONNECT和FD_CLOSE事件来说,因为它们只是一种状态(连接建立成功和连接关闭),因此不会产生多个消息。

如果应用程序在收到FD_WRITE消息之后使用send()或sendto()调用发送数据均成功返回,那么它在以后需要再次发送数据时可以直接发送;但如果它希望再次获得一个FD_WRITE消息,则必须使用函数WSAAsyncSelect()来重新注册FD_WRITE事件。

5、如果使用WSAAsyncSelect()函数为监听套接字设置了事件选择,那么此事件选择将同样作用于新的接收套接字。并且它们拥有相同的消息wMsg值,如果应用程序对于不同的接收套接字要求不同的消息或事件,那么它应该使用WSAAsyncSelect()函数来给接收套接字设置不同的事件选择。

6、基本使用方法

A.第一步是在某个套接字上注册特定的事件,通过设置lEvent为不同的值来实现。如WSAAsyncSelect(s, hWnd, wMsg, FD_READ|FD_WRITE)。

B.在窗口函数的消息循环中增加一个分支:

case wMsg:

switch (lParam) {

case FD_READ:

/* 从套接字wParam读取数据 */

case FD_WRITE:

/* 向套接字wParam发送数据 */

}

break;

7、当套接字s上注册的网络事件(读准备好或写准备好)发生时,窗口hWnd将收到消息wMsg。消息变量wParam指示发生网络事件的套接字,变量lParam的低字描述发生的网络事件,高字包含错误码。