异步事件模型

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;
}

你可能感兴趣的:(异步事件模型)