libevent开源库

开源。精简。跨平台(Windows、Linux、maxos、unix)。专注于网络通信

1、官网下载源码包:libevent

我下载的是libevent-2.1.8-stable

2、解压:

tar zxvf libevent-2.1.8-stable.tar.gz

3、源码包安装:  参考 README、readme

./configure       检查安装环境 生成 makefile

make          生成 .o 和 可执行文件            

sudo make install 将必要的资源cp至系统指定目录。

进入 sample 目录,运行demo验证库安装使用情况。

编译使用库的 .c 时,需要加 -levent 选项。

库名 libevent.so --> /usr/local/lib   查看的到。

特性:

    基于“事件”异步通信模型。--- 回调。

libevent框架

libevent框架:

    1. 创建 event_base       (乐高底座)

    2. 创建 事件evnet   

    3. 将事件 添加到 base上

    4. 循环监听事件满足

    5. 释放 event_base

1. 创建 event_base       (乐高底座)

       struct event_base *event_base_new(void);

       struct event_base *base = event_base_new();

2. 创建 事件evnet   

       常规事件 event    --> event_new();

       bufferevent --> bufferevent_socket_new();

3. 将事件 添加到 base上

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

4. 循环监听事件满足

       int event_base_dispatch(struct event_base *base);

           event_base_dispatch(base);

5. 释放 event_base

       event_base_free(base);

创建事件event:

	struct event *ev;

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

		base: event_base_new()返回值。

		 fd: 绑定到 event 上的 文件描述符

		what:对应的事件(r、w、e)

			EV_READ		一次 读事件

			EV_WRTIE	一次 写事件

			EV_PERSIST	持续触发。 结合 event_base_dispatch 函数使用,生效。

		cb:一旦事件满足监听条件,回调的函数。

		typedef void (*event_callback_fn)(evutil_socket_t fd,  short,  void *)	

		arg: 回调的函数的参数。

		返回值:成功创建的 event
添加事件到 event_base

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

		ev: event_new() 的返回值。

		tv:NULL


销毁事件

	int event_free(struct event *ev);

		ev: event_new() 的返回值。

使用fifo的读写

读端

#include <stdio.h>  
#include <unistd.h>  
#include <stdlib.h>  
#include <sys/types.h>  
#include <sys/stat.h>  
#include <string.h>  
#include <fcntl.h>  
#include <event2/event.h>  
  
// 对操作处理函数  
void read_cb(evutil_socket_t fd, short what, void *arg)  
{  
    // 读管道  
    char buf[1024] = {0};  
      
    int len = read(fd, buf, sizeof(buf));  
      
    printf("read event: %s \n", what & EV_READ ? "Yes" : "No");  
    printf("data len = %d, buf = %s\n", len, buf);  
      
    sleep(1);  
}  
  
  
// 读管道  
int main(int argc, const char* argv[])  
{  
    unlink("myfifo");  
  
    //创建有名管道  
    mkfifo("myfifo", 0664);  
  
    // open file  
    //int fd = open("myfifo", O_RDONLY | O_NONBLOCK);  
    int fd = open("myfifo", O_RDONLY);  
    if(fd == -1)  
    {  
        perror("open error");  
        exit(1);  
    }  
  
    // 创建个event_base  
    struct event_base* base = NULL;  
    base = event_base_new();  
  
    // 创建事件  
    struct event* ev = NULL;  
    ev = event_new(base, fd, EV_READ | EV_PERSIST, read_cb, NULL);  
  
    // 添加事件  
    event_add(ev, NULL);  
  
    // 事件循环  
    event_base_dispatch(base);  // while(1) { epoll();}  
  
    // 释放资源  
    event_free(ev);  
    event_base_free(base);  
    close(fd);  
      
    return 0;  
}  

写端

#include <stdio.h>  
#include <unistd.h>  
#include <stdlib.h>  
#include <sys/types.h>  
#include <sys/stat.h>  
#include <string.h>  
#include <fcntl.h>  
#include <event2/event.h>  
  
// 对操作处理函数  
void write_cb(evutil_socket_t fd, short what, void *arg)  
{  
    // write管道  
    char buf[1024] = {0};  
      
    static int num = 0;  
    sprintf(buf, "hello,world-%d\n", num++);  
    write(fd, buf, strlen(buf)+1);  
      
    sleep(1);  
}  
  
  
// 写管道  
int main(int argc, const char* argv[])  
{  
    // open file  
    //int fd = open("myfifo", O_WRONLY | O_NONBLOCK);  
    int fd = open("myfifo", O_WRONLY);  
    if(fd == -1)  
    {  
        perror("open error");  
        exit(1);  
    }  
  
    // 写管道  
    struct event_base* base = NULL;  
    base = event_base_new();  
  
    // 创建事件  
    struct event* ev = NULL;  
    // 检测的写缓冲区是否有空间写  
    //ev = event_new(base, fd, EV_WRITE , write_cb, NULL);  
    ev = event_new(base, fd, EV_WRITE | EV_PERSIST, write_cb, NULL);  
  
    // 添加事件  
    event_add(ev, NULL);  
  
    // 事件循环  
    event_base_dispatch(base);  
  
    // 释放资源  
    event_free(ev);  
    event_base_free(base);  
    close(fd);  
      
    return 0;  
}  

编译运行,结果如下:

未决和非未决

非未决: 没有资格被处理

 未决: 有资格被处理,但尚未被处理

    event_new --> event ---> 非未决 --> event_add --> 未决 --> dispatch() && 监听事件被触发 --> 激活态

    --> 执行回调函数 --> 处理态 --> 非未决 event_add && EV_PERSIST --> 未决 --> event_del --> 非未决

bufferevent

带缓冲区的事件 bufferevent

    #include <event2/bufferevent.h>

    read/write 两个缓冲. 借助 队列.

bufferevent事件对象创建、销毁

创建、销毁bufferevent:

	struct bufferevent *ev;

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

		base: event_base

		fd:	封装到bufferevent内的 fd

		options:BEV_OPT_CLOSE_ON_FREE
//释放bufferevent时关闭底层传输端口。这将关闭底层套接字,释放底层bufferevent等

	返回: 成功创建的 bufferevent事件对象。

	
	void  bufferevent_socket_free(struct bufferevent *ev);

 给读写缓存区设置回调

给bufferevent设置回调:
	
	对比event:	event_new( fd, callback );  					event_add() -- 挂到 event_base 上。

	
			bufferevent_socket_new(fd)  bufferevent_setcb( callback )

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

	bufev: bufferevent_socket_new() 返回值

	readcb: 设置 bufferevent 读缓冲,对应回调  read_cb{  bufferevent_read() 读数据  }

	writecb: 设置 bufferevent 写缓冲,对应回调 write_cb {  } -- 给调用者,发送写成功通知。  可以 NULL

	eventcb: 设置 事件回调。   也可传NULL

		typedef void (*bufferevent_event_cb)(struct bufferevent *bev,  short events, void *ctx);

		void event_cb(struct bufferevent *bev,  short events, void *ctx)
		{

			。。。。。
		}

		events: BEV_EVENT_CONNECTED
//请求的连接过程已经完成,实现客户端时可用

	cbarg:	上述回调函数使用的 参数。

	read 回调函数类型:

		typedef void (*bufferevent_data_cb)(struct bufferevent *bev, void*ctx);

		void read_cb(struct bufferevent *bev, void *cbarg )
		{
			.....
			bufferevent_read();   --- read();
		}

	bufferevent_read()函数的原型:

		size_t bufferevent_read(struct bufferevent *bev, void *buf, size_t bufsize);

	
	write 回调函数类型:

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

缓冲区的开启关闭

启动、关闭 bufferevent的 缓冲区:

    void bufferevent_enable(struct bufferevent *bufev, short events);   启动  

       events: EV_READ、EV_WRITE、EV_READ|EV_WRITE

       默认、write 缓冲是 enable、read 缓冲是 disable

           bufferevent_enable(evev, EV_READ);     -- 开启读缓冲。

客户端和服务器连接和监听

连接客户端:

    socket();connect();

    int bufferevent_socket_connect(struct bufferevent *bev, struct sockaddr *address, int addrlen);

       bev: bufferevent 事件对象(封装了fd)

       address、len:等同于 connect() 参2/3

创建监听服务器:

    ------ socket();bind();listen();accept();

    struct evconnlistener * listner

    struct evconnlistener *evconnlistener_new_bind (

       struct event_base *base,

       evconnlistener_cb cb,

       void *ptr,

       unsigned flags,

       int backlog,

       const struct sockaddr *sa,

       int socklen);

    base: event_base

    cb: 回调函数。 一旦被回调,说明在其内部应该与客户端完成, 数据读写操作,进行通信。

    ptr: 回调函数的参数

    flags: LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE

    backlog: listen() 2参。 -1 表最大值

    sa:服务器自己的地址结构体

    socklen:服务器自己的地址结构体大小。

    返回值:成功创建的监听器。

释放监听服务器:

    void evconnlistener_free(struct evconnlistener *lev);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值