异步选择模型

WSASelectSevere.h
#pragma once
#define UM_ACCEPT WM_USER+1
#define UM_TALKING WM_USER+2
#define UM_USER WM_USER+3
#include"MyThread.h"
class WSASelectSevere
{
public:
	WSASelectSevere(void);
	~WSASelectSevere(void);
public :
	bool StartSevere(HWND m_hWnd,short nPort=1234,CString nIp=_T("127.0.0.1"));
	void StopSevere();
	bool SendData(TCHAR *tzbuf,int nsize);
public:
	SOCKET SocketListen;
	HWND m_hParrentWnd;
	SOCKET SocketWaiter;
	CMyThread *m_thread;
public :
	void OnAccept(WPARAM wparam ,LPARAM lparam);
	void OnTalking(WPARAM wparam ,LPARAM lparam);
};
WSASelectSevere.cpp
#include "stdafx.h"
#include "WSASelectSevere.h"
#include"MyThread.h"
#include"MyWnd.h"
WSASelectSevere::WSASelectSevere(void)
{
	m_thread=NULL;
	SocketListen=NULL;
	SocketWaiter=NULL;
	m_hParrentWnd=NULL;
}


WSASelectSevere::~WSASelectSevere(void)
{
	StopSevere();
}
bool WSASelectSevere::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.注册事件
	//创建UI线程    1.需要一个线程类  CMyThread   继承   CwinThread
	//             2.需要一个窗口类  窗口类处理接收的消息     CMyWnd   继承   CFrameWnd
	//             3.在线程类中  CMyThread.cpp中的 InitStance 中   将  new CMyWnd   给  主窗口指针 
	//                            窗口指针  创建一个不带界面的窗口
	m_thread=(CMyThread *)AfxBeginThread(RUNTIME_CLASS(CMyThread));
	Sleep(1000);//等待窗口创建完成
	((CMyWnd*)m_thread->m_pMainWnd)->SetWSASelect(this);//将网络类的指针传到   窗口类中
	WSAAsyncSelect(SocketListen,m_thread->m_pMainWnd->m_hWnd,UM_ACCEPT,FD_ACCEPT);//注册接收的是事件
	              //将消息发送到窗口中处理
	return 1;
}
bool WSASelectSevere::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=0;i<m_num;i++)
	//{	
		if(SOCKET_ERROR==send(SocketWaiter,szbuf,nsize,0))
		{
			return false;
		}
	//}
	return true;
}
void WSASelectSevere::StopSevere()
{
	WSACleanup();
	if(SocketListen)
	{
		closesocket(SocketListen);
		SocketListen=NULL;
	}
	if(SocketWaiter)
	{
		closesocket(SocketWaiter);
		SocketWaiter=NULL;
	}
}
void WSASelectSevere::OnAccept(WPARAM wparam ,LPARAM lparam)
{
	SocketWaiter =accept(SocketListen,NULL/*客户端信息*/,NULL);
	if(SocketWaiter!=INVALID_SOCKET)
	{
		TCHAR szbuf[1024]=_T("服务器链接成功");
		SendMessage(m_hParrentWnd,UM_USER,(WPARAM)szbuf,1024);
		WSAAsyncSelect(SocketWaiter,m_thread->m_pMainWnd->m_hWnd,UM_TALKING,FD_READ|FD_WRITE|FD_CLOSE);//注册事件
	     //将消息发送到窗口中处理
	}
	
}
void WSASelectSevere::OnTalking(WPARAM wparam ,LPARAM lparam)
{
	SOCKET SocketTemp = (SOCKET)wparam;
	switch(LOWORD(lparam))
	{
	case FD_READ:
		{
			char szbuf[1024]={0};
			TCHAR tzbuf[1024]={0};	
			int nres =recv(SocketTemp,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(m_hParrentWnd,UM_USER,(WPARAM)tzbuf,1024);
				//pthis->m_lstbox.AddString(tzbuf);
			}
		}
		break;
	case FD_WRITE:
		{
			TRACE ("FD_WRITE \n");
		}
		break;
	case FD_CLOSE:
		{
			TRACE("FD_CLOSE \n");
		}
		break;
	}
}
MyWnd.h
#pragma once

#include"WSASelectSevere.h"
// CMyWnd 框架

class CMyWnd : public CFrameWnd
{
	DECLARE_DYNCREATE(CMyWnd)
public:
	CMyWnd();           
	virtual ~CMyWnd();

protected:
	DECLARE_MESSAGE_MAP()
public :
	LRESULT OnAccept(WPARAM wparam ,LPARAM lparam);
	LRESULT OnTalking(WPARAM wparam ,LPARAM lparam);//窗口处理网络事件
	void SetWSASelect(WSASelectSevere *severe)//获得网络类的指针
	{
		m_severe =severe;
	}
	WSASelectSevere *m_severe;
};
MyWnd.cpp
// MyWnd.cpp : 实现文件
//

#include "stdafx.h"
#include "severe.h"
#include "MyWnd.h"


// CMyWnd

IMPLEMENT_DYNCREATE(CMyWnd, CFrameWnd)

CMyWnd::CMyWnd()
{

}

CMyWnd::~CMyWnd()
{
}


BEGIN_MESSAGE_MAP(CMyWnd, CFrameWnd)
	ON_MESSAGE(UM_ACCEPT,&CMyWnd::OnAccept)
	ON_MESSAGE(UM_TALKING,&CMyWnd::OnTalking)
END_MESSAGE_MAP()

LRESULT CMyWnd::OnAccept(WPARAM wparam ,LPARAM lparam)//需要用到网络的中的东西太多  所以在网络类中  处理
{
	if(m_severe)
	{
		m_severe->OnAccept(wparam,lparam);
	}
	return 1l;
}
LRESULT CMyWnd::OnTalking(WPARAM wparam ,LPARAM lparam)
{
	if(m_severe)
	{
		m_severe->OnTalking(wparam,lparam);
	}
	return 1l;
}
// CMyWnd 消息处理程序
MyThread.h
#pragma once



// CMyThread

class CMyThread : public CWinThread
{
	DECLARE_DYNCREATE(CMyThread)

protected:
	CMyThread();           // 动态创建所使用的受保护的构造函数
	virtual ~CMyThread();

public:
	virtual BOOL InitInstance();
	virtual int ExitInstance();

protected:
	DECLARE_MESSAGE_MAP()
};
MyThred.cpp
// MyThread.cpp : 实现文件
//

#include "stdafx.h"
#include "severe.h"
#include "MyThread.h"
#include"MyWnd.h"

// CMyThread

IMPLEMENT_DYNCREATE(CMyThread, CWinThread)

CMyThread::CMyThread()
{
}

CMyThread::~CMyThread()
{
}

BOOL CMyThread::InitInstance()
{
	// TODO: 在此执行任意逐线程初始化
	m_pMainWnd=new CMyWnd;
	((CFrameWnd*)m_pMainWnd)->Create(NULL/*类的名字*/,_T("mywnd"));
	return TRUE;
}

int CMyThread::ExitInstance()
{
	// TODO: 在此执行任意逐线程清理
	return CWinThread::ExitInstance();
}

BEGIN_MESSAGE_MAP(CMyThread, CWinThread)
END_MESSAGE_MAP()


// CMyThread 消息处理程序

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值