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