libevent 简单学习
//NetworkManager.h #ifndef _NET_WORK_MANAGER_ #define _NET_WORK_MANAGER_ #include "event2/util.h" #include "event_struct.h" #include<vector> struct event_base; struct evconnlistener; struct sockaddr_in; struct NetObserver { virtual void onReadDataNotify(struct bufferevent* be, const char* data,size_t size) {} virtual void onCmdNotify(const char* data,size_t size) {} }; class NetworkManager { public: static NetworkManager* getInstance(); static void listenerEventBuffer(struct evconnlistener* listener, evutil_socket_t,struct sockaddr* addr, int socklen, void* data); static void readEventBuffer(struct bufferevent* be,void* data); static void writeEventBuffer(struct bufferevent* be,void* data); static void eventEventBuffer(struct bufferevent *bev, short events, void *user_data); static void timer(int fd, short event, void* arg); static void eventLog(int severity, const char *msg); void addObserver(NetObserver* observer); void removeObserver(NetObserver* observer); bool init(int port); void listener(struct evconnlistener* listener, evutil_socket_t,struct sockaddr* addr); void read(struct bufferevent* be); void write(struct bufferevent* be, const char* data,size_t len); void event(struct bufferevent* be,short events); char* getDataBuffer(size_t size); void dispatch(); void update(); private: NetworkManager(); ~NetworkManager(); private: evconnlistener * m_listener; event_base* m_eventBase; struct event* m_timer; struct timeval m_timeval; sockaddr_in* m_lisSockAddr; std::vector<NetObserver*> m_observers; char* m_dataBuff; size_t m_buffSize; }; #endif // _NET_WORK_MANAGER_
//NetworkManager.cpp #include "NetworkManager.h" #include<string.h> #include<stdio.h> #include<chrono> #include "event.h" #include "listener.h" #include "bufferevent.h" #include "evutil.h" #ifdef _WIN32 #include<WinSock2.h> #endif NetworkManager* NetworkManager::getInstance() { static NetworkManager mgr; return &mgr; } void NetworkManager::listenerEventBuffer(struct evconnlistener* listener, evutil_socket_t fd,struct sockaddr* addr, int socklen, void* data) { NetworkManager::getInstance()->listener(listener,fd,addr); } void NetworkManager::readEventBuffer(struct bufferevent* be,void* data) { NetworkManager::getInstance()->read(be); } void NetworkManager::writeEventBuffer(struct bufferevent* be,void* data) { } void NetworkManager::eventEventBuffer(struct bufferevent *be, short events, void *user_data) { NetworkManager::getInstance()->event(be,events); } void NetworkManager::timer(int fd, short event, void* arg) { NetworkManager::getInstance()->update(); } void NetworkManager::eventLog(int severity, const char *msg) { const char *severity_str; switch (severity) { case _EVENT_LOG_DEBUG: severity_str = "debug"; break; case _EVENT_LOG_MSG: severity_str = "msg"; break; case _EVENT_LOG_WARN: severity_str = "warn"; break; case _EVENT_LOG_ERR: severity_str = "err"; break; default: severity_str = "???"; break; } fprintf(stderr, "[%s] %s\n", severity_str, msg); } /********************************************************/ NetworkManager::NetworkManager() :m_listener(NULL) ,m_eventBase(NULL) ,m_lisSockAddr(NULL) ,m_dataBuff(NULL) ,m_buffSize(0) ,m_timer(NULL) { m_timeval.tv_sec = m_timeval.tv_usec = 0; m_lisSockAddr = new sockaddr_in; #ifdef _WIN32 WSADATA ws; WSAStartup(MAKEWORD(2, 2), &ws); #endif } NetworkManager::~NetworkManager() { delete m_lisSockAddr; WSACleanup(); } void NetworkManager::addObserver(NetObserver* observer) { for(auto iter = m_observers.begin(); iter != m_observers.end(); ++iter) { if((*iter) == observer) return; } m_observers.push_back(observer); } void NetworkManager::removeObserver(NetObserver* observer) { for(auto iter = m_observers.begin(); iter != m_observers.end(); ++iter) { if((*iter) == observer) { m_observers.erase(iter); return; } } } bool NetworkManager::init(int port) { memset(m_lisSockAddr,0,sizeof(sockaddr_in)); m_lisSockAddr->sin_family = AF_INET; m_lisSockAddr->sin_port = htons(port); m_eventBase = event_base_new(); if(!m_eventBase) { printf("Could not initialize libevent\n"); return false; } event_set_log_callback(&NetworkManager::eventLog); m_listener = evconnlistener_new_bind(m_eventBase,NetworkManager::listenerEventBuffer,(void*)m_eventBase, LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_FREE,1,(struct sockaddr*)m_lisSockAddr ,sizeof(sockaddr_in)); if(!m_listener) { int errCode = EVUTIL_SOCKET_ERROR(); const char* reason = evutil_socket_error_to_string(errCode); event_base_free(m_eventBase); printf("Could not create a listener, msg : %s\n",reason); return false; } evutil_gettimeofday(&m_timeval, NULL); struct timeval tv = {1,0}; m_timer = event_new(m_eventBase,-1, EV_PERSIST, &NetworkManager::timer,"update"); event_add(m_timer, &tv); printf("network init secceed...\n"); return true; } void NetworkManager::listener(struct evconnlistener* listener, evutil_socket_t fd,struct sockaddr* addr) { struct bufferevent* be = bufferevent_socket_new(m_eventBase,fd, BEV_OPT_CLOSE_ON_FREE); if(!be) { printf("Could not create a bufferevent\n"); event_base_loopbreak(m_eventBase); return ; } printf("connect a client...\n"); bufferevent_setcb(be,NetworkManager::readEventBuffer,NetworkManager::writeEventBuffer,NetworkManager::eventEventBuffer,NULL); bufferevent_enable(be,EV_READ | EV_WRITE); const char* str = "login secceed"; write(be,str,strlen(str)); } void NetworkManager::read(struct bufferevent* be) { struct evbuffer* input = bufferevent_get_input(be); size_t size = evbuffer_get_length(input); if(size > 0) { char* buff = getDataBuffer(size); bufferevent_read(be,buff,size); for(auto iter = m_observers.begin(); iter != m_observers.end(); ++iter) { (*iter)->onReadDataNotify(be,buff,size); } } } void NetworkManager::write(struct bufferevent* be, const char* data,size_t len) { if(!m_eventBase) return; bufferevent_write(be,data,len); } void NetworkManager::event(struct bufferevent* be,short events) { if (events & BEV_EVENT_EOF) { printf("connection close \n"); bufferevent_free(be); } else if (events & BEV_EVENT_ERROR) { printf("connect error \n"); bufferevent_free(be); } else { printf("connect a event \n"); } } char* NetworkManager::getDataBuffer(size_t size) { if(m_buffSize < size) { delete [] m_dataBuff; m_buffSize = 2 * size; m_dataBuff = new char[m_buffSize]; } memset(m_dataBuff,0,m_buffSize); return m_dataBuff; } void NetworkManager::dispatch() { if(m_eventBase && m_listener) { printf("network dispatch...\n"); event_base_dispatch(m_eventBase); evconnlistener_free(m_listener); event_base_free(m_eventBase); } } void NetworkManager::update() { struct timeval tv, difference; evutil_gettimeofday(&tv, NULL); evutil_timersub(&tv, &m_timeval, &difference); double escape = difference.tv_sec + (difference.tv_usec / 1.0e6); //printf("escape = %f\n", escape); m_timeval = tv; }