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

      

  • 相关阅读:
    Android拍照、摄像方向旋转的问题 代码具体解释
    Java 实现桥接(Bridge)模式
    C++标准I/O库:iostream, fstream, sstringstream
    Android 使用 DownloadManager 管理系统下载任务的方法
    JavaScript提高:005:ASP.NET使用easyUI TABS标签显示问题
    使用c++的cocos2d-x-3.0rc1程序公布apk
    UVA 146 ID Codes(下一个排列)
    C/C++:C++伪函数
    开源项目AndroidUtil-採用Fragment实现TabHost
    系统编程是什么
  • 原文地址:https://www.cnblogs.com/yu-chao/p/9495017.html
Copyright © 2020-2023  润新知