libevent封装

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lightjia/article/details/83181778

EvDefine.h

#ifndef __CEVUDEFINE__H_
#define __CEVUDEFINE__H_
#if defined(WIN32) || defined(_WIN32)
#include <winsock2.h>  
#elif  __linux__
#endif

#if defined(WIN32) || defined(_WIN32)
typedef SOCKET ev_fd;
#elif  __linux__
typedef int ev_fd;
#endif

#define EV_DEFAULT_BUFFER_LEN	1024*1024*10
typedef int(*ev_msg_cb)(ev_fd iFd, char* pMsg, size_t pLen, void* pUser, void* pUserParam, struct sockaddr_in* pAddr);
#endif

EvBase.h

#ifndef __CEVBASE__H_
#define __CEVBASE__H_
#include "CThread.h"
#include <event2/event-config.h>  
#include <event.h>
#include <evutil.h>
#include <map>
//#include "util-internal.h"

using namespace std;
typedef void(*ev_cb)(evutil_socket_t, short, void *);

struct ev_param
{
	ev_param()
	{
		pEvent = nullptr;
		pCb = nullptr;
		pCbParam = nullptr;
	}

	struct event *pEvent;
	ev_cb pCb;
	void* pCbParam;
};

struct ev_ctl
{
	ev_param pReadEv;
	ev_param pWriteEv;
	ev_param pTimeOutEv;
	time_t iLastOper;	//上一次读写操作时间
};

class CEvBase : public CThread
{
public:
	CEvBase();
	~CEvBase();

public:
	int StopBaseLoop();
	int StartBaseLoop();
	int AddFd(const evutil_socket_t iFd, ev_cb pReadCb, void* pReadParam, ev_cb pWriteCb, void* pWriteParam, ev_cb pTimeoutCb, void* pTimeoutParam, timeval* pTimeVal = nullptr);
	int DelFd(const evutil_socket_t iFd);
	int Write(evutil_socket_t iFd, const char* pData, size_t iDataLen);	//发送TCP数据
	int Write(evutil_socket_t iFd, struct sockaddr* pAddr, int iSockLen, const char* pData, size_t iDataLen);	//发送UDP数据
	struct event_base* GetBase(){ return m_pEvBase; }
	int UpdateActiveTime(const evutil_socket_t iFd);
	time_t GetActiveTime(const evutil_socket_t iFd);

public:
	static void TimeOutCb(evutil_socket_t fd, short event, void* arg);

protected:
	virtual void* work();

private:
	ev_ctl* FindEvCtl(evutil_socket_t iFd);

private:
	bool m_bInit;
	struct event_base *m_pEvBase;
	struct event* m_pTimeoutEvent;
	map<evutil_socket_t, ev_ctl> m_mapEvCtl;
};
#endif

EvServer.h

#ifndef __EVSERVER__H_
#define __EVSERVER__H_
#include "EvBase.h"
#include "EvDefine.h"

class CEvServer
{
public:
	CEvServer();
	virtual ~CEvServer();

public:
	virtual int Init(const short sListenPort, ev_msg_cb pMsgCb = nullptr) = 0;
	int Stop();
	int RegMsgCb(ev_msg_cb pMsgCb, void* pUser, void* pUserParam);
	virtual int Write(evutil_socket_t iFd, char* pData, size_t iDataLen, void* pParam) = 0;
	virtual bool IsParamAddr() = 0;

public:
	static void ReadCb(evutil_socket_t iFd, short events, void *arg);//Tcp是accept Udp是接收
	static void WriteCb(evutil_socket_t iFd, short events, void *arg);
	static void TimeoutCb(evutil_socket_t iFd, short events, void *arg);

protected:
	virtual int DoRead(evutil_socket_t iFd, short events, void *arg) = 0;
	virtual int DoWrite(evutil_socket_t iFd, short events, void *arg) = 0;
	virtual int DoClose(evutil_socket_t iFd, short events, void *arg) = 0;
	virtual int DoTimeout(evutil_socket_t iFd, short events, void *arg) = 0;

protected:
	ev_msg_cb m_pMsgCb;
	void* m_pUser;
	void* m_pUsrParam;
	bool m_bInit;
	short m_sListenPort;
	evutil_socket_t m_iListenFd;
	CEvBase* m_pListenEvBase;
	char* m_pBuf;
};

#endif

EvTcpServer.h

#ifndef __CEVTCPSERVER__H_
#define __CEVTCPSERVER__H_
#include "EvServer.h"

class CEvTcpServer : public CEvServer
{
public:
	CEvTcpServer();
	~CEvTcpServer();

public:
	int Init(const short sListenPort, ev_msg_cb pMsgCb = nullptr);
	int Write(evutil_socket_t fd, char* pData, size_t iDataLen, void* pParam);
	bool IsParamAddr(){ return false; }

protected:
	int DoRead(evutil_socket_t iFd, short events, void *arg);
	int DoWrite(evutil_socket_t iFd, short events, void *arg);
	int DoClose(evutil_socket_t iFd, short events, void *arg);
	int DoTimeout(evutil_socket_t iFd, short events, void *arg);
};

#endif

EvUdpServer.h

#ifndef __CEVUDPSERVER__H_
#define __CEVUDPSERVER__H_
#include "EvServer.h"

class CEvUdpServer : public CEvServer
{
public:
	CEvUdpServer();
	~CEvUdpServer();

public:
	int Init(const short sListenPort, ev_msg_cb pMsgCb = nullptr);
	int Write(evutil_socket_t fd, char* pData, size_t iDataLen, void* pParam);
	bool IsParamAddr(){ return true; }

protected:
	int DoRead(evutil_socket_t iFd, short events, void *arg);
	int DoWrite(evutil_socket_t iFd, short events, void *arg);
	int DoClose(evutil_socket_t iFd, short events, void *arg);
	int DoTimeout(evutil_socket_t iFd, short events, void *arg);
};

#endif

EvSerMgr.h

#ifndef __EVSERMGR__H_
#define __EVSERMGR__H_
#include "singleton.h"
#include "EvTcpServer.h"
#include "EvUdpServer.h"
#include <map>
using namespace std;

#define DEFAULT_LISTEN_PORT 8100
struct tagEvServerInfo
{
	tagEvServerInfo()
	{
		pEvTcpSer = nullptr;
		pEvUdpSer = nullptr;
	}
	CEvServer* pEvTcpSer;
	CEvServer* pEvUdpSer;
};

class CEvSerMgr :public CSingleton<CEvSerMgr>
{
	SINGLE_CLASS_INITIAL(CEvSerMgr);
public:
	~CEvSerMgr();
	CEvTcpServer* AddTcpServer(const short sPort = DEFAULT_LISTEN_PORT);
	CEvUdpServer* AddUdpServer(const short sPort = DEFAULT_LISTEN_PORT);
	int StopTcpServer(const short sPort = DEFAULT_LISTEN_PORT);
	int StopUdpServer(const short sPort = DEFAULT_LISTEN_PORT);
	int StopAllServer();

private:
	tagEvServerInfo* GetServerInfo(const short sPort);

private:
	map<short, tagEvServerInfo*> m_mapServer;
	CMutex m_cMutex;
};

#define sEvSerMgr CEvSerMgr::Instance()
#endif

EvCli.h

#ifndef __EVCLI__H_
#define __EVCLI__H_
#include "EvBase.h"
#include "EvDefine.h"
#include <string>

using namespace std;
class CEvCli
{
public:
	CEvCli();
	virtual ~CEvCli();

public:
	virtual int Init(const char* pIp, const short sSerPort, CEvBase* pBase) = 0;
	int Stop();
	int RegMsgCb(ev_msg_cb pMsgCb, void* pUser, void* pUserParam);
	virtual int Write(const char* pData, size_t pDataLen) = 0;

public:
	static void ReadCb(evutil_socket_t iFd, short event, void *arg);
	static void TimeoutCb(evutil_socket_t iFd, short events, void *arg);

protected:
	virtual int DoRead() = 0;
	virtual int DoClose() = 0;
	virtual int DoTimeout() = 0;

protected:
	ev_msg_cb m_pMsgCb;
	void* m_pUser;
	void* m_pUserParam;
	bool m_bInit;
	string m_strSerIp;
	short m_sSerPort;
	evutil_socket_t m_iCliFd;
	CEvBase* m_pEvBase;
	char* m_pBuf;
};

#endif

EvTcpCli.h

#ifndef __CEVTCPCLI__H_
#define __CEVTCPCLI__H_
#include "EvCli.h"

class CEvTcpCli : public CEvCli
{
public:
	CEvTcpCli();
	~CEvTcpCli();

public:
	int Init(const char* pIp, const short sSerPort, CEvBase* pBase);
	int Write(const char* pData, size_t pDataLen);

protected:
	int DoRead();
	int DoClose();
	int DoTimeout();
};

#endif

EvUdpCli.h

#ifndef __CEVUDPCLI__H_
#define __CEVUDPCLI__H_
#include "EvCli.h"

class CEvUdpCli : public CEvCli
{
public:
	CEvUdpCli();
	~CEvUdpCli();

public:
	int Init(const char* pIp, const short sSerPort, CEvBase* pBase);
	int Write(const char* pData, size_t pDataLen);

protected:
	int DoRead();
	int DoClose();
	int DoTimeout();
};

#endif

EvCliMgr.h

#ifndef __EVCLIMGR__H_
#define __EVCLIMGR__H_
#include "singleton.h"
#include "EvTcpCli.h"
#include "EvUdpCli.h"
#include <set>
using namespace std;

class CEvCliMgr :public CSingleton<CEvCliMgr>
{
	SINGLE_CLASS_INITIAL(CEvCliMgr);
public:
	~CEvCliMgr();
	int Init();
	CEvTcpCli* AddTcpCli(const char* pIp, const short sSerPort);
	CEvUdpCli* AddUdpCli(const char* pIp, const short sSerPort);
	int DelTcpCli(CEvTcpCli* pCli);
	int DelUdpCli(CEvUdpCli* pCli);
	int DelAllCli();

private:
	bool m_bInit;
	CMutex m_cMutex;
	set<CEvCli*> m_setCli;
	CEvBase* m_pMainBase;
};

#define sEvCliMgr CEvCliMgr::Instance()
#endif

EvBase.cpp

#include "stdafx.h"
#include "EvBase.h"
#include "CLogmanager.h"

CEvBase::CEvBase()
{
	m_pEvBase = nullptr;
	m_pTimeoutEvent = nullptr;
	m_bInit = false;
}

CEvBase::~CEvBase()
{
	if (nullptr != m_pEvBase)
	{
		event_base_free(m_pEvBase);
		m_pEvBase = nullptr;
	}
}

int CEvBase::StartBaseLoop()
{
	if (m_bInit)
	{
		return 0;
	}

	m_pEvBase = event_base_new();//初始化libevent 
	if (nullptr == m_pEvBase)
	{
		return 1;
	}

	m_pTimeoutEvent = event_new(m_pEvBase, -1, EV_PERSIST | EV_TIMEOUT, CEvBase::TimeOutCb, (void*)this);
	if (nullptr != m_pTimeoutEvent)
	{
		timeval stTime = { 0, 18 };
		event_add(m_pTimeoutEvent, &stTime);
	}
	
	m_bInit = true;
	return Start();
}

void* CEvBase::work()
{
	while (!m_bStop)
	{
		//event_base_loop(m_pEvBase, EVLOOP_NO_EXIT_ON_EMPTY);
		while (nullptr != m_pEvBase && m_bInit)
		{
			event_base_dispatch(m_pEvBase);
			//event_base_loop(m_pEvBase, EVLOOP_NONBLOCK);
		}
		
		Wait();
	}

	if (nullptr != m_pTimeoutEvent)
	{
		event_free(m_pTimeoutEvent);
		m_pTimeoutEvent = nullptr;
	}
	return nullptr;
}

void CEvBase::TimeOutCb(evutil_socket_t fd, short event, void* arg)
{
	CEvBase* pEvBase = reinterpret_cast<CEvBase*>(arg);
	if (nullptr != pEvBase)
	{
		if (!pEvBase->m_bInit)
		{
			event_base_loopbreak(pEvBase->m_pEvBase);
		}
	}
}

int CEvBase::StopBaseLoop()
{
	if (!m_bInit)
	{
		return 0;
	}

	if (m_bInit && nullptr != m_pEvBase)
	{
		m_bInit = false;
		//event_base_loopbreak(m_pEvBase);
		//event_base_loopexit(m_pEvBase, nullptr);
	}
	
	return Stop();
}

int CEvBase::AddFd(const evutil_socket_t iFd, ev_cb pReadCb, void* pReadParam, ev_cb pWriteCb, void* pWriteParam, ev_cb pTimeoutCb, void* pTimeoutParam, timeval* pTimeVal)
{
	if (nullptr == m_pEvBase || (nullptr == pReadCb && nullptr == pWriteCb))
	{
		return 1;
	}

	m_cMutex.Lock();
	ev_ctl* pEvCtl = FindEvCtl(iFd);
	if (nullptr == pEvCtl)
	{
		ev_ctl stEvTmp;
		stEvTmp.pReadEv.pCb = pReadCb;
		stEvTmp.pReadEv.pCbParam = pReadParam;
		
		if (nullptr != stEvTmp.pReadEv.pCb)
		{
			stEvTmp.pReadEv.pEvent = event_new(m_pEvBase, iFd, EV_READ | EV_PERSIST, pReadCb, pReadParam);
			event_add(stEvTmp.pReadEv.pEvent, nullptr);
		}
		
		stEvTmp.pWriteEv.pCb = pWriteCb;
		stEvTmp.pWriteEv.pCbParam = pWriteParam;
		if (nullptr != stEvTmp.pWriteEv.pCb)
		{
			stEvTmp.pWriteEv.pEvent = event_new(m_pEvBase, iFd, EV_WRITE | EV_PERSIST, pWriteCb, pWriteParam);
			event_add(stEvTmp.pWriteEv.pEvent, nullptr);
		}

		stEvTmp.pTimeOutEv.pCb = pTimeoutCb;
		stEvTmp.pTimeOutEv.pCbParam = pTimeoutParam;
		if (nullptr != stEvTmp.pTimeOutEv.pCb)
		{
			stEvTmp.pTimeOutEv.pEvent = event_new(m_pEvBase, iFd, EV_TIMEOUT | EV_PERSIST, pTimeoutCb, pTimeoutParam);
			event_add(stEvTmp.pTimeOutEv.pEvent, pTimeVal);
		}

		m_mapEvCtl.insert(pair<evutil_socket_t, ev_ctl>(iFd, stEvTmp));
	}
	m_cMutex.UnLock();

	return 0;
}

int CEvBase::DelFd(const evutil_socket_t iFd)
{
	ev_ctl* pEvCtl = nullptr;
	m_cMutex.Lock();
	map<evutil_socket_t, ev_ctl>::iterator iter = m_mapEvCtl.find(iFd);
	if (iter != m_mapEvCtl.end())
	{
		pEvCtl = (ev_ctl*)&iter->second;
		if (nullptr != pEvCtl->pReadEv.pEvent)
		{
			event_free(pEvCtl->pReadEv.pEvent);
		}

		if (nullptr != pEvCtl->pWriteEv.pEvent)
		{
			event_free(pEvCtl->pWriteEv.pEvent);
		}

		if (nullptr != pEvCtl->pTimeOutEv.pEvent)
		{
			event_free(pEvCtl->pTimeOutEv.pEvent);
		}
		m_mapEvCtl.erase(iter);
	}
	m_cMutex.UnLock();

	return 0;
}

ev_ctl* CEvBase::FindEvCtl(evutil_socket_t iFd)
{
	ev_ctl* pRet = nullptr;
	map<evutil_socket_t, ev_ctl>::iterator iter = m_mapEvCtl.find(iFd);
	if (iter != m_mapEvCtl.end())
	{
		pRet = (ev_ctl*)&iter->second;
	}

	return pRet;
}

int CEvBase::Write(evutil_socket_t iFd, const char* pData, size_t iDataLen)
{
	if (nullptr == pData || iDataLen <= 0)
	{
		return -1;
	}
	
	int iWrite = 0;
	while (iWrite < iDataLen)
	{
		int iTmp = send(iFd, pData + iWrite, (int)(iDataLen - iWrite), 0);
		if (iTmp <= 0)
		{
			if (iTmp == 0)
			{
				continue;
			}
			
#if defined(WIN32) || defined(_WIN32)
			if (GetLastError() == WSAEWOULDBLOCK)
			{
				continue;
			}
#elif  __linux__
			extern int errno;
			if (errno == EAGAIN)
			{
				continue;
			}
#endif
			return -1;
		}

		iWrite += iTmp;
	}

	if (UpdateActiveTime(iFd) != 0)
	{
		return -1;
	}

	return 0;
}

int CEvBase::Write(evutil_socket_t iFd, struct sockaddr* pAddr, int iSockLen, const char* pData, size_t iDataLen)
{
	if (nullptr == pData || iDataLen <= 0)
	{
		return -1;
	}

	int iRet = 0;
	int iWrite = 0;
	while (iWrite < iDataLen)
	{
		iRet = sendto(iFd, pData + iWrite, (int)(iDataLen - iWrite), 0, pAddr, iSockLen);
		if (iRet <= 0)
		{
			break;
		}

		iWrite += iRet;
	}

	return iRet;
}

int CEvBase::UpdateActiveTime(const evutil_socket_t iFd)
{
	int iRet = 1;
	m_cMutex.Lock();
	ev_ctl* pEvCtl = FindEvCtl(iFd);
	if (nullptr != pEvCtl)
	{
		pEvCtl->iLastOper = time(nullptr);
		iRet = 0;
	}
	m_cMutex.UnLock();
	return iRet;
}

time_t CEvBase::GetActiveTime(const evutil_socket_t iFd)
{
	time_t iRet = 0;
	m_cMutex.Lock();
	ev_ctl* pEvCtl = FindEvCtl(iFd);
	if (nullptr != pEvCtl)
	{
		iRet = pEvCtl->iLastOper;
	}
	m_cMutex.UnLock();
	return iRet;
}

EvServer.cpp

#include "stdafx.h"
#include "EvServer.h"
#include "CLogmanager.h"
CEvServer::CEvServer()
{
	m_bInit = false;
	m_sListenPort = 0;
	m_iListenFd = 0;
	m_pListenEvBase = nullptr;
	m_pMsgCb = nullptr;
	m_pUser = nullptr;
	m_pUsrParam = nullptr;
	m_pBuf = nullptr;
	while (nullptr == m_pBuf)
	{
		m_pBuf = (char*)do_malloc(EV_DEFAULT_BUFFER_LEN * sizeof(char));
	}
}

CEvServer::~CEvServer()
{
	if (nullptr != m_pBuf)
	{
		DOFREE(m_pBuf);
	}
	Stop();
}

int CEvServer::Stop()
{
	if (m_bInit)
	{
		if (nullptr != m_pListenEvBase)
		{
			m_pListenEvBase->StopBaseLoop();
			DODELETE(m_pListenEvBase);
		}

		if (m_iListenFd != 0)
		{
			evutil_closesocket(m_iListenFd);
			m_iListenFd = 0;
		}
	}

	m_bInit = false;
	return 0;
}

int CEvServer::RegMsgCb(ev_msg_cb pMsgCb, void* pUser, void* pUserParam)
{
	if (!m_bInit || nullptr == pMsgCb)
	{
		return 1;
	}

	m_pMsgCb = pMsgCb;
	m_pUser = pUser;
	m_pUsrParam = pUserParam;
	return 0;
}

void CEvServer::WriteCb(evutil_socket_t iFd, short events, void *arg)
{
	CEvServer* pEvServer = reinterpret_cast<CEvServer*>(arg);
	if (nullptr != pEvServer && pEvServer->m_bInit)
	{
		pEvServer->DoWrite(iFd, events, arg);
	}
}

void CEvServer::ReadCb(evutil_socket_t iFd, short events, void *arg)
{
	CEvServer* pEvServer = reinterpret_cast<CEvServer*>(arg);
	if (nullptr != pEvServer && pEvServer->m_bInit)
	{
		pEvServer->DoRead(iFd, events, arg);
	}
}

void CEvServer::TimeoutCb(evutil_socket_t iFd, short events, void *arg)
{
	CEvServer* pEvServer = reinterpret_cast<CEvServer*>(arg);
	if (nullptr != pEvServer && pEvServer->m_bInit)
	{
		pEvServer->DoTimeout(iFd, events, arg);
	}
}

EvTcpServer.cpp

#include "stdafx.h"
#include "EvTcpServer.h"
#include "CLogmanager.h"

#define CLI_IDLE_WAIT_SEC	60*100	//客户端连接后多少秒没发消息包超时
#define CLI_IDLE_WAIT_USEC	0	//客户端连接后多少微秒没发消息包超时

CEvTcpServer::CEvTcpServer()
{
}

CEvTcpServer::~CEvTcpServer()
{

}

int CEvTcpServer::Init(const short sListenPort, ev_msg_cb pMsgCb)
{
	m_sListenPort = sListenPort;
	struct sockaddr_in sin;
	sin.sin_family = AF_INET;
	sin.sin_addr.s_addr = htonl(INADDR_ANY);//本机  
	sin.sin_port = htons(m_sListenPort);

	m_iListenFd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (m_iListenFd < 0)
	{
		int err = EVUTIL_SOCKET_ERROR();
		LOG_ERR("%s", evutil_socket_error_to_string(err));
		return 1;
	}

	int on = 1;
	if (setsockopt(m_iListenFd, SOL_SOCKET, SO_KEEPALIVE, (const char*)&on, sizeof(on)) < 0)
	{
		int err = EVUTIL_SOCKET_ERROR();
		LOG_ERR("%s", evutil_socket_error_to_string(err));
		evutil_closesocket(m_iListenFd);
		return 1;
	}
	evutil_make_socket_nonblocking(m_iListenFd);
	evutil_make_listen_socket_reuseable(m_iListenFd);
	evutil_make_listen_socket_reuseable_port(m_iListenFd);
	if (bind(m_iListenFd, (struct sockaddr*)&sin, sizeof(sin)) < 0)
	{
		int err = EVUTIL_SOCKET_ERROR();
		LOG_ERR("%s", evutil_socket_error_to_string(err));
		evutil_closesocket(m_iListenFd);
		return 1;
	}

	if (listen(m_iListenFd, 128) < 0)
	{
		int err = EVUTIL_SOCKET_ERROR();
		LOG_ERR("%s", evutil_socket_error_to_string(err));
		evutil_closesocket(m_iListenFd);
		return 1;
	}

	m_pListenEvBase = new CEvBase();
	if (nullptr == m_pListenEvBase)
	{
		evutil_closesocket(m_iListenFd);
		return 1;
	}

	if (0 != m_pListenEvBase->StartBaseLoop())
	{
		evutil_closesocket(m_iListenFd);
		DODELETE(m_pListenEvBase);
		return 1;
	}

	m_pListenEvBase->AddFd(m_iListenFd, CEvServer::ReadCb, (void*)this, nullptr, nullptr, nullptr, nullptr);
	m_pMsgCb = pMsgCb;
	m_bInit = true;
	return  0;
}

int CEvTcpServer::DoClose(evutil_socket_t iFd, short events, void *arg)
{
	if (m_bInit)
	{
		if (iFd == m_iListenFd)
		{
			return 0;
		}

		LOG_INFO("Del Cli:%d", iFd);
		if (m_pMsgCb)
		{
			m_pMsgCb(iFd, nullptr, 0, m_pUser, m_pUsrParam, nullptr);
		}

		evutil_closesocket(iFd);
		m_pListenEvBase->DelFd(iFd);
	}

	return 0;
}

int CEvTcpServer::DoWrite(evutil_socket_t iFd, short events, void *arg)
{
	if (m_bInit)
	{
		LOG_DBG("Enter CEvTcpServer::WriteCb");
	}
	
	return 0;
}

int CEvTcpServer::DoRead(evutil_socket_t iFd, short events, void *arg)
{
	//LOG_DBG("Enter DoRead iFd:%d events:%d", iFd, events);
	if (m_bInit)
	{
		if (iFd == m_iListenFd)
		{
			struct sockaddr_storage ss;
			socklen_t slen = sizeof(ss);
			evutil_socket_t iNewFd = accept(m_iListenFd, (struct sockaddr*)&ss, &slen);
			if (iNewFd > 0)
			{
				struct timeval stTmp;
				stTmp.tv_sec = 1;
				stTmp.tv_usec = 0;
				evutil_make_socket_nonblocking(iNewFd);
				m_pListenEvBase->AddFd(iNewFd, CEvServer::ReadCb, (void*)this, nullptr, nullptr, CEvServer::TimeoutCb, (void*)this, &stTmp);
				LOG_INFO("New Cli:%d", iNewFd);
			}
		}
		else
		{
			int iRead = 0;
			bool bFirst = true;
			while (iRead < EV_DEFAULT_BUFFER_LEN - 1)
			{
				int iTmpRead = recv(iFd, m_pBuf + iRead, EV_DEFAULT_BUFFER_LEN - 1 - iRead, 0);
				if (iTmpRead <= 0)
				{
					if (bFirst)
					{
						return DoClose(iFd, events, arg);
					}

					break;
				}

				iRead += iTmpRead;
				bFirst = false;
			}

			m_pBuf[iRead] = '\0';
			if (m_pMsgCb)
			{
				//回调需要关闭的客户端
				if (m_pMsgCb(iFd, m_pBuf, iRead, m_pUser, m_pUsrParam, nullptr) != 0)
				{
					return DoClose(iFd, events, arg);
				}
			}

			m_pListenEvBase->UpdateActiveTime(iFd);
		}
	}

	return 0;
}

int CEvTcpServer::DoTimeout(evutil_socket_t iFd, short events, void *arg)
{
	time_t iNow = time(nullptr);
	time_t iLastActiveTime = m_pListenEvBase->GetActiveTime(iFd);
	if (iNow > iLastActiveTime + CLI_IDLE_WAIT_SEC)
	{
		LOG_INFO("fd:%d timeout", iFd);
		DoClose(iFd, events, arg);
	}

	return 0;
}

int CEvTcpServer::Write(evutil_socket_t fd, char* pData, size_t iDataLen, void* pParam)
{
	if (!m_bInit)
	{
		return 1;
	}

	return m_pListenEvBase->Write(fd, pData, iDataLen);
}

EvUdpServer.cpp

#include "stdafx.h"
#include "EvUdpServer.h"
#include "CLogmanager.h"

CEvUdpServer::CEvUdpServer()
{
}

CEvUdpServer::~CEvUdpServer()
{

}

int CEvUdpServer::Init(const short sListenPort, ev_msg_cb pMsgCb)
{
	m_sListenPort = sListenPort;
	m_iListenFd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	if (m_iListenFd < 0)
	{
		int err = EVUTIL_SOCKET_ERROR();
		LOG_ERR("%s", evutil_socket_error_to_string(err));
		return 1;
	}
	evutil_make_socket_nonblocking(m_iListenFd);
	evutil_make_listen_socket_reuseable(m_iListenFd);
	struct sockaddr_in sin_udp;
	sin_udp.sin_family = AF_INET;
	sin_udp.sin_addr.s_addr = htonl(INADDR_ANY);//本机  
	sin_udp.sin_port = htons(m_sListenPort);

	if (bind(m_iListenFd, (struct sockaddr*)&sin_udp, sizeof(sin_udp)) < 0)
	{
		int err = EVUTIL_SOCKET_ERROR();
		LOG_ERR("%s", evutil_socket_error_to_string(err));
		return 1;
	}

	m_pListenEvBase = new CEvBase();
	if (nullptr == m_pListenEvBase)
	{
		evutil_closesocket(m_iListenFd);
		return 1;
	}

	if (0 != m_pListenEvBase->StartBaseLoop())
	{
		evutil_closesocket(m_iListenFd);
		DODELETE(m_pListenEvBase);
		return 1;
	}

	m_pListenEvBase->AddFd(m_iListenFd, CEvServer::ReadCb, (void*)this, nullptr, nullptr, nullptr, nullptr);
	m_pMsgCb = pMsgCb;
	m_bInit = true;
	return  0;
}

int CEvUdpServer::DoClose(evutil_socket_t iFd, short events, void *arg)
{
	return 0;
}

int CEvUdpServer::DoTimeout(evutil_socket_t iFd, short events, void *arg)
{
	return 0;
}

int CEvUdpServer::DoWrite(evutil_socket_t iFd, short events, void *arg)
{
	if (m_bInit)
	{
		//m_pListenEvBase->ActiveWrite();
	}
	return 0;
}

int CEvUdpServer::DoRead(evutil_socket_t iFd, short events, void *arg)
{
	if (m_bInit)
	{
		struct sockaddr_in client_addr;
		socklen_t client_addr_length = sizeof(client_addr);
		int  n;
		while (true)
		{
			n = recvfrom(m_iListenFd, m_pBuf, EV_DEFAULT_BUFFER_LEN - 1, 0, (struct sockaddr*)&client_addr, &client_addr_length);
			if (n > 0)
			{
				m_pBuf[n] = '\0';
				if (m_pMsgCb)
				{
					m_pMsgCb(m_iListenFd, m_pBuf, n, m_pUser, m_pUsrParam, &client_addr);
				}
				//m_pListenEvBase->Write(m_iListenFd, (struct sockaddr*)&client_addr, (int)client_addr_length, buffer, strlen(buffer));
			}
			else
			{
				break;
			}
		}
	}

	return 0;
}

int CEvUdpServer::Write(evutil_socket_t fd, char* pData, size_t iDataLen, void* pParam)
{
	if (!m_bInit)
	{
		return 1;
	}

	return m_pListenEvBase->Write(fd, (struct sockaddr*)pParam, sizeof(sockaddr_in), pData, iDataLen);
}

EvSerMgr.cpp

#include "stdafx.h"
#include "EvSerMgr.h"
#include "util.h"
CEvSerMgr::CEvSerMgr()
{

}

CEvSerMgr::~CEvSerMgr()
{

}

int CEvSerMgr::StopAllServer()
{
	m_cMutex.Lock();
	for (map<short, tagEvServerInfo*>::iterator iter = m_mapServer.begin(); iter != m_mapServer.end(); )
	{
		CEvTcpServer* pTcpSer = reinterpret_cast<CEvTcpServer*>(iter->second->pEvTcpSer);
		if (nullptr != pTcpSer)
		{
			pTcpSer->Stop();
			DODELETE(pTcpSer);
		}
			
		CEvUdpServer* pUdpSer = reinterpret_cast<CEvUdpServer*>(iter->second->pEvUdpSer);
		if (nullptr != pUdpSer)
		{
			pUdpSer->Stop();
			DODELETE(pUdpSer);
		}

		iter = m_mapServer.erase(iter);
	}
	m_cMutex.UnLock();
	return 0;
}

int CEvSerMgr::StopTcpServer(const short sPort)
{
	m_cMutex.Lock();
	map<short, tagEvServerInfo*>::iterator iter = m_mapServer.find(sPort);
	if (iter != m_mapServer.end() && nullptr != iter->second->pEvTcpSer)
	{
		CEvTcpServer* pSer = reinterpret_cast<CEvTcpServer*>(iter->second->pEvTcpSer);
		if (nullptr != pSer)
		{
			pSer->Stop();
			DODELETE(pSer);
		}
		iter->second->pEvTcpSer = nullptr;

		if (nullptr == iter->second->pEvUdpSer)
		{
			m_mapServer.erase(iter);
		}
	}
	m_cMutex.UnLock();

	return 0;
}

CEvTcpServer* CEvSerMgr::AddTcpServer(const short sPort)
{
	CEvTcpServer* pSer = nullptr;
	m_cMutex.Lock();
	tagEvServerInfo* pServerInfo = GetServerInfo(sPort);
	if (nullptr != pServerInfo && nullptr != pServerInfo->pEvTcpSer)
	{
		pSer = reinterpret_cast<CEvTcpServer*>(pServerInfo->pEvTcpSer);
		m_cMutex.UnLock();
		return pSer;
	}

	pSer = new CEvTcpServer();
	if (nullptr != pSer)
	{
		if (0 != pSer->Init(sPort))
		{
			DODELETE(pSer);
			m_cMutex.UnLock();
			return pSer;
		}
	}

	
	if (nullptr == pServerInfo)
	{
		while (nullptr == pServerInfo)
		{
			pServerInfo = new tagEvServerInfo;
		}

		pServerInfo->pEvTcpSer = reinterpret_cast<CEvServer*>(pSer);
		m_mapServer.insert(pair<short, tagEvServerInfo*>(sPort, pServerInfo));
	}
	else
	{
		pServerInfo->pEvTcpSer = reinterpret_cast<CEvServer*>(pSer);
	}
	m_cMutex.UnLock();

	return pSer;
}

int CEvSerMgr::StopUdpServer(const short sPort)
{
	m_cMutex.Lock();
	map<short, tagEvServerInfo*>::iterator iter = m_mapServer.find(sPort);
	if (iter != m_mapServer.end() && nullptr != iter->second->pEvUdpSer)
	{
		CEvUdpServer* pSer = reinterpret_cast<CEvUdpServer*>(iter->second->pEvUdpSer);
		if (nullptr != pSer)
		{
			pSer->Stop();
			DODELETE(pSer);
		}
		iter->second->pEvUdpSer = nullptr;

		if (nullptr == iter->second->pEvTcpSer)
		{
			m_mapServer.erase(iter);
		}
	}
	m_cMutex.UnLock();

	return 0;
}

CEvUdpServer* CEvSerMgr::AddUdpServer(const short sPort)
{
	CEvUdpServer* pSer = nullptr;
	m_cMutex.Lock();
	tagEvServerInfo* pServerInfo = GetServerInfo(sPort);
	if (nullptr != pServerInfo && nullptr != pServerInfo->pEvUdpSer)
	{
		pSer = reinterpret_cast<CEvUdpServer*>(pServerInfo->pEvUdpSer);
		m_cMutex.UnLock();
		return pSer;
	}

	pSer = new CEvUdpServer();
	if (nullptr != pSer)
	{
		if (0 != pSer->Init(sPort))
		{
			DODELETE(pSer);
			m_cMutex.UnLock();
			return pSer;
		}
	}


	if (nullptr == pServerInfo)
	{
		while (nullptr == pServerInfo)
		{
			pServerInfo = new tagEvServerInfo;
		}

		pServerInfo->pEvUdpSer = reinterpret_cast<CEvServer*>(pSer);
		m_mapServer.insert(pair<short, tagEvServerInfo*>(sPort, pServerInfo));
	}
	else
	{
		pServerInfo->pEvUdpSer = reinterpret_cast<CEvServer*>(pSer);
	}
	m_cMutex.UnLock();

	return pSer;
}

tagEvServerInfo* CEvSerMgr::GetServerInfo(const short sPort)
{
	tagEvServerInfo* pRet = nullptr;
	map<short, tagEvServerInfo*>::iterator iter = m_mapServer.find(sPort);
	if (iter != m_mapServer.end())
	{
		pRet = iter->second;
	}

	return pRet;
}

EvCli.cpp

#include "stdafx.h"
#include "EvCli.h"
#include "CLogmanager.h"
CEvCli::CEvCli()
{
	m_bInit = false;
	m_iCliFd = 0;
	m_strSerIp = "";
	m_sSerPort = 0;
	m_pEvBase = nullptr;
	m_pMsgCb = nullptr;
	m_pUser = nullptr;
	m_pUserParam = nullptr;
	m_pBuf = nullptr;
	while (nullptr == m_pBuf)
	{
		m_pBuf = (char*)do_malloc(EV_DEFAULT_BUFFER_LEN * sizeof(char));
	}
}

CEvCli::~CEvCli()
{
	if (nullptr != m_pBuf)
	{
		DOFREE(m_pBuf);
	}
	Stop();
}

int CEvCli::Stop()
{
	if (m_bInit)
	{
		DoClose();

		m_pEvBase->DelFd(m_iCliFd);
		if (m_iCliFd != 0)
		{
			evutil_closesocket(m_iCliFd);
			m_iCliFd = 0;
		}
	}

	m_bInit = false;
	return 0;
}

void CEvCli::ReadCb(evutil_socket_t iFd, short event, void *arg)
{
	CEvCli* pEvCli = reinterpret_cast<CEvCli*>(arg);
	if (nullptr != pEvCli && pEvCli->m_bInit)
	{
		pEvCli->DoRead();
	}
}

void CEvCli::TimeoutCb(evutil_socket_t iFd, short events, void *arg)
{
	CEvCli* pEvCli = reinterpret_cast<CEvCli*>(arg);
	if (nullptr != pEvCli && pEvCli->m_bInit)
	{
		pEvCli->DoTimeout();
	}
}

int CEvCli::RegMsgCb(ev_msg_cb pMsgCb, void* pUser, void* pUserParam)
{
	if (!m_bInit || nullptr == pMsgCb)
	{
		return 1;
	}

	m_pMsgCb = pMsgCb;
	m_pUser = pUser;
	m_pUserParam = pUserParam;
	return 0;
}

EvTcpCli.cpp

#include "stdafx.h"
#include "EvTcpCli.h"
#include "CLogmanager.h"

CEvTcpCli::CEvTcpCli()
{
}

CEvTcpCli::~CEvTcpCli()
{

}

int CEvTcpCli::Init(const char* pIp, const short sSerPort, CEvBase* pBase)
{
	if (nullptr == pBase)
	{
		return 1;
	}

	m_pEvBase = pBase;
	m_strSerIp = pIp;
	m_sSerPort = sSerPort;

	m_iCliFd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (m_iCliFd < 0)
	{
		int err = EVUTIL_SOCKET_ERROR();
		LOG_ERR("%s", evutil_socket_error_to_string(err));
		return 1;
	}

	struct sockaddr_in serv_addr;
	memset(&serv_addr, 0, sizeof(serv_addr));
	serv_addr.sin_family = AF_INET;
	//serv_addr.sin_addr.s_addr = inet_addr(m_strSerIp.c_str());
	inet_pton(AF_INET, m_strSerIp.c_str(), (void *)&serv_addr.sin_addr.s_addr);
	serv_addr.sin_port = htons(m_sSerPort);
	if (connect(m_iCliFd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
	{
		LOG_ERR("Connect Error!");
		evutil_closesocket(m_iCliFd);
		return 1;
	}

	evutil_make_socket_nonblocking(m_iCliFd);
	m_pEvBase->AddFd(m_iCliFd, CEvCli::ReadCb, (void*)this, nullptr, nullptr, nullptr, nullptr);

	m_bInit = true;
	return 0;
}

int CEvTcpCli::DoRead()
{
	int iRet = 0;
	if (m_bInit)
	{
		int  iRead = 0;
		bool bFirst = true;
		while (iRead < EV_DEFAULT_BUFFER_LEN - 1)
		{
			int iTmpRead = recv(m_iCliFd, m_pBuf + iRead, EV_DEFAULT_BUFFER_LEN - 1 - iRead, 0);
			if (iTmpRead <= 0)
			{
				if (bFirst)
				{
					Stop();
					return -1;
				}
				break;
			}
			
			iRead += iTmpRead;
			bFirst = false;
		}

		m_pBuf[iRead] = '\0';
		if (nullptr != m_pMsgCb)
		{
			m_pMsgCb(m_iCliFd, m_pBuf, iRead, m_pUser, m_pUserParam, nullptr);
		}
	}

	return iRet;
}

int CEvTcpCli::DoTimeout()
{
	return 0;
}

int CEvTcpCli::Write(const char* pData, size_t pDataLen)
{
	int iRet = -1;
	int iWrite = 0;
	if (m_bInit)
	{
		while (iWrite < pDataLen)
		{
			iRet = send(m_iCliFd, pData + iWrite, (int)(pDataLen - iWrite), 0);
			if (iRet <= 0)
			{
				return Stop();
			}

			iWrite += iRet;
		}
	}

	return iRet;
}

int CEvTcpCli::DoClose()
{
	return 0;
}

EvUdpCli.cpp

#include "stdafx.h"
#include "EvUdpCli.h"
#include "CLogmanager.h"

CEvUdpCli::CEvUdpCli()
{
}

CEvUdpCli::~CEvUdpCli()
{
}

int CEvUdpCli::Init(const char* pIp, const short sSerPort, CEvBase* pBase)
{
	if (nullptr == pBase)
	{
		return 1;
	}

	m_pEvBase = pBase;
	m_strSerIp = pIp;
	m_sSerPort = sSerPort;

	m_iCliFd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	if (m_iCliFd < 0)
	{
		int err = EVUTIL_SOCKET_ERROR();
		LOG_ERR("%s", evutil_socket_error_to_string(err));
		return 1;
	}

	m_pEvBase->AddFd(m_iCliFd, CEvCli::ReadCb, (void*)this, nullptr, nullptr, nullptr, nullptr);
	evutil_make_socket_nonblocking(m_iCliFd);
	m_bInit = true;
	return 0;
}

int CEvUdpCli::DoRead()
{
	if (m_bInit)
	{
		struct sockaddr_in client_addr;
		socklen_t client_addr_length = sizeof(client_addr);
		int  n;
		while (true)
		{
			n = recvfrom(m_iCliFd, m_pBuf, EV_DEFAULT_BUFFER_LEN - 1, 0, (struct sockaddr*)&client_addr, &client_addr_length);
			if (n > 0)
			{
				m_pBuf[n] = '\0';
				if (nullptr != m_pMsgCb)
				{
					m_pMsgCb(m_iCliFd, m_pBuf, n, m_pUser, m_pUserParam, nullptr);
				}
			}
			else
			{
				break;
			}
		}
	}

	return 0;
}

int CEvUdpCli::DoClose()
{
	return 0;
}

int CEvUdpCli::Write(const char* pData, size_t pDataLen)
{
	int iRet = -1;
	if (m_bInit)
	{
		int iWrite = 0;
		struct sockaddr_in serv_addr;
		memset(&serv_addr, 0, sizeof(serv_addr));
		serv_addr.sin_family = AF_INET;
		//serv_addr.sin_addr.s_addr = inet_addr(m_strSerIp.c_str());
		inet_pton(AF_INET, m_strSerIp.c_str(), (void *)&serv_addr.sin_addr.s_addr);
		serv_addr.sin_port = htons(m_sSerPort);
		while (iWrite < pDataLen)
		{
			iRet = m_pEvBase->Write(m_iCliFd, (struct sockaddr*)&serv_addr, (int)sizeof(serv_addr), pData, pDataLen);
			if (iRet <= 0)
			{
				return Stop();
			}

			iWrite += iRet;
		}
	}

	return iRet;
}

int CEvUdpCli::DoTimeout()
{
	return 0;
}

EvCliMgr.cpp

#include "stdafx.h"
#include "EvCliMgr.h"
#include "CLogmanager.h"

CEvCliMgr::CEvCliMgr()
{
	m_pMainBase = nullptr;
	m_bInit = false;
}

CEvCliMgr::~CEvCliMgr()
{

}

int CEvCliMgr::Init()
{
	if (!m_bInit)
	{
		m_pMainBase = new CEvBase();
		if (nullptr == m_pMainBase)
		{
			LOG_ERR("New CEvBase Error");
			return 1;
		}

		if (m_pMainBase->StartBaseLoop() != 0)
		{
			LOG_ERR("CEvBase StartBaseLoop Error");
			DODELETE(m_pMainBase);
			return 1;
		}

		m_bInit = true;
	}

	return 0;
}

int CEvCliMgr::DelTcpCli(CEvTcpCli* pCli)
{
	int iRet = 1;
	if (nullptr != pCli)
	{
		m_cMutex.Lock();
		if (m_setCli.find(pCli) != m_setCli.end())
		{
			pCli->Stop();
			DODELETE(pCli);
			iRet = 0;
		}
		m_cMutex.UnLock();
	}
	return iRet;
}

CEvTcpCli* CEvCliMgr::AddTcpCli(const char* pIp, const short sSerPort)
{
	CEvTcpCli* pCli = nullptr;
	if (m_bInit)
	{
		pCli = new CEvTcpCli();
		if (nullptr != pCli)
		{
			if (0 == pCli->Init(pIp, sSerPort, m_pMainBase))
			{
				m_cMutex.Lock();
				m_setCli.insert(reinterpret_cast<CEvCli*>(pCli));
				m_cMutex.UnLock();
			}
			else
			{
				DODELETE(pCli);
			}
		}
	}
	
	return pCli;
}

int CEvCliMgr::DelAllCli()
{
	m_cMutex.Lock();
	for (set<CEvCli*>::iterator iter = m_setCli.begin(); iter != m_setCli.end(); )
	{
		if (nullptr != *iter)
		{
			if (typeid(*iter) == typeid(CEvUdpCli))
			{
				CEvUdpCli* pCli = reinterpret_cast<CEvUdpCli*>(*iter);
				if (nullptr != pCli)
				{
					DODELETE(pCli);
				}
			}
			else if (typeid(*iter) == typeid(CEvTcpCli))
			{
				CEvTcpCli* pCli = reinterpret_cast<CEvTcpCli*>(*iter);
				if (nullptr != pCli)
				{
					DODELETE(pCli);
				}
			}
		}
		
		m_setCli.erase(iter++);
	}
	m_cMutex.UnLock();

	return 0;
}

int CEvCliMgr::DelUdpCli(CEvUdpCli* pCli)
{
	int iRet = 1;
	if (nullptr != pCli)
	{
		m_cMutex.Lock();
		if (m_setCli.find(pCli) != m_setCli.end())
		{
			pCli->Stop();
			DODELETE(pCli);
			iRet = 0;
		}
		m_cMutex.UnLock();
	}
	return iRet;
}

CEvUdpCli* CEvCliMgr::AddUdpCli(const char* pIp, const short sSerPort)
{
	CEvUdpCli* pCli = nullptr;
	if (m_bInit)
	{
		pCli = new CEvUdpCli();
		if (nullptr != pCli)
		{
			if (0 == pCli->Init(pIp, sSerPort, m_pMainBase))
			{
				m_cMutex.Lock();
				m_setCli.insert(reinterpret_cast<CEvCli*>(pCli));
				m_cMutex.UnLock();
			}
			else
			{
				DODELETE(pCli);
			}
		}
	}

	return pCli;
}

猜你喜欢

转载自blog.csdn.net/lightjia/article/details/83181778