⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 framework.h

📁 用c++编写的网络通信框架
💻 H
字号:
/*-----------------------------------------------------------------------------
 * FILE: framework.h
 * AUTH: xuwannian@gmail.com
 * TIME: 2008-04-29
 *---------------------------------------------------------------------------*/
#pragma warning (disable: 4430)
#pragma warning (disable: 4786)

#ifndef __FRAMEWORK_H__
#define __FRAMEWORK_H__

#ifdef _WIN32
#include <Windows.h>
#endif


#include "include/global.h"
#include "include/queue.h"
#include "include/exception.h"

#ifndef HOSTSTRUCT
typedef xuwn::HOSTSTRUCTSTRUCT<void* >	HOSTSTRUCT;
#endif

typedef xuwn::CList<HOSTSTRUCT>	HOSTSTRUCTS;


//////////////////////////////////////////////////////////////////////////
class CFramework
{
public:
			 CFramework();
	virtual ~CFramework();
public:
	BOOL Run(int argc, char** argv);
	void Close();
protected:
	// 添加路由信息到系统路表中
	inline int AddRoute(const HOSTSTRUCT& host__)
	{ return __route.put(host__.name, host__);	}
	inline int GetRoute(const char* key, HOSTSTRUCT& host__)
	{ return __route.get(key, host__, false);	}
	//  从系统路由表中删除指定的路由信息
	inline int EraseRoute(const char* key)
	{ return __route.erase(key);				}
protected:
	// 当连接到远程主机或远程主机连接本机时触发该方法
	virtual BOOL OnConnected(const HOSTSTRUCT& host__);
	// 当远程主机断开与本机的连接触发该方法
	virtual void OnDisconnected(const HOSTSTRUCT& host__);	
protected:
	// 初始化应用程序
	virtual BOOL InitApplication(int argc, char** argv);	
	// 销毁应用程序
	virtual void DestroyApplication();						
protected:
	// 当有消息可以接收时触发该方法
	virtual BOOL OnRecvData(const HOSTSTRUCT& host__, xuwn::MESSAGE& msg);		
protected:
	// 处理消息,用户需要重载该方法,应用自己的业务逻辑去处理
	// 收到的消息
	virtual void OnExecuteMessage(const xuwn::MESSAGE& message);	
protected:
	// 创建服务器端的线程,用户需要重载该方法,往hosts__中添加主机信息
	// 并调用CFramework::OnCreateServer(host__)去创建相应的线程
	virtual BOOL OnCreateServer(HOSTSTRUCTS& hosts__);
	// 创建客户端线程,用户需要重载该方法,往hosts__中添加主机信息
	// 并调用CFramework::OnCreateClient(hosts__)去创建相应的线程
	virtual BOOL OnCreateClient(HOSTSTRUCTS& hosts__);
	// 创建处理消息队列的线程,传入参数为线程数,默认线程数为128个处理线程
	virtual BOOL OnCreateDoMessage(int& nThreadCount);
	// 创建接收SOCKET消息的线程一,所创建的线程只接收作为服务器端时,
	// 其它客户端连接过来的SOCKET
	virtual BOOL OnCreateRecvMessage(int& nRecvThreadsCount);
protected:
	// 系统空闲时执行
	virtual void OnSysIdle(){}
private:
	// 序列化和反序列化
	void Serialize();
	void UnSerialize();
private:
	// 把线程添加到LIST进行控制
	inline void AddThreadToList(xuwn::thread* pthread)
	{ 
		xuwn::lock loc(__mutex_thrd);
		__threads.push_back(pthread); 
	}
private:
	// 创建线程相关方法
	// 该静态方法是为_beginthread调用
	// 参数为class ARGS 
	// 
	static void __cdecl create_server_thread(LPVOID args)
	{
		xuwn::ARGS<HOSTSTRUCT>* p = (xuwn::ARGS<HOSTSTRUCT>*)args;
		try
		{
			CFramework* pthis = (CFramework*)p->__h;
			if (pthis) pthis->__server_thread(p->__t);
		}
		catch (CException& e) 
		{
			e.ShowException();
		}
	};
	// 真正的服务线程
	void __server_thread(const HOSTSTRUCT& host__);

	// 创建线程相关方法
	// 该静态方法是为_beginthread调用
	// 参数为class ARGS 
	// 
	static void __cdecl create_client_thread(LPVOID args)
	{
		xuwn::ARGS<HOSTSTRUCT>* p = (xuwn::ARGS<HOSTSTRUCT>*)args;
		try
		{
			CFramework* pthis = (CFramework*)p->__h;
			if (pthis) pthis->__client_thread(p->__t);
		}
		catch (CException& e) 
		{
			e.ShowException();
		}
	};
	// 真正的服务线程
	void __client_thread(const HOSTSTRUCT& host__);
	
	// 创建接收消息的线程
	// 
	static void __cdecl create_recv_threads(LPVOID args)
	{
		CFramework* pthis = (CFramework*)args;
		try
		{
			if (pthis) pthis->__recv_thread();
		}
		catch (CException& e) 
		{
			e.ShowException();
		}
	}
	// 接收线程
	void __recv_thread();

	// 创建处理消息队列中的消息线程
	static void __cdecl create_do_message_threads(LPVOID args)
	{
		CFramework* pthis = (CFramework*)args;
		try
		{
			if (pthis) pthis->__do_message_thread();
		}
		catch (CException& e) 
		{
			e.ShowException();
		}
	}
	// 真正处理消息队列中的消息方法
	void __do_message_thread();
protected:
	// 判断是否是允许访问的主机
	// 如果是允许访问的主机,则将一些信息考贝到新主机信息中
	inline BOOL IsApplyHost(HOSTSTRUCT& host)
	{
		char key[64];
		::memset(key, 0, sizeof(key));
		::sprintf(key, "%s:%d", host.addr, host.port);

		HOSTSTRUCT a;
		int rc = __applys.get(key, a, false);

		// 表示允许主机访问列表中取到相应的主机信息
		if (rc == 0)
		{
			SOCKET fd = host.fd;
			::memcpy(&host, &a, sizeof(host));
			host.fd = fd;
			return TRUE;
		}
		else
		{
			return FALSE;
		}
	}
	
	// 往系统路由中添加允许访问的主机信息
	inline void AddApplyHost(const HOSTSTRUCT& host)
	{
		char key[64];
		::memset(key, 0, sizeof(key));
		::sprintf(key, "%s:%d", host.addr, host.port);
		__applys.put(key, host);
	}
private:
	std::list<xuwn::thread*>		__threads;		// 线程管理队列
	xuwn::CList<xuwn::MESSAGE >		__queue;		// 消息队列
	xuwn::CMap<HOSTSTRUCT  >		__route;		// 系统路由队列
	xuwn::CMap<HOSTSTRUCT  >		__applys;		// 允许访问的主机
	xuwn::CList<HOSTSTRUCT >		__socket_queue;	// SOCKET接收队列
	xuwn::mutex						__mutex_log;	// 日志互斥
	xuwn::mutex						__mutex_thrd;	// 线程互斥
	bool							__bexit;		// 退出标识
};	// END class CFramework


#endif	// END DEFINE

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -