WSAEventSelect 是 WinSock 提供的一种异步事件通知I/O模型,
1、相关函数和结构:
函数:
WSACreateEvent创建一个事件对象;
WSAEventSelect指定要与指定的FD_XXX网络事件集关联的事件对象
WSAWaitForMultipleEvents等待事件对象数组上发生一个你感兴趣的网络事件;
WSAEnumNetworkEvents 对发生事件的事件对象查询具体发生的事件类型;
结构:
typedef struct _WSANETWORKEVENTS {
long lNetworkEvents;
int iErrorCode[FD_MAX_EVENTS];
} WSANETWORKEVENTS, FAR * LPWSANETWORKEVENTS;
2、SOCKET事件分为如下类型:
FD_READ ,想要接收阅读准备情况通知。
FD_WRITE ,想要接收编写准备情况的通知。
FD_OOB ,想要接收 OOB 数据的到达通知。
FD_ACCEPT,想要接收传入连接的通知。
FD_CONNECT ,想要接收已完成连接或多点联接操作的通知。
FD_CLOSE,想要接收套接字关闭通知。
FD_QOS ,想要接收套接字 (QoS 更改的通知。
FD_GROUP_QOS , 保留以供将来与套接字组一起使用。 想要接收套接字组 QoS 更改的通知。
FD_ROUTING_INTERFACE_CHANGE , 想要接收指定目标的路由接口更改通知。
FD_ADDRESS_LIST_CHANGE,想要接收套接字地址系列更改的本地地址列表更改通知。
3、各函数参考代码
SOCKET ListenSocket;
WSAEVENT NewEvent;
sockaddr_in InetAddr;
ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
NewEvent = WSACreateEvent();
WSAEventSelect( ListenSocket, NewEvent, FD_ACCEPT | FD_CLOSE);
WSAEVENT eventArray[WSA_MAXIMUM_WAIT_EVENTS]; // 事件对象数组
SOCKET sockArray[WSA_MAXIMUM_WAIT_EVENTS]; // 事件对象数组对应的SOCKET句柄
while (true)
{
int nIndex = ::WSAWaitForMultipleEvents(nEvent, eventArray, false, WSA_INFINITE, false);
WSANETWORKEVENTS event;
SOCKET sock = sockArray[nIndex];
::WSAEnumNetworkEvents(sock, eventArray[nIndex], &event);
if (event.lNetworkEvents & FD_ACCEPT) {
}
else if (event.lNetworkEvents & FD_READ) {
if (event.iErrorCode[FD_READ_BIT] == 0) {
int nRecv = ::recv(sock, buf, 2500, 0);
}
}
else if (event.lNetworkEvents & FD_CLOSE) {
::WSACloseEvent(eventArray[nIndex]);
::closesocket(sockArray[nIndex]);
}
else if (event.lNetworkEvents & FD_WRITE) {
}
}