zoukankan      html  css  js  c++  java
  • 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
    ", 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
    ");
            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
    ",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...
    ");
        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
    ");
            event_base_loopbreak(m_eventBase);
            return ;
        }
        printf("connect a client...
    ");
        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 
    ");
            bufferevent_free(be);
        }
        else if (events & BEV_EVENT_ERROR)
        {
            printf("connect error 
    ");
            bufferevent_free(be);
        }
        else
        {
            printf("connect a event 
    ");
        }
    }
    
    
    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...
    ");
            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
    ", escape);
        m_timeval = tv;
    }
    

      

  • 相关阅读:
    [ERR] Node 10.211.55.8:7001 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0.
    PAT A1137 Final Grading (25 分)——排序
    PAT A1136 A Delayed Palindrome (20 分)——回文,大整数
    PAT A1134 Vertex Cover (25 分)——图遍历
    PAT A1133 Splitting A Linked List (25 分)——链表
    PAT A1132 Cut Integer (20 分)——数学题
    PAT A1130 Infix Expression (25 分)——中序遍历
    PAT A1142 Maximal Clique (25 分)——图
    PAT A1141 PAT Ranking of Institutions (25 分)——排序,结构体初始化
    PAT A1140 Look-and-say Sequence (20 分)——数学题
  • 原文地址:https://www.cnblogs.com/yu-chao/p/9495017.html
Copyright © 2011-2022 走看看