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

  

posted @ 2018-08-17 19:38  书山有路,学海无涯  阅读(236)  评论(0编辑  收藏  举报