windows socket网络编程--事件选择模型
作者:互联网
Winsock提供了另一种有用的异步事件通知I/O模型——WSAEventSelect模型。这个模型与WSAAsyncSelect模型类似,允许应用程序在一个或者多个套接字上接收基于事件的网络通知。它与 WSAAsyncSelect模型类似是因为它也接收FDXXX类型的网络事件,不过并不是依靠Windows的消息驱动机制,而是经由事件对象句柄通知
API详解
WSAEVENT WSAAPI WSACreateEvent();
返回值
如果未发生错误, WSACreateEvent 将返回事件对象的句柄。 否则,返回值WSA_INVALID_EVENT。
作用
创建新的事件对象
int WSAAPI WSAEventSelect(
SOCKET s, //标识套接字的描述符。
WSAEVENT hEventObject, //标识要与指定FD_XXX网络事件集关联的事件对象的句柄。
long lNetworkEvents//一个位掩码,指定应用程序感兴趣的FD_XXX网络事件的组合。
);
返回值
如果应用程序的网络事件的规范和关联的事件对象成功,则返回值为零。 否则,返回值SOCKET_ERROR。
作用
给事件绑上socket与操作码,并投递给操作系统,应用程序便可以在事件上等待了。
事件类型 | 含义 |
---|---|
FD_READ | 应用程序想接收是否有可读的通知 |
FD_WRITE | 应用程序想接收是否有可写的通知 |
FD_OOB | 应用程序想接收是否有OOB数据抵达通知 |
FD_ACCEPT | 应用程序想接收与传入连接有关的通知 |
FD_CONNECT | 应用程序想接收一个已完成连接的通知或者一个多点join操作的通知 |
FD_CLOSE | 应用程序想接收与套接字关闭有关的通知 |
DWORD WSAAPI WSAWaitForMultipleEvents(
DWORD cEvents,
const WSAEVENT *lphEvents,
BOOL fWaitAll,
DWORD dwTimeout,
BOOL fAlertable
);
cEvents
lphEvents 指向的数组中的事件对象句柄数。 事件对象句柄的最大数目 是WSA_MAXIMUM_WAIT_EVENTS。 必须指定一个或多个事件。
lphEvents
指向事件对象句柄数组的指针。 数组可以包含不同类型的对象的句柄。 如果 fWaitAll 参数设置为 TRUE,则它可能不包含同一句柄的多个副本。 如果在等待仍在挂起时关闭其中一个句柄,则未定义 WSAWaitForMultipleEvents 的行为。
fWaitAll
一个指定等待类型的值。 如果为 TRUE,则当 发出 lphEvents 数组中所有对象的状态时,函数将返回。 如果为 FALSE,则函数在发出任何事件对象的信号时返回。 在后一种情况下,返回值减 去WSA_WAIT_EVENT_0 指示导致函数返回其状态的事件对象的索引。 如果在调用期间发出了多个事件对象的信号,则这是信号事件对象的数组索引,其索引值为所有信号事件对象的最小索引值。
dwTimeout
超时间隔(以毫秒为单位)。 WSAWaitForMultipleEvents 如果超时间隔过期,即使 不满足 fWaitAll 参数指定的条件,也会返回。 如果 dwTimeout 参数为零, WSAWaitForMultipleEvents 将测试指定事件对象的状态并立即返回。 如果 dwTimeoutWSA_INFINITE, WSAWaitForMultipleEvents 将永远等待;也就是说,超时间隔永远不会过期。
fAlertable
一个值,该值指定线程是否处于可警报的等待状态,以便系统可以执行I/O完成例程。 如果为TRUE,则线程处于可警报的等待状态,当系统执行 I/O 完成例程时, WSAWaitForMultipleEvents 可以返回。 在这种情况下,将返回 WSA_WAIT_IO_COMPLETION ,并且等待的事件尚未发出信号。 应用程序必须再次调用 WSAWaitForMultipleEvents 函数。 如果为FALSE,则线程不会处于可警报的等待状态,并且不会执行 I/O 完成例程。
int WSAAPI WSAEnumNetworkEvents(
SOCKET s, //标识套接字
WSAEVENT hEventObject, //用于标识要重置的关联事件对象的可选句柄
LPWSANETWORKEVENTS lpNetworkEvents //指向 WSANETWORKEVENTS 结构的指针,该结构填充了发生的网络事件记录和任何关联的错误代码
);
返回值
如果操作成功,则返回值为零。 否则,返回值SOCKET_ERROR
作用
枚举出与事件对象相关联的套接字发生了哪些信号,结果放在WSANETWORKEVENTS结构体中
工作原理
流程大致是这样: