//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. ubuntu遇到的问题

    昨天分辨率在装一个游戏时被更改了,改过之后,怎么都改不过来... 折腾了一下午,在配置文件中/etc/X11/xorg.conf.failsafe,但是网上都是/etc/X11/xorg.conf, ...

  2. hibernate映射xml文件配置之一对多,多对多

    一对多配置 [1]班级和学生模型 --->班级可容纳多个学生 --->学生只能属于一个班级 [2]一对多配置中的关系维护(inverse) --->一端放弃关系的维护 ---> ...

  3. Netty5.x 和3.x、4.x的区别及注意事项(官方翻译)

    Netty5.x 和3.x.4.x的区别及注意事项 (官方翻译) 本文档列出了Netty5新版本中值得注意变化和新特性列表.帮助你的应用更好的适应新的版本.   不像Netty3.x和4.x之间的变化 ...

  4. cratedb 基本试用

    安装 docker run -d -p 4200:4200 crate UI访问 http://localhost:4200/#!/ 创建数据 tweets 是默认导入的,点击帮助导航可以操作 登陆 ...

  5. jenkins初始化配置完后设置了管理员账号密码 网页停留时间长了刷新登录不了了

    好像陆陆续续在几台机子安装到最后正式使用的这台机器都是这样.难道是它自己本身的问题吗?只能网上帖子凑了. 找到.jenkins/config.xml文件:(windows环境就是和initialsec ...

  6. SonarQube使用教程

    SonarQube是管理代码质量一个开放平台,可以快速的定位代码中潜在的或者明显的错误,本文将会介绍一下这个工具的安装.配置以及使用. 一.SonarQube的安装使用: 下载地址:http://ww ...

  7. TestCase和TestSuite详解

    一.TestCast和TestSuite概念介绍 TestCase:字面意思,测试用例.为一个或多个方法提供测试方法,一般是一个test. TestSuite:测试集合,即一组测试.一个test su ...

  8. 输入和输出(read,recv,recvmsg...和write,writev,writemsg)

    每一个TCP套接口有一个发送缓冲区,可以用SO_SNDBUF套接口选项来改变这个缓冲区的大小. 应用进程调用 write时,内核从应用进程的缓冲区中拷贝所有数据到套接口的发送缓冲区.如果套接口的发送缓 ...

  9. HBuilder webApp开发 Websql增删改查操作

    来源:http://blog.csdn.net/zhuming3834/article/details/51471434 这段时间公司要求我们做原生iOS和安卓的都转做H5开发APP,使用的工具HBu ...

  10. ThinkPHP实现事务回滚示例代码

    ThinkPHP的事务回滚示例如下: ? 1 2 3 4 5 6 7 8 9 10 $m=D('YourModel');//或者是M(); $m2=D('YouModel2'); $m->sta ...