WSAEventSelect事件Select模型Client——》Server
2010-03-05 21:53
603 查看
////////////////////////////////////////////////// // WSAEventSelect文件 #include <winsock2.h> #pragma comment(lib, "WS2_32") class CInitSock { public: CInitSock(); ~CInitSock(); }; inline CInitSock::CInitSock() { // 初始化WS2_32.dll WSADATA wsaData; WORD sockVersion = MAKEWORD(2, 2); if(::WSAStartup(sockVersion, &wsaData) != 0) { exit(0); } } inline CInitSock::~CInitSock() { ::WSACleanup(); } #include <stdio.h> #include <iostream.h> #include <windows.h> // 初始化Winsock库 CInitSock theSock; int main1(); int main2(); void main() { printf("Please select a item:/n"); printf("s:Server/n"); printf("c:Client/n"); char a; while(1){ scanf("%c",&a); if(a=='s'){main1();break;} else if(a=='c'){main2();break;} else continue; } } int main1() { // 事件句柄和套节字句柄表 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函数会自动重置受信事件 WSANETWORKEVENTS event; ::WSAEnumNetworkEvents(sockArray[i], eventArray[i], &event); if(event.lNetworkEvents & FD_ACCEPT) // 处理FD_ACCEPT通知消息 { if(event.iErrorCode[FD_ACCEPT_BIT] == 0) { if(nEventTotal > WSA_MAXIMUM_WAIT_EVENTS) { printf(" Too many connections! /n"); 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]; char temp; int nRecv = ::recv(sockArray[i], szText, strlen(szText), 0); if(nRecv > 0) { temp=szText[nRecv]; szText[nRecv] = '/0'; printf("接收到数据:%s /n", szText); szText[nRecv]=temp; } } } else if(event.lNetworkEvents & FD_CLOSE) // 处理FD_CLOSE通知消息 { if(event.iErrorCode[FD_CLOSE_BIT] == 0) { ::closesocket(sockArray[i]); for(int j=i; j<nEventTotal-1; j++) { sockArray[j] = sockArray[j+1]; sockArray[j] = sockArray[j+1]; } nEventTotal--; } } else if(event.lNetworkEvents & FD_WRITE) // 处理FD_WRITE通知消息 { } } } } return 0; } //Client int main2() { // 创建套节字 SOCKET s = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(s == INVALID_SOCKET) { printf(" Failed socket() /n"); return 0; } // 也可以在这里调用bind函数绑定一个本地地址 // 否则系统将会自动安排 // 填写远程地址信息 sockaddr_in servAddr; servAddr.sin_family = AF_INET; servAddr.sin_port = htons(4567); // 注意,这里要填写服务器程序(TCPServer程序)所在机器的IP地址 // 如果你的计算机没有联网,直接使用127.0.0.1即可 servAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); if(::connect(s, (sockaddr*)&servAddr, sizeof(servAddr)) == -1) { printf(" Failed connect() /n"); return 0; } char szText[256]; while(TRUE){ scanf("%s",szText); //puts(szText); // 向服务器端发送数据 ::send(s, szText, strlen(szText), 0); } // 关闭套节字 ::closesocket(s); return 0; }
相关文章推荐
- [置顶] WinSock 异步I/O模型[3]---事件选择 - WSAEventSelect
- Winsock异步模式I/O模型WSAEventSelect的使用及FD_WRITE事件的触发机制
- WinSock IO模型 -- WSAEventSelect模型事件触发条件说明
- Socket I/O模型之事件选择(WSAEventSelect)
- WSAEventselect模型中各网络事件触发机制
- Socket I/O模型之事件选择(WSAEventSelect)
- WSAEventSelect(事件选择)模型
- Winsock的事件I/O异步模型——WSAEventSelect
- WSAEventSelect模型中FD_READ 网络事件的处理
- IO模型(二)WSAEventSelect--事件选择机制
- 很幽默的讲解六种Socket IO模型 Delphi版本(自己Select查看,WM_SOCKET消息通知,WSAEventSelect自动收取,Overlapped I/O 事件通知模型,Overlapped I/O 完成例程模型,IOCP模型机器人)
- WinSock IO模型三: WSAEventSelect 事件机制
- WinSock IO模型 -- WSAEventSelect模型事件触发条件说明
- 多种SOKECT通讯模型的理解(select,WSAAsyncSelect,WSAEventSelect,Overlapped I/O 事件通知,Overlapped I/O 完成例程,IOCP)
- 多种SOKECT通讯模型的理解(select,WSAAsyncSelect,WSAEventSelect,Overlapped I/O 事件通知,Overlapped I/O 完成例程,IOCP)
- 基于事件的select:WSAEventSelect模型
- WSAEventselect模型中的一些注意事项(尤其是event和事件的关联与重置;FD_WRITE事件的作用)
- WSAEventSelectI/O模型中FD_WRITE事件的处理以及如何发送数据
- WSAEventSelect-事件通知模型
- Socket I/O模型之事件选择(WSAEventSelect)(转)