WSAEventSelect 模型
2014-11-20 16:08
302 查看
Winsock提供了另一种有用的异步事件通知
I/O模型——WSAEventSelect模型。这个模型与
WSAAsyncSelect模型类似,允许应用程序在一个或者多个套接字上接收基于事件的网络通知。它与
WSAAsyncSelect 模型类似是因为它也接收FD_XXX
类型的网络事件,不过并不是依靠Windows
的消息驱动机制,而是经由事件对象句柄通知。
I/O模型——WSAEventSelect模型。这个模型与
WSAAsyncSelect模型类似,允许应用程序在一个或者多个套接字上接收基于事件的网络通知。它与
WSAAsyncSelect 模型类似是因为它也接收FD_XXX
类型的网络事件,不过并不是依靠Windows
的消息驱动机制,而是经由事件对象句柄通知。
////////////////////////////////////////////////// // WSAEventSelect #include "../common/initsock.h" #include <stdio.h> #include <iostream.h> #include <windows.h> CInitSock initSock; // 初始化Winsock库 int main() { // 事件句柄和套接字句柄表 WSAEVENT eventArray[WSA_MAXIMUM_WAIT_EVENTS]; SOCKET sockArray[WSA_MAXIMUM_WAIT_EVENTS]; int nEventTotal = 0; USHORT nPort = 4567; // 服务器监听端口 // 创建监听套接字 SOCKET sListen = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); sockaddr_in sin; sin.sin_family = AF_INET; sin.sin_port = htons(nPort); sin.sin_addr.S_un.S_addr = INADDR_ANY; // 绑定端口 if (::bind(sListen, (sockaddr *)&sin, sizeof(sin)) == SOCKET_ERROR) { printf("Failed bind() \n"); return -1; } // 进入监听 ::listen(sListen, 5); // 创建事件对象,并关联到新的套接字 WSAEVENT event = ::WSACreateEvent(); // 将网络事件和事件对象关联起来; ::WSAEventSelect(sListen, event, FD_ACCEPT|FD_CLOSE); // 添加到表中 eventArray[nEventTotal] = event; sockArray[nEventTotal] = sListen; nEventTotal++; // 处理网络事件 while (TRUE) { // 在所有事件对象上等待,下面函数会等待网络事件发生 int nIndex = ::WSAWaitForMultipleEvents(nEventTotal, eventArray, FALSE, WSA_INFINITE, FALSE); // 对每个事件再次调用WSAWaitForMultipleEvents, 以便确定它们的状态; nIndex = nIndex - WSA_WAIT_EVENT_0; for(int i = nIndex; i <nEventTotal; i++) { nIndex = ::WSAWaitForMultipleEvents(1, &eventArray[i], TRUE, 1000, FALSE); if (nIndex == WSA_WAIT_FAILED || nIndex == WSA_WAIT_TIMEOUT) { continue; } else { // 获取到来的通知消息,WSAEnumNetworkEvents函数会自动重置受信事件; // 找到与之对应的套接字,WSAEnumNetworkEvents查看发生了什么网络事件; WSANETWORKEVENTS event; ::WSAEnumNetworkEvents(sockArray[i], eventArray[i], &event); if (event.lNetworkEvents & FD_ACCEPT) // 处理FD_ACCEPT通知消息 { if (event.iErrorCode[FD_ACCEPT_BIT] == 0) // FD_ACCEPT未出错 { if (nEventTotal > WSA_MAXIMUM_WAIT_EVENTS) { printf(" Too many connections"); continue; } SOCKET sNew = ::accept(sockArray[i], NULL, NULL); WSAEVENT event = ::WSACreateEvent(); ::WSAEventSelect(sNew, event, FD_READ|FD_CLOSE|FD_WRITE); eventArray[nEventTotal] = event; sockArray[nEventTotal] = sNew; nEventTotal++; } } else if (event.lNetworkEvents & FD_READ) // 处理FD_READ通知消息 { if (event.iErrorCode[FD_READ_BIT] == 0) { char szText[256]; int nRecv = ::recv(sockArray[i], szText, strlen(szText), 0); if (nRecv > 0) { szText[nRecv] = '\0'; printf("接受到数据:%s \n", szText); } } } else if (event.lNetworkEvents & FD_CLOSE) // 处理FD_CLOSE通知消息 { if (event.iErrorCode[FD_CLOSE_BIT] == 0) { ::closesocket(sockArray[i]); for(int j = i; j < nEventTotal; j++) // 删除数组元素; { sockArray[j] = sockArray[j+1]; } nEventTotal--; } } else if (event.lNetworkEvents & FD_WRITE) // 处理FD_WRITE通知消息 { } } } } return 0; }
相关文章推荐
- WinSock IO模型三: WSAEventSelect 事件机制
- 套接字IO模型(三) WSAEventSelect模型
- WSAEventSelect模型 ---应用实例,重写TCP服务器实例
- WSAEventSelect模型
- Winsock异步模式I/O模型WSAEventSelect的使用
- 三、事件选择模型(WSAEventSelect)
- 详细解析WSAEventSelect模型
- WSAEventSelect模型编程
- WsaEventSelect编程模型
- WSAEventSelect-事件通知模型
- (三)Socket I/O模型之事件选择(WSAEventSelect)
- 套接字I/O模型-WSAEventSelect(转载)
- 多种SOKECT通讯模型的理解(select,WSAAsyncSelect,WSAEventSelect,Overlapped I/O 事件通知,Overlapped I/O 完成例程,IOCP)
- 一个基于线程池的WSAEventSelect模型服务器设计
- [置顶] WinSock 异步I/O模型[3]---事件选择 - WSAEventSelect
- WSAEventSelect服务器模型
- 套接字的select、WsaAsyncSelect、WsaEventSelect模型
- vc++ windows socket I/O模型 WSAeventSelect 模型例子
- WSAEventSelect模型编程
- WSAEventSelect模型详解