libevent windows多线程

#pragma once
#include <event2/bufferevent.h>
#include <event2/bufferevent_compat.h>
#include <event2/buffer.h>
#include <event2/listener.h>
#include <event2/util.h>
#include <event2/event.h>
#include <event2/http.h>
#include <event2/buffer_compat.h>
#include <event2/http_struct.h>
#include <event2/bufferevent.h>
#include <event2/thread.h>

#include "CProtocol.h"

#include "base\packet\PacketUtil.h"
#include "base\packet\Packet.h"
//#include <hash_map>

//using namespace stdext;
struct _Conn;
struct _Worker;

//服务器属性封装对象
struct _Server
{
	bool bStart;					//服务器是否已经启动
	short nPort;					//服务器端口
	short workernum;				//工作线程
	unsigned int connnum;			//每个工作线程,可以连接的数量
	volatile int nCurrentWorker;	//当前线程的Worker数量
	int read_timeout;				//读数据的超时时间
	int write_timeout;				//写数据的超时时间
	struct evconnlistener *pListener;	//监听事件
	struct event_base *pBase;			//服务器主程事件组
	HANDLE hThread;						//服务器线程
	_Worker *pWorker;					//工作线程表		
};
//连接对象列表
struct _ConnList
{
	_ConnList()
	{
		head=NULL;
		tail=NULL;
		plistConn=NULL;
	}
	_Conn *head;
	_Conn *tail;
	_Conn *plistConn;
};
//连接对象
struct _Conn
{
	_Conn()
	{
		fd=NULL;
		bufev=NULL;
		index=-1;
		in_buf_len=0;
		out_buf_len=0;
		owner = NULL;
		next = NULL;
		in_buf = new char[emMaxBuffLen];
		out_buf = new char[emMaxBuffLen];
	}
	~_Conn()
	{
		delete[]in_buf;
		delete[]out_buf;
		bufferevent_free(bufev);
	}
	struct bufferevent *bufev;
	evutil_socket_t fd;
	int index;
	char *in_buf;
	short in_buf_len;
	char *out_buf;
	short out_buf_len;
	_Worker *owner;
	_Conn *next;
};
//工作线程封装对象.
struct _Worker
{
	_Worker()
	{
		pWokerbase=NULL;
		hThread = INVALID_HANDLE_VALUE;
		pListConn=NULL;
	}
	struct event_base *pWokerbase;
	HANDLE hThread;
	_ConnList *pListConn;
	inline _Conn* GetFreeConn()
	{
		_Conn* pItem=NULL;
		if(pListConn->head != pListConn->tail)
		{
			pItem=pListConn->head;

			printf("pItem addr:%d\n", pItem);

			pListConn->head = pListConn->head->next;
		}
		if (pItem == NULL)
		{
			printf("connection reach max connection num\n");
		}
		return pItem;
	}
	inline void PutFreeConn(_Conn *pItem)
	{
		if (pItem)
		{
			printf("Close Conn Free Connecton! fd=%d\n", pItem->fd);
		}
		pListConn->tail->next=pItem;
		pListConn->tail=pItem;
	}
};

typedef struct _Server Server;
typedef struct _Worker Worker;
typedef struct _Conn Conn;
typedef struct _ConnList ConnList;

  

#pragma once
typedef enum HeadStx
{
	CHECKSTX = 860805
};
typedef enum emConfig
{
	emMaxBuffLen = 8192,
	emMaxPackageType = 65535
};
//命令号
typedef enum emFunID
{
	emFunNull = -1,
	emFunClosed = 0,
	emFunTimeout = 1,
	emFunError = 2,
	emFunConnected = 3,
	emFunDisConnected = 4,

	emFunBase = 1000,
	//emFunLogin = emFunBase + 1,
	LOGIN_CS_IN = emFunBase + 1,
	//int uid;	//用户名

	LOGIN_SC_IN = emFunBase + 2,
	//int uid;

	LOGIN_CS_OUT = emFunBase + 3,

	LOGIN_SC_OUT = emFunBase + 4,

	CONNECT_SC_CLOSE = emFunBase + 5,

	emFunLogout = emFunBase + 6
};

typedef enum emFunReturn
{
	emFunReturClose=1,
	emFunReturnSend,
	emFunReturnRecv
};
/************************************************************************/
/* 包头                                                                 */
/************************************************************************/
typedef struct _Head 
{
	int stx;
	int pkglen;
	int nFunID;
	_Head()
	{
		stx = 0;
		pkglen = 0;
		nFunID = 0;
	}
}Head,*PHead;

/************************************************************************/
/* 用户登录协议                                                         */
/************************************************************************/
typedef struct _Proto_Login_Req
{
	int uid;	//用户名
}Proto_Login_Req,*PProto_Login_Req;

typedef struct _Proto_Login_Rsp
{
	int uid;
}Proto_Login_Rsp,*PProto_Login_Rsp;


/************************************************************************/
/* 登出协议                                                             */
/************************************************************************/
typedef struct _ProtoLogout_Req
{
}ProtoLogout_Req,*PProtoLogout_Req;

  

#pragma once
#include "CLibEventData.h"
#include "LibEventFunction.h"
#include "LibUserFunction.h"

class CLibEvent
{
public:
	CLibEvent(void);
	~CLibEvent(void);
private:
	//当前服务器对象
	Server m_Server;
public:
	bool StartServer(int port, short workernum, unsigned int connnum, int read_timeout, int write_timeout);
	void StopServer();
private:
	void LoadFuns();
	static void DoAccept(struct evconnlistener *listener, evutil_socket_t fd,struct sockaddr *sa, int socklen, void *user_data);
	static void DoError(struct bufferevent *bev, short error, void *ctx);
	static void CloseConn(Conn *pConn,int nFunID);
	static void CloseConn(Conn *pConn);
	static void TimeOut(Conn *pConn, int nFunID);
	static void TimeOut(Conn *pConn);
	static int DispatchFunction(struct bufferevent *bev, CPacketHead* header, Conn *pConn);
	static void DoRead(struct bufferevent *bev, void *ctx);

	static void SetConnTimeOut(struct bufferevent *bev, timeval& timeOutRead, timeval& timeOutWrite);

	static void DeleteSingleton();

	static DWORD WINAPI ThreadServer(LPVOID lPVOID);
	static DWORD WINAPI ThreadWorkers(LPVOID lPVOID);
};

  

#include "StdAfx.h"
#include "LibEventFunction.h"

lpFunPtr CLibEventFunction::m_FunPtrList[emMaxPackageType]={0};
int CLibEventFunction::m_stx=0;

CLibEventFunction::CLibEventFunction(void)
{
}

CLibEventFunction::~CLibEventFunction(void)
{
}

void CLibEventFunction::RegistFunc(int id, lpFunPtr func)
{
	m_FunPtrList[id] = func;
}

void CLibEventFunction::RegistConnectedFunc(lpFunPtr func)
{
	m_FunPtrList[emFunConnected]=func;
}

void CLibEventFunction::RegistDisconnectedFunc(lpFunPtr func)
{
	//m_FunPtrList[emFunTimeout] = func;
	//m_FunPtrList[emFunClosed] = func;
	//m_FunPtrList[emFunError] = func;
	m_FunPtrList[emFunDisConnected] = func;
	
}

void CLibEventFunction::RegistTimeoutFunc(lpFunPtr func)
{
	m_FunPtrList[emFunTimeout] = func;
}

void CLibEventFunction::RegistClosedFunc(lpFunPtr func)
{
	m_FunPtrList[emFunClosed] = func;
}

void CLibEventFunction::RegistErrorFunc(lpFunPtr func)
{
	m_FunPtrList[emFunError]=func;
}

void CLibEventFunction::RegistStx(int stx)
{
	m_stx=stx;
}

int CLibEventFunction::LoadStx()
{
	return m_stx;
}

int CLibEventFunction::DispatchFunction(int nFunID,Conn*pItem)
{
	bool bFind = 0;
	if (m_FunPtrList[nFunID])
	{
		bFind = 1;
		if (pItem)
		{
			return m_FunPtrList[nFunID](pItem);
		}		
	}
	return bFind;
}

  

#pragma once
#include "CLibEventData.h"
#include "LibUserFunction.h"
#include <map>
using namespace std;

class CLibEventFunction
{
public:
	CLibEventFunction(void);
	~CLibEventFunction(void);
public:	
	/************************************************************************/
	/* 注册业务处理函数                                                     */
	/************************************************************************/
	static void RegistFunc(int id, lpFunPtr func);
	/************************************************************************/
	/* 注册接受客户端连接时响应函数                                         */
	/************************************************************************/
	static void RegistConnectedFunc(lpFunPtr func);
	/************************************************************************/
	/* 注册客户端断开处理函数                                               */
	/************************************************************************/
	static void RegistDisconnectedFunc(lpFunPtr func);
	/************************************************************************/
	/* 注册网络超时处理函数                                                 */
	/************************************************************************/
	static void RegistTimeoutFunc(lpFunPtr func);
	/************************************************************************/
	/* 注册客户端连接关闭处理函数                                           */
	/************************************************************************/
	static void RegistClosedFunc(lpFunPtr func);
	/************************************************************************/
	/* 注册网络错误处理函数                                                 */
	/************************************************************************/
	static void RegistErrorFunc(lpFunPtr func);
	/************************************************************************/
	/* 注册用户自定义头部的同步密码                                         */
	/************************************************************************/
	static void RegistStx(int stx);
	/************************************************************************/
	/* 注册用户自定义头部的同步密码                                         */
	/************************************************************************/
	static int LoadStx();
public:	
	static int DispatchFunction(int nFunID,Conn*pItem);
private:
	static lpFunPtr m_FunPtrList[emMaxPackageType];
	static int m_stx;
};

  

#pragma once
#include "CLibEventData.h"

class CLibUserFunction
{
public:
	CLibUserFunction(void);
	~CLibUserFunction(void);
public:
	static int Connect(Conn* c);
	static int DisConnect(Conn* c);
	static int TimeOut(Conn* c);
	static int Login(Conn* c);
	static int Logout(Conn* c);
};
//回调函数指针
typedef int (*lpFunPtr)(Conn* c);

  

#include "StdAfx.h"
#include "LibUserFunction.h"
#include "LibEvent.h"
#include "base\packet\JobDBQueueEx.h"

#include "..\Model.h"

CLibUserFunction::CLibUserFunction(void)
{
}

CLibUserFunction::~CLibUserFunction(void)
{
}

int CLibUserFunction::Connect(Conn* c)
{
	static int iConnectNum = 0;
	iConnectNum++;
	printf("CLibUserFunction::Connect =%d\n", iConnectNum);
	return 0;
}

int CLibUserFunction::DisConnect(Conn* c)
{
	printf("CLibUserFunction::Disconnect: %d\n", c->fd);
	return 0;
}

int CLibUserFunction::TimeOut(Conn* c)
{
	printf("CLibUserFunction::TimeOut: %d\n", c->fd);
	return 0;
}

int CLibUserFunction::Login(Conn* c)
{

	CPacketHead *hreq = (CPacketHead*)c->in_buf;

	int PersonStrLen = c->in_buf_len - sizeof(CPacketHead);

	char szBuffer[8196] = {0};

	memcpy(szBuffer, c->in_buf + sizeof(CPacketHead), PersonStrLen);
	std::string strBuffer = szBuffer;

	
	Login::Login_CS loginCS;
	loginCS.ParseFromString(strBuffer);

	printf("Client Login: fd=%d,username=%s,PWD=%s,type=%d\n", c->fd, loginCS.username().c_str(), loginCS.userpassword().c_str()
		, loginCS.isercettype());


	//操作数据库验证
	CJobDBMsg* pJobMsg = GetDBJobQueueEx()->AllocDBJobMsg();
	if (!pJobMsg) 
		return 0;
	int iSerectType = loginCS.isercettype();
	char szUserName[MAX_NAME_LEN] = {0};
	char szUserPWD[MAX_PWD_LEN] = { 0 };
	int iLen = loginCS.username().size() > MAX_NAME_LEN ? MAX_NAME_LEN : loginCS.username().size();
	memcpy(szUserName, loginCS.username().c_str(), iLen);

	iLen = loginCS.userpassword().size() > MAX_PWD_LEN ? MAX_PWD_LEN : loginCS.userpassword().size();
	memcpy(szUserPWD, loginCS.userpassword().c_str(), iLen);

	int iConnectFD = c->fd;			//服务器唯一标识
	bool bAdd = false;

	pJobMsg->Init(ACCOUNT_SD_AUTH);
	pJobMsg->PushBack(iConnectFD);
	pJobMsg->PushBack(szUserName, MAX_NAME_LEN);
	pJobMsg->PushBack(szUserPWD, MAX_PWD_LEN);
	pJobMsg->PushBack(iSerectType);
	bAdd = GetDBJobQueueEx()->AddDBJobMsg(pJobMsg);
	
	if (!bAdd)
	{
		GetDBJobQueueEx()->FreeDBJobMsg(pJobMsg);
	}
	
	return LOGIN_SC_IN;
}


int CLibUserFunction::Logout(Conn* c)
{
	printf("Logout: %d\n", c->fd);
	return CONNECT_SC_CLOSE;
}

  

猜你喜欢

转载自www.cnblogs.com/xsad2012/p/9265720.html