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

  

libevent 简单学习的更多相关文章

  1. Log4j简单学习笔记

    log4j结构图: 结构图展现出了log4j的主结构.logger:表示记录器,即数据来源:appender:输出源,即输出方式(如:控制台.文件...)layout:输出布局 Logger机滤器:常 ...

  2. shiro简单学习的简单总结

    权限和我有很大渊源. 培训时候的最后一个项目是OA,权限那块却不知如何入手,最后以不是我写的那个模块应付面试. 最开始的是使用session装载用户登录信息,使用简单权限拦截器做到权限控制,利用资源文 ...

  3. CentOS 简单学习 firewalld的使用

    1. centos7 开始 使用firewalld 代替了 iptables 命令工具为 firewall-cmd 帮助信息非常长,简单放到文末 2. 简单使用 首先开启 httpd 一般都自带安装了 ...

  4. Windows 下 Docker 的简单学习使用过程之一 dockertoolbox

    1. Windows 下面运行 Docker 的两个主要工具1): Docker for Windows2): DockerToolbox区别:Docker For Windows 可以理解为是新一代 ...

  5. 在MVC中实现和网站不同服务器的批量文件下载以及NPOI下载数据到Excel的简单学习

    嘿嘿,我来啦,最近忙啦几天,使用MVC把应该实现的一些功能实现了,说起来做项目,实属感觉蛮好的,即可以学习新的东西,又可以增加自己之前知道的知识的巩固,不得不说是双丰收啊,其实这周来就开始面对下载在挣 ...

  6. Linux——帮助命令简单学习笔记

    Linux帮助命令简单学习笔记: 一: 命令名称:man 命令英文原意:manual 命令所在路径:/usr/bin/man 执行权限:所有用户 语法:man [命令或配置文件] 功能描述:获得帮助信 ...

  7. OI数学 简单学习笔记

    基本上只是整理了一下框架,具体的学习给出了个人认为比较好的博客的链接. PART1 数论部分 最大公约数 对于正整数x,y,最大的能同时整除它们的数称为最大公约数 常用的:\(lcm(x,y)=xy\ ...

  8. mongodb,redis简单学习

     2.mongodb安装配置简单学习                   配置好数据库路径就可以mongo命令执行交互操作了:先将服务器开起来:在开个cmd执行交互操作                 ...

  9. html css的简单学习(三)

    html css的简单学习(三) 前端开发工具:Dreamweaver.Hbuilder.WebStorm.Sublime.PhpStorm...=========================== ...

随机推荐

  1. python3.5 安装 numpy1.14.4

    AMD64 import pip._internal print(pip._internal.pep425tags.get_supported()) WIN32 import pip print(pi ...

  2. test20181018 B君的第三题

    题意 B 君的第三题(shenyang) 题目描述 客似云来,万里无云 B 君得到了一个数组\(\{a_1,a_2,\dots,a_n\}\). B 君想通过修改让数组中个每对数都互质. 每次使一个数 ...

  3. 【小白的java成长系列】——windows下搭建和配置java环境

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/enson16855/article/details/25967851 基于非常多原因,还是得说说ja ...

  4. win10 下ie11安装flash debuger (install flashplayer debuger on win10 64bit)

    1不能安装的现象 由于win10  ie11  内置flash  微软不让用户自己手动更新ie11的flash以及安装flash  debugger  ,这怕是让还在用 flex 开发的大胸弟们很头疼 ...

  5. FastAdmin 升级后出现 is already in use

    FastAdmin 升级后出现 is already in use 升级 FastAdmin 改进很多,但全新安装出现以下错误 Cannot use app\common\library\Menu a ...

  6. oracle之 Oracle归档日志管理

    在Oracle中,数据一般是存放在数据文件中,不过数据库与Oracle最大的区别之一就是数据库可以在数据出错的时候进行恢复.这个也就是我们常见的Oracle中的重做日志(REDO FILE)的功能了. ...

  7. HR-人力资源管理系统(Human Resources Management System,HRMS)

    人力资源管理系统(Human Resources Management System,HRMS),是指组织或社会团体运用系统学理论方法,对企业的人力资源管理方方面面进行分析.规划.实施.调整,提高企业 ...

  8. mysql-2 数据类型

    mysql中定义数据字段的类型对数据库的优化是非常重要的. mysql数据类型大致分为三类:数值.日期/时间.字符串(字符)类型. 数值类型 MySQL支持所有标准SQL数值数据类型. 这些类型包括严 ...

  9. CSS布局模型学习

    转自:http://www.cnblogs.com/erliang/p/4092192.html CSS布局模型学习   参考链接慕课网:HTML+CSS基础课程 知识基础 1. 样式 内联 嵌入 外 ...

  10. 【BZOJ】1801 [Ahoi2009]chess 中国象棋(dp)

    题目 传送门:QWQ 分析 发现我们关心的不是棋子的位置,我们只关心棋子数量就ok. 首先每行每列最多两个棋子.这是显然的. 然后我觉得本题最难的部分就是对行进行讨论,蒟蒻我一直被限制在了对格点讨论. ...