WSAEventSelect事件模型函数介绍
2017-10-09 17:36
295 查看
WSAEventSelect事件模型函数介绍
事件选择(WSAEventSelect)模型是另一个有用的异步I/O 模型。和WSAAsyncSelect 模型类似的是,它也允许应用程序在一个或多个套接字上,接收以事件为基础的网络事件通知,最主要的差别在于网络事件会投递至一个事件对象句柄,而非投递到一个窗口例程。
1、WSACreateEvent( )
定义:WSAEVENT WSACreateEvent(void);
作用:事件通知模型要求我们的应用程序针对使用的每一个套接字,首先创建一个事件对象。该函数返回一个创建好的事件对象句柄。
注释:WSACreateEvent 创建的事件有两种工作状态,以及两种工作模式。工作状态分别是“已传信”(signaled)和“未传信”(nonsignaled)。工作模式则包括“人工重设”(manualreset)和“自动重设”(autoreset)。
WSACreateEvent开始是在一种未传信的工作状态,并用一种人工重设模式,来创建事件句柄。随着网络事件触发了与一个套接字关联在一起的事件对象,工作状态便会从“未传信”转变成“已传信”。由于事件对象是在一种人工重设模式中创建的,所以在完成了一个 I/O 请求的处理之后,我们的应用程序需要负责将工作状态从已传信更改为未传信,可调用
WSAResetEvent 函数。
BOOLWSAResetEvent(
__in WSAEVENT hEvent //事件句柄;
);
应用程序完成了对一个事件对象的处理后,便应调用WSACloseEvent函数,释放由事件句柄使用的系统资源。
BOOLWSACloseEvent(
__in WSAEVENT hEvent //事件句柄;
);
2、WSAEventSelect
函数
定义:int WSAEventSelect(
__in SOCKET s, //代表感兴趣的套接字
__in WSAEVENT hEventObject, /*指定要与套接字关联在一起的事件对象,
即用WSACreateEvent 创建的那一个*/
__in long lNetworkEvents /*对应一个“位掩码”,用于指定应用程序感
兴趣的各种网络事件类型的一个组合。*/
);
作用:将事件与某个套接字关联在一起,同时注册自己感兴趣的网络事件类型。
参数lNetworkEvents可以用以下数值进行OR操作
FD_READ 应用程序想要接收有关是否可读的通知,以便读入数据
FD_WRITE 应用程序想要接收有关是否可写的通知,以便写入数据
FD_ACCEPT 应用程序想接收与进入连接有关的通知
FD_CONNECT 应用程序想接收与一次连接完成的通知
FD_CLOSE 应用程序想接收与套接字关闭的通知
一个套接字同一个事件对象句柄关联在一起后,应用程序便可开始I/O处理;方法是等待网络事件触发事件对象句柄的工作状态。
3、WSAWaitForMultipleEvents
函数
定义:DWORDWSAWaitForMultipleEvents(
__in DWORD cEvents,
__in const WSAEVENT* lphEvents,
__in BOOL fWaitAll,
__in DWORD dwTimeout,
__in BOOL fAlertable
);
参数描述:
1)cEvents和lphEvents 参数:定义了由 WSAEVENT 对象构成的一个数组,在这个数组中:
cEvents指定的是事件对象的数量;
lphEvents对应的是一个指针,用于直接引用该数组。
注:WSAWaitForMultipleEvents只能支持由WSA_MAXIMUM_WAIT_EVENTS 对象规定的一个最大值,在此定义成64个。因此,针对发出WSAWaitForMultipleEvents 调用的每个线程,该 I/O 模型一次最多都只能支持64个套接字。假如想让这个模型同时管理不止64个套接字,必须创建额外的工作者线程,以便等待更多的事件对象。
2)fWaitAll参数:指定了WSAWaitForMultipleEvents 如何等待在事件数组中的对象。
若设为TRUE,那么只有等lphEvents 数组内包含的所有事件对象都已进入“已传信”状态,函数才会返回;
若设为FALSE,任何一个事件对象进入“已传信”状态,函数就会返回。就后一种情况来说,返回值指出了到底是哪个事件对象造成了函数的返回。
当WSAWaitForMultipleEvents
收到一个事件对象的网络事件通知,便会返回一个值,指出造成函数返回的事件对象。这样一来,我们的应用程序便可引用事件数组中已传信的事件,并检索与那个事件对应的套接字,判断到底是在哪个套接字上,发生了什么网络事件类型。对事件数组中的事件进行引用时,应该用WSAWaitForMultipleEvents
的返回值,减去预定义的值 WSA_WAIT_EVENT_0,得到具体的引用值(即索引位置)。
Index = WSAWaitForMultipleEvents(...);
MyEvent =EventArray[Index - WSA_WAIT_EVENT_0];
通常,应用程序应将该参数设为 FALSE,一次只为一个套接字事件提供服务。
3)dwTimeout参数:规定了WSAWaitForMultipleEvents 最多可等待一个网络事件发生有多长时间,以毫秒为单位,这是一项“超时”设定。超过规定的时间,函数就会立即返回,即使由fWaitAll 参数规定的条件尚未满足也如此。考虑到它对性能造成的影响,应尽量避免将超时值设为0。假如没有等待处理的事件,WSAWaitForMultipleEvents便会返回WSA_WAIT_TIMEOUT。如 dwTimeout 设为WSAINFINITE(永远等待),那么只有在一个网络事件传信了一个事件对象后,函数才会返回。
4)fAlertable参数:在我们使用WSAEventSelect 模型的时候,它是可以忽略的,且应设为 FALSE。该参数主要用于在重叠式 I/O 模型中,在完成例程的处理过程中使用。
4)WSAEnumNetworkEvents
函数
定义:int WSAEnumNetworkEvents(
__in SOCKET s,
__in WSAEVENT hEventObject,
__out LPWSANETWORKEVENTS lpNetworkEvents
);
作用:知道了造成网络事件的套接字后,调用WSAEnumNetworkEvents 函数调查发生了什么类型的网络事件。
参数说明:
1)s
参数:对应于造成了网络事件的套接字。
2)hEventObject
参数:该参数是可选的;它指定了一个事件句柄,对应于打算重设的那个事件对象。由于我们的事件对象处在一个“已传信”状态,所以可将它传入,令其自动成为“未传信”状态。如果不想用
hEventObject 参数来重设事件,那么可使用WSAResetEvent
函数,见上述。
3)lpNetworkEvents参数:代表一个指针,指向 WSANETWORKEVENTS
结构,用于接收套接字上发生的网络事件类型以及可能出现的任何错误代码。对于该结构,可以看我另一篇文章。winsock 常用数据结构
应用举例:
if(NetwordEvents.lNetworkEvents & FD_READ)
{
if (NetworkEvents.iErrorCode[FD_READ_BIT]!= 0)
{
printf("FD_READ failed with error%d\n", NetworkEvents.iErrorCode[FD_READ_BIT]);
}
}
事件选择(WSAEventSelect)模型是另一个有用的异步I/O 模型。和WSAAsyncSelect 模型类似的是,它也允许应用程序在一个或多个套接字上,接收以事件为基础的网络事件通知,最主要的差别在于网络事件会投递至一个事件对象句柄,而非投递到一个窗口例程。
1、WSACreateEvent( )
定义:WSAEVENT WSACreateEvent(void);
作用:事件通知模型要求我们的应用程序针对使用的每一个套接字,首先创建一个事件对象。该函数返回一个创建好的事件对象句柄。
注释:WSACreateEvent 创建的事件有两种工作状态,以及两种工作模式。工作状态分别是“已传信”(signaled)和“未传信”(nonsignaled)。工作模式则包括“人工重设”(manualreset)和“自动重设”(autoreset)。
WSACreateEvent开始是在一种未传信的工作状态,并用一种人工重设模式,来创建事件句柄。随着网络事件触发了与一个套接字关联在一起的事件对象,工作状态便会从“未传信”转变成“已传信”。由于事件对象是在一种人工重设模式中创建的,所以在完成了一个 I/O 请求的处理之后,我们的应用程序需要负责将工作状态从已传信更改为未传信,可调用
WSAResetEvent 函数。
BOOLWSAResetEvent(
__in WSAEVENT hEvent //事件句柄;
);
应用程序完成了对一个事件对象的处理后,便应调用WSACloseEvent函数,释放由事件句柄使用的系统资源。
BOOLWSACloseEvent(
__in WSAEVENT hEvent //事件句柄;
);
2、WSAEventSelect
函数
定义:int WSAEventSelect(
__in SOCKET s, //代表感兴趣的套接字
__in WSAEVENT hEventObject, /*指定要与套接字关联在一起的事件对象,
即用WSACreateEvent 创建的那一个*/
__in long lNetworkEvents /*对应一个“位掩码”,用于指定应用程序感
兴趣的各种网络事件类型的一个组合。*/
);
作用:将事件与某个套接字关联在一起,同时注册自己感兴趣的网络事件类型。
参数lNetworkEvents可以用以下数值进行OR操作
FD_READ 应用程序想要接收有关是否可读的通知,以便读入数据
FD_WRITE 应用程序想要接收有关是否可写的通知,以便写入数据
FD_ACCEPT 应用程序想接收与进入连接有关的通知
FD_CONNECT 应用程序想接收与一次连接完成的通知
FD_CLOSE 应用程序想接收与套接字关闭的通知
一个套接字同一个事件对象句柄关联在一起后,应用程序便可开始I/O处理;方法是等待网络事件触发事件对象句柄的工作状态。
3、WSAWaitForMultipleEvents
函数
定义:DWORDWSAWaitForMultipleEvents(
__in DWORD cEvents,
__in const WSAEVENT* lphEvents,
__in BOOL fWaitAll,
__in DWORD dwTimeout,
__in BOOL fAlertable
);
参数描述:
1)cEvents和lphEvents 参数:定义了由 WSAEVENT 对象构成的一个数组,在这个数组中:
cEvents指定的是事件对象的数量;
lphEvents对应的是一个指针,用于直接引用该数组。
注:WSAWaitForMultipleEvents只能支持由WSA_MAXIMUM_WAIT_EVENTS 对象规定的一个最大值,在此定义成64个。因此,针对发出WSAWaitForMultipleEvents 调用的每个线程,该 I/O 模型一次最多都只能支持64个套接字。假如想让这个模型同时管理不止64个套接字,必须创建额外的工作者线程,以便等待更多的事件对象。
2)fWaitAll参数:指定了WSAWaitForMultipleEvents 如何等待在事件数组中的对象。
若设为TRUE,那么只有等lphEvents 数组内包含的所有事件对象都已进入“已传信”状态,函数才会返回;
若设为FALSE,任何一个事件对象进入“已传信”状态,函数就会返回。就后一种情况来说,返回值指出了到底是哪个事件对象造成了函数的返回。
当WSAWaitForMultipleEvents
收到一个事件对象的网络事件通知,便会返回一个值,指出造成函数返回的事件对象。这样一来,我们的应用程序便可引用事件数组中已传信的事件,并检索与那个事件对应的套接字,判断到底是在哪个套接字上,发生了什么网络事件类型。对事件数组中的事件进行引用时,应该用WSAWaitForMultipleEvents
的返回值,减去预定义的值 WSA_WAIT_EVENT_0,得到具体的引用值(即索引位置)。
Index = WSAWaitForMultipleEvents(...);
MyEvent =EventArray[Index - WSA_WAIT_EVENT_0];
通常,应用程序应将该参数设为 FALSE,一次只为一个套接字事件提供服务。
3)dwTimeout参数:规定了WSAWaitForMultipleEvents 最多可等待一个网络事件发生有多长时间,以毫秒为单位,这是一项“超时”设定。超过规定的时间,函数就会立即返回,即使由fWaitAll 参数规定的条件尚未满足也如此。考虑到它对性能造成的影响,应尽量避免将超时值设为0。假如没有等待处理的事件,WSAWaitForMultipleEvents便会返回WSA_WAIT_TIMEOUT。如 dwTimeout 设为WSAINFINITE(永远等待),那么只有在一个网络事件传信了一个事件对象后,函数才会返回。
4)fAlertable参数:在我们使用WSAEventSelect 模型的时候,它是可以忽略的,且应设为 FALSE。该参数主要用于在重叠式 I/O 模型中,在完成例程的处理过程中使用。
4)WSAEnumNetworkEvents
函数
定义:int WSAEnumNetworkEvents(
__in SOCKET s,
__in WSAEVENT hEventObject,
__out LPWSANETWORKEVENTS lpNetworkEvents
);
作用:知道了造成网络事件的套接字后,调用WSAEnumNetworkEvents 函数调查发生了什么类型的网络事件。
参数说明:
1)s
参数:对应于造成了网络事件的套接字。
2)hEventObject
参数:该参数是可选的;它指定了一个事件句柄,对应于打算重设的那个事件对象。由于我们的事件对象处在一个“已传信”状态,所以可将它传入,令其自动成为“未传信”状态。如果不想用
hEventObject 参数来重设事件,那么可使用WSAResetEvent
函数,见上述。
3)lpNetworkEvents参数:代表一个指针,指向 WSANETWORKEVENTS
结构,用于接收套接字上发生的网络事件类型以及可能出现的任何错误代码。对于该结构,可以看我另一篇文章。winsock 常用数据结构
应用举例:
if(NetwordEvents.lNetworkEvents & FD_READ)
{
if (NetworkEvents.iErrorCode[FD_READ_BIT]!= 0)
{
printf("FD_READ failed with error%d\n", NetworkEvents.iErrorCode[FD_READ_BIT]);
}
}
相关文章推荐
- [置顶] WinSock 异步I/O模型[3]---事件选择 - WSAEventSelect
- WSAEventSelect-事件通知模型
- WSAEventSelect模型 用法介绍
- 基于事件的select:WSAEventSelect模型
- WSAEventSelect模型 用法介绍
- Socket I/O模型之事件选择(WSAEventSelect)
- WinSock IO模型三: WSAEventSelect 事件机制
- WSAEventSelect函数模型
- WSAEventSelectI/O模型中FD_WRITE事件的处理以及如何发送数据
- 三、事件选择模型(WSAEventSelect)
- 多种SOKECT通讯模型的理解(select,WSAAsyncSelect,WSAEventSelect,Overlapped I/O 事件通知,Overlapped I/O 完成例程,IOCP)
- Socket I/O模型之事件选择(WSAEventSelect)(转)
- WSAEventSelect事件Select模型Client——》Server
- WSAEventselect模型中各网络事件触发机制
- (三)Socket I/O模型之事件选择(WSAEventSelect)
- WSAEventselect模型中的一些注意事项(尤其是event和事件的关联与重置;FD_WRITE事件的作用)
- Winsock异步模式I/O模型WSAEventSelect的使用及FD_WRITE事件的触发机制
- 很幽默的讲解六种Socket IO模型 Delphi版本(自己Select查看,WM_SOCKET消息通知,WSAEventSelect自动收取,Overlapped I/O 事件通知模型,Overlapped I/O 完成例程模型,IOCP模型机器人)
- Winsock的事件I/O异步模型——WSAEventSelect
- WinSock IO模型 -- WSAEventSelect模型事件触发条件说明