引子:
WSAEventSelect模型
该模型与WSAAsyncSelect模型类似,允许应用程序在一个或者多个套接字上接收基于事件的网络通知。
不过它并不是依靠Windows的消息驱动机制,
而是经由事件对象句柄通知。
- 使用这个模型的基本思路是为感兴趣的一组网络事件创建一个事件对象,再调用WSAEventSelect函数将网络事件和事件对象关联起来。
- 当网络事件发生时,Winsock使相应的事件对象受信,在事件对象上等待的函数就会返回。
- 之后再调用WSAEnumNetworkEvents函数就可以获知到底发生了什么网络事件。
- 最后便可以根据具体的网络事件类型来对其进行具体处理啦。
WSAEVENT WSACreateEvent (void); //返回一个事件对象的句柄
int WSAEventSelect(
SOCKER s, // 套接字句柄
WSAEVENT hEventObject, //事件对象句柄
long lNetworkEvents //感兴趣的网络事件的组合
);
- 在网络事件和事件对象关联之后,应用程序便可以在事件对象上等待了。
- Winsock提供了WSAWaitForMultipleEvents函数在一个或多个事件对象上等待,当所等待的事件受信或者超过指定的时间时,此函数返回。
DWORD WSAWaitForMultipleEvents(
DWORD cEvents, //指向下面lphEvents所指的数组中事件对象句柄的个数
const WSAEVENT* lphEvents, //指向一个事件对象句柄的数组的指针
BOOL fWaitAll, //指定是否等待所有事件对象都变成受信状态
DWORD dwTimeout, //指定要等待的时间,WSA_INFINITE为无穷大
BOOL fAlertable //在使用WSAEventSelect模型时可以忽略,应设为FALSE
);
一旦事件对象受信,那么找到与之对应的套接字,然后调用WSAEnumNetworkEvents函数就可以查看到底发生了什么类型的网络事件。
int WSAEnumNetworkEvents(
SOCKETR s, //套接字句柄
WSAEVENT hEventObjecj, //和套接字对应的事件对象句柄
LPWSANETWORKEVENTS lpNetworkEvents //指向一个WSANETWORKEVENTS结构
);
typedef struct_WSANETWORKEVENTS{
long lNetworkEvents; //指定已经发生的网络事件
int iErrorCode[FD_MAX_EVENTS]; //与lNetworkEvents相关的出错代码
}WSANETWORKEVENTS, *LPWSANETWORKEVENTS;