三.Windows I/O模型之事件选择(WSAEventSelect )模型

时间:2022-03-11 09:07:28

1.事件选择模型:和异步选择模型类似的是,它也允许应用措施在一个或多个套接字上,接收以事件为根本的网络事件通知。对付异步选择模型给与的网络事件来说,它们均可原封不动地移植到事件选择模型。事件选择模型和异步选择模型最主要的分歧在于网络事件会投递至一个事件东西句柄,而非投递至一个窗口例程。
2.创建事件东西:事件选择模型要求应用措施针对筹算使用事件选择模型的每一个套接字,首先创建一个事件东西。创建要领是挪用WSACreateEvent函数,它的界说如下:WSAEVENT WSACreateEvent(void);
3.绑定事件东西与套接字:
int WSAEventSelect(
    SOCKET s,
    WSAEvent hEventObject,
    long lNetworkEvents//网络事件,就是异步选择中的网络事件,用法完全不异
    );
 对付事件来说,他有两种类型,自动事件和人工事件。有两种状态,未触发状态和触发状态。使用WSACreateEvent函数创建的事件默认为人工事件且处于未触发状态。跟着网络事件触发了与一个套接字关联在一起的事件东西,事情状态便会从未触发状态转酿成触发状态。由于事件东西是在一种人工重设模式中创建的,所以在完成了一个I/O请求的措置惩罚惩罚之后,我们的应用措施需要卖力将事情
状态触发状态变动未触发状态。
4.重置事件为未触发状态:
BOOL WSAResetEvent(WSAEVENT hEvent);
该函数的成果就是把时间从触发状态重置为未触发状态
5.*事件东西,释放其所占用的内核资源:
BOOL WSACloseEvent(WSAEVENT hEvent);
6.监视事件东西的状态:
DWORD WSAWaitForMultipleEvents(
    DWORD cEvents;//事件东西数组中事件的数目
    const WSAEVENT FAR* lphEvents,//事件东西数组
    BOOL fWaitAll,//该参数指明了是否要等到所有事件东西变为触发状态函数才返回
    DWORD dwTimeout,//超时,毫秒为单位赶过规定的时间,函数就会当即返回,即使由fWaitAll参数规定的条件尚未满足也如此
    BOOL fAlertable//忽略,置为FALSE
    );
参数:
    要注意的是,WSAWaitForMultipleEvents只能撑持由WSA_MAXIMUM_WAIT_EVENTS东西规定的一个最大值,在此界说成6 4个。因此,针对发出WSAWaitForMultipleEvents挪用的每个线程,该I/O模型一次最多都只能撑持6 4个套接字。假如想让这个模型同时打点不止64个套接字,必需创建特别的事情者线程,以便期待更多的事件东西。fWaitAll 参数指定了指明了是否要等到所有事件东西变为触发状态函数才返回。若设为TRUE,那么只有等lphEvents数组内包罗的所有事件东西都已进入触发状态,函数才会返回;但若设为FALSE,任何一个事件东西进入触发状态,函数就会返回。就后一种情况来说,返回值指出了到底是哪个事件东西造成了函数的返回。凡是,应用措施应将该参数设为FALSE,凡是,dwTimeout被置为0.
一次只为一个套接字事件供给处事    
函数解释:
一个套接字同一个事件东西句柄关联在一起后,应用措施便可开始I/O措置惩罚惩罚;要领是期待网络事件触发事件东西句柄的事情状态。WSAWaitForMultipleEvents函数的设计宗旨等于用来期待一个或多个事件东西句柄,并在事先指定的一个或所有事件东西进入触发状态后,
或在赶过了一个规定的时间周期后,当即返回。
7.确定网络事件产生的套接字:若WSAWaitForMultipleEvents收到一个事件东西的网络事件通知,便会返回一个值,指出造成函数返回的事件东西。这样一来,我们的应用措施便可引用事件数组中已传信的事件,并检索与阿谁事件对应的套接字,判断到底是在哪个套接字上,产生了什么网络事件类型。对事件数组中的事件进行引用时,应该用WSAWaitForMultipleEvents的返回值,,减去预界说值WSA_WAIT_EVENT_0,得到具体的引用值(即索引位置)。
Index=WSAWaitForMultipleEvents(...);
myEvent=EventArray[Index-WSA_WAIT_EVENT_0];
7.查询拜访产生的网络事件类型:
int WSAEnumNetworkEvents(
    SOCKET s,
    WSAEVENT hEventObjects,//参数可选,对应于筹算重设的事件东西,即设置事件为未触发状态。和WSAtResetEvent函数成果不异
    LPWSANETWORKEVENTS lpNetworkEvents//用来接受产生的网络事件类型以及可能呈现的任何错误代码
    );
该函数中的第四个参数用来接收产生的网络事件类型
8.WSANETWORKEVENTS布局:
tydef struct _WSANETWORKEVENTS
{
    long lNetworkEvents;//网络事件类型
    long iErrorCode[FD_MAX_EVENTS];//错误代码
}WSANETWORKEVENTS,FAR* LPWSANETWORKEVENTS;
iErrorCode参数指定的是一个错误代码数组,同lNetworkEvents中的事件关联在一起。iErrorCode针对每个网络事件类型,都存在着一个特殊的事件索引,名字与事件类型的名字类似,只是要在事件名字后面添加一个“ _BIT”后缀字串即可.

示例代码: