MyWSAEventSelect.h #pragma once #define MAX_NUM 64 #define UM_USER WM_USER+1 class CMyWSAEventSelect { public: CMyWSAEventSelect(void); ~CMyWSAEventSelect(void); public : bool StartSevere(HWND m_hWnd,short nPort=1234,CString nIp=_T("127.0.0.1")); static DWORD WINAPI ThreadProc(LPVOID lpvoid); bool SendData(TCHAR *tzbuf,int nsize); void StopSevere(); public : HWND m_hParrentWnd; SOCKET SocketListen; HANDLE m_hEventQuit; HANDLE m_hEventQuitCheck; HANDLE m_hThread; WSAEVENT m_arryEvent[MAX_NUM]; SOCKET m_arrySocket[MAX_NUM]; SOCKET SocketWaiter[MAX_NUM]; int m_hEventNum; int m_hClientNum; }; MyWSAEventSelect.cpp #include "stdafx.h" #include "MyWSAEventSelect.h" CMyWSAEventSelect::CMyWSAEventSelect(void) { m_hEventQuit=NULL; m_hEventQuitCheck=NULL; m_hEventNum=0; m_hClientNum=0; ZeroMemory(SocketWaiter,sizeof(SocketWaiter)); ZeroMemory(m_arrySocket,sizeof(m_arrySocket)); } CMyWSAEventSelect::~CMyWSAEventSelect(void) { StopSevere(); } bool CMyWSAEventSelect::StartSevere(HWND m_hWnd,short nPort,CString nIp) { m_hParrentWnd=m_hWnd; //0.加载库 WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD( 2, 2 ); err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) { return 0; } if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 ) { WSACleanup( ); return 0; } //1.创建socket与外界通信的接口 SocketListen=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); if(INVALID_SOCKET==SocketListen) { StopSevere(); return 0; } //2.bind sockaddr_in addrsock; addrsock.sin_family=AF_INET; addrsock.sin_port=htons(nPort); char szbuf[1024]; #ifdef _UNICODE WideCharToMultiByte(CP_ACP,0,nIp,-1,szbuf,1024,0,0); #else strcpy_s(szbuf,1024,nIP); #endif addrsock.sin_addr.s_addr=inet_addr(szbuf); int nsize=sizeof(sockaddr_in); if(SOCKET_ERROR==bind(SocketListen,(const struct sockaddr*)&addrsock,nsize)) { StopSevere(); return 0; } //3.listen 监听 if(SOCKET_ERROR==listen(SocketListen,10)) { StopSevere(); return 0; } //4.插入异步事件模型 WSAEVENT we=WSACreateEvent();//创建事件 if(!WSAEventSelect(SocketListen,we,FD_ACCEPT)) { m_arryEvent[m_hEventNum]=we;//放到事件数组 m_arrySocket[m_hEventNum]=SocketListen;//放到Socket数组 m_hEventNum++; } m_hThread=::CreateThread(NULL,0,&CMyWSAEventSelect::ThreadProc,this,0,NULL);//创建线程 return true; } void CMyWSAEventSelect::StopSevere() { WSACleanup(); if(SocketListen) { closesocket(SocketListen); SocketListen=NULL; } SetEvent(m_hEventQuit); if( WAIT_OBJECT_0 != WaitForSingleObject(m_hEventQuit,INFINITE)) { ::TerminateThread(m_hThread,-1); m_hThread=NULL; } for(int i=0;i<m_hEventNum;i++) { closesocket(m_arrySocket[i]); m_arrySocket[i]=NULL; } for(int i=0;i<m_hClientNum;i++) { closesocket(SocketWaiter[i]); SocketWaiter[i]=NULL; } } bool CMyWSAEventSelect::SendData(TCHAR *tzbuf,int nsize) { if(!tzbuf||nsize<0) { return false; } char szbuf[1024]={0}; #ifdef _UNICODE WideCharToMultiByte(CP_ACP,0,tzbuf,-1,szbuf,1024,0,0); #else strcpy_s(szbuf,1024,tzbuf); #endif for(int i=1;i<m_hEventNum;i++) { if(SOCKET_ERROR==send(m_arrySocket[i],szbuf,nsize,0)) { return false; } } return true; } DWORD WINAPI CMyWSAEventSelect::ThreadProc(LPVOID lpvoid) { CMyWSAEventSelect *pthis=(CMyWSAEventSelect*)lpvoid; WSANETWORKEVENTS wwe;//判断是什么网络事件 while(1) { if( WAIT_OBJECT_0 == WaitForSingleObject(pthis->m_hEventQuit,100))//线程退出 { break; } //等待注册的事件 DWORD index; index = WSAWaitForMultipleEvents(pthis->m_hEventNum,pthis->m_arryEvent, FALSE, WSA_INFINITE, TRUE); if(index == WSA_WAIT_FAILED) { continue; } index-=WSA_WAIT_EVENT_0;//事件数组下标 //判断是什么网络事件 if(!WSAEnumNetworkEvents(pthis->m_arrySocket[index],pthis->m_arryEvent[index],&wwe)) { if(wwe.lNetworkEvents&FD_ACCEPT)//接收事件 { if(wwe.iErrorCode[FD_ACCEPT_BIT]!=0) { continue; } //accept pthis->SocketWaiter[pthis->m_hClientNum]=accept(pthis->m_arrySocket[index],NULL,NULL); WSAEVENT we=WSACreateEvent(); //插入异步事件模型 if(!WSAEventSelect(pthis->SocketWaiter[pthis->m_hClientNum],we,FD_READ|FD_CLOSE|FD_WRITE)) { pthis->m_arryEvent[pthis->m_hEventNum]=we; pthis->m_arrySocket[pthis->m_hEventNum]=pthis->SocketWaiter[pthis->m_hClientNum]; pthis->m_hEventNum++; pthis->m_hClientNum++; } } if(wwe.lNetworkEvents &FD_READ) { if(wwe.iErrorCode[FD_READ_BIT]!=0) { continue; } char szbuf[1024]={0}; TCHAR tzbuf[1024]={0}; int nres =recv(pthis->m_arrySocket[index],szbuf,1024,0); if(0!=nres &&SOCKET_ERROR !=nres) { #ifdef _UNICODE MultiByteToWideChar(CP_ACP,0,szbuf,-1,tzbuf,1024); #else strcpy_s(tzbuf,1024,szbuf); #endif SendMessage(pthis->m_hParrentWnd,UM_USER,(WPARAM)tzbuf,1024); } } if(wwe.lNetworkEvents &FD_WRITE) { if(wwe.iErrorCode[FD_WRITE_BIT]!=0) { continue; } TRACE("FD_WRITE \n"); } } } SetEvent(pthis->m_hEventQuitCheck); return 0; }