网络通信库Libevent的基本介绍

来源:互联网 发布:淘宝联盟可以赚钱吗 编辑:程序博客网 时间:2024/06/09 14:52

Libevent是一个轻量级、开源的网络库,与之相似的还有ACE(但是它比较庞大臃肿),Libev(可以说它是对Libevent的扩展,但是没有Libevent更稳定),当然还有Windows下非常强大的I/O完全端口(没有研究过再见),不过据说,最新的Libevent好像也可以支持完全端口哦。


下面直接上干货(针对最新的稳定的2.0.22版本)!


优点:

1、跨平台:支持Windos,Linux,Mac Os

2、支持各种I/O多路复用技术:select、poll、epoll、kqueue等(在不同的平台上都是选择最优的技术,比如在Windows下选择select,在Linux下选择epoll)。

{

这里顺带说一下,select跟epoll的一些区别

相同点:select跟epoll都是I/O多路复用技术,都可以用来实现高并发访问

不同点:

select:跨平台、采用轮询模式(也就是说每次有事件发生的时候都要进行遍历)、能监听的文件描述符受限于FD_SETSIZE,一般为1024,实现相对简单

epoll:只支持Linux,更加灵活,文件描述符不会受限制,使用一个文件描述符来管理多个文件描述符,将用户关系的文件描述符存放到内核的事件表中,这样从用户态到内核态只需要拷贝一次,不需要每次都进行遍历,但是实现相对复杂

使用场景:

绝大部分下我们都应该用epoll,因为epoll的优点导致它在大部分情况下都比select的效率更高,但如果我们是在局域网并且访问量不大的时候就可以使用select,这样select的效率反而会高,而且相对简单

}

3、支持定时器、信号等事件


安装使用:

1、在终端上输入  git clone  https://github.com/libevent/libevent.git 便可下载安装包,或者进入官网下载安装包。

2、在终端上依次输入以下命令

cd libevent

./autogen.sh

./configure

make

sudo make install

3、通过第2步就安装完成了,此时你会发现  /usr/local/lib 这个目录下会新增好多的库,我们只需用libevent_core(主要包含事件跟缓冲功能)这个库,也就说在运行程序的时候只需要链接(-levent_core)到这个库,而头文件在/usr/local/include/event2这个目录中,在源文件中我们要这样包含头文件#include<event2/event.h>,event2.h是这个目录下的一个头文件


常用的API(这里没看懂不要紧吐舌头,下一篇我将用以下的API搭建client跟server,用代码说话)


//以下几个函数的头文件都是<event2/event.h>


//返回一个指向struct event_base结构体的指针,用来管理事件

struct event_base *event_base_new(void);


//释放struct event_base结构体对象

int event_base_free(struct event_base *base);


//循环等待事件的发生

int event_base_dispatch(struct event_base *base);


//停止循环

//如果event_base正在执行激活事件的回调,它将执行完当前的事件立刻退出循环

event_base_loopbreak(struct event_base *base);


//注册事件

//base是event_base_new返回的base

//fd是要监听的文件描述符

//what是事件标志(一般写EV_READ|EV_PERSIST)表示事件是持久的、在读取的时候事件被激活

//cb是回调函数名,函数原型是 void  cb (evutil_socket_t fd,short what ,void * arg);

//arg是传给cb的最后一个形参的

//evutil_socket_fd其实就是int类型

struct event *event_new(struct event_base *base,evutil_socket_t fd,short what,event_callback_fn cb,void *arg);


//让事件成为未决的,因为调用event_new注册的事件刚刚开始是非未决的

//ev是event_new返回的值

//tv一般设置为NULL

int event_add(struct event *ev,const struct timeval *tv);



//关闭套接字,这个函数的头文件是<event2/util.h>

int evutil_closesocket(evutil_socket_t socketfd);



//以下几个函数的头文件是<event2/bufferevent.h>,<event2/buffer.h>


//返回一个指向struct bufferevent的对象

//base是event_base_new函数的返回值

//fd是一个文件描述符,如果是服务器就是accept产生的fd,如果是客户端那就是socket函数产生的fd

//option一般为BEV_OPT_CLOSE_ON_FREE(表示释放bufferevent时关闭底层传输端口)

struct bufferevent * bufferevent_socket_new(struct event_base *base,evutil_sock_t fd,enum bufferevent_options options);


//释放struct bufferevent对象

 int  bufferevent_free(struct bufferevent *buefv);


//设置回调,当缓冲区有东西可读可写或者出错时,调用相应的回调函数

//bufev是bufferevent_socket_new函数的返回值

//readcb的原型是      void  readcb(struct bufferevent *bev, void *ctx);

//writecb的原型是    void  readcb(struct bufferevent *bev, void *ctx);

//eventcb的原型是    void (*bufferevent_event_cb)(struct bufferevent *bev, short what, void *ctx);

//ctx是传给回调函数的参数

void bufferevent_setcb(struct bufferevent *bufev,bufferevent_data_cb readcb, bufferevent_data_cb writecb, bufferevent_event_cb eventcb, void *ctx);


//启动回调、水位

//event一般写EV_READ|EV_PERSIST,启用读事件并且保持持久状态

int bufferevent_enable(struct bufferevent *bufev, short event);


//读取bufferevent里面的数据,可以简单理解为读取对方发送过来的数据

size_t bufferevent_read(struct bufferevent *bufev, void *data, size_t size);


//往bufferevent里面写数据,可以简单理解为向对方发送数据

int bufferevent_write(struct bufferevent *bufev,const void *data, size_t size);


//当客户端没有调用connect函数连接服务器的时候,可以使用这个函数

//bufev是bufferevent_socket_new函数的返回值

//addr跟addrlen的这两个参数跟connect的两个参数是一样的

//该函数参数会产生一个新的套接字,并且是非阻塞的

int bufferevent_socket_connect(struct bufferevent * bufev, const struct sockaddr *addr, int addrlen);






作者:****@鸿定义@****

提前祝大家新年快乐**&**



0 0
原创粉丝点击