Windows套接字IO模型之EventSelect

来源:互联网 发布:telnet 端口链接失败 编辑:程序博客网 时间:2024/05/19 12:27
 一、相关的API函数

/**

 * @brief  创建一个手工重设的事件对象,该对象的初始状态是未受信。

 *               返回的事件对象的句柄不能被子进程所继承。事件对象是未命名的。

 *

 * @return 成功的话,返回事件对象句柄;否则,返回WSA_INVALID_EVENT。

 * */

WSAEVENT WSACreateEvent(void);

 

/**

 * @brief  将一个事件对象与FD_XXX等网络事件相关联。

 *

 * @param  s                           套接字描述符

 * @param  hEventObject     事件对象句柄

 * @param  lNetworkEvents 网络事件FD_XXX的位掩码组合

 *

 * @return 调用成功时,返回0;否则,返回SOCKET_ERROR。

 * */

int WSAEventSelect(SOCKET s, WSAEVENT hEventObject, long lNetworkEvents);

 

/**

 * @brief  在一个或多个事件对象上等待。当所等待的事件对象受信,或者指定

 *               的时间过去时,此函数返回。

 *

 * @param  cEvents     事件对象句柄的个数

 * @param  lphEvents   指向一个事件对象句柄数组

 * @param  fWaitAll    是否等待所有事件对象变成受信状态

 * @param  dwTimeout   指定要等待的时间

 * @param  fAlertable  使用WSAEventSelect模型时可忽略,应设为FALSE

 *

 * @return 如果调用成功,将返回下列值:

 *         1) WSA_WAIT_EVENT_0至WSA_WAIT_EVENT_0 + cEvents - 1;

 *         2) WSA_WAIT_IO_COMPLETION

 *         3) WSA_WAIT_TIMEOUT

 *         失败的话,返回WSA_WAIT_FAILED。

 * */

DWORD WSAWaitForMultipleEvents(DWORD cEvnets, const WSAEVENT *lphEvents,

        BOOL fWaitAll, DWORD dwTimeout, BOOL fAlertable);

使用WSAWaitForMultipleEvents()的注意事项:

将fWaitAll设为FALSE后,如果同时有几个事件对象受信,此函数的返回值仅能指明一个,就是句柄数组中最前的那个。如果指明的这个事件对象总有网络事件发生,那么后面其他事件对象所关联的网络事件就得不到处理了。解决办法是,此函数返回后,对每个事件都再次调用它,以便确定其状态。

 

/**

 * @brief  查看发生了什么网络事件

 *

 * @param  s                套接字描述符

 * @param  hEventObject     事件对象句柄

 * @param  lpNetworkEvents  网络事件和相关的出错代码

 *

 * @return 成功,返回0;否则,返回SOCKET_ERROR。

 * */

int WSAEnumNetworkEvents(SOCKET s, WSAEVENT hEventObject,

        LPWSANETWORKEVENTS lpNetworkEvents);

 

WSANETWORKEVENTS对象的定义如下:

typedef struct _WSANETWORKEVENTS {

    long lNetworkEvents;

    int iErrorCode[FD_MAX_EVENTS];

}WSANETWORKEVENTS, *LPWSANETWORKEVENTS;

iErrorCode参数是一个数组,它的每一个成员对应着一个网络事件的出错代码。可以用预定义标识FD_READ_BIT(=0)、FD_WRITE_BIT(=1)等来索引FD_READ、FD_WRITE等事件发生时的出错代码。FD_READ与FD_READ_BIT的关系如下:

                                                   FD_READ (1 << FD_READ_BIT)

其它网络事件以此类推。

 

二、EventSelect模型的流程 :

1. 创建事件对象;

2. 将事件对象与FD_XXX等网络事件相关联;

3. 等待事件对象处于受信状态(有事件发生或者超时);

4. 枚举网络事件(确定什么事件发生了),编写事件处理代码。

 

附: 几个标识的含义

    SOCKET —— typedef UINT_PTR(无符号整型数,32或64位)

    WSAEVENT —— HANDLE (句柄)

    WSA_WAIT_EVENT_0 —— ((DWORD)0)

    WSA_WAIT_TIMEOUT —— ((DWORD)0x102L)

    WSA_WAIT_FAILED  —— ((DWORD)-1L)

 

参考文献

1.《Windows网络与通信程序设计》(王艳平);

2. MSDN.

原创粉丝点击