开源。精简。跨平台(Windows、Linux、Maxos、unix)。专注于网络通信。
源码包安装:
./configure 检查安装环境 生成makefile
make 生成.o和可执行文件
sudo make install 将必要的资源cp至系统指定目录。
进入sample目录,运行demo验证库安装使用情况。
编译使用库的.c时,需要加-levent选项。
库名libevent.so--> /usr/local/lib 查看得到。
特性:
基于“事件”异步通信模型。---回调。
libevent框架:
1. 创建event_base (乐高底座)
struct event_base *event_base_new(void);
struct event_base *event *base=event_base_new();
2. 创建 事件event
常规事件 event -->event_new();
bufferevent -->bufferevnet_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);
创建事件:
struct event *ev;struct event *evennt_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
从event_base上摘下事件 【了解】
int event_del(struct event *ev); ev:event_new()的返回值。
销毁事件:
int event_free(struct event *ev); ev:event_new()的返回值。
未决和非未决:
非未决:没有资格被处理
未决:有资格被处理,但尚未被处理
event_new--->event---->非未决--->event_add--->未决--->dispatch()&&监听事件被触发-->激活态
——>执行回调函数--->处理态--->非未决 event_add && EV_PERSIST---->未决--->event_del--->非未决
带缓冲区的事件 bufferevent
#include<event2/buffereevent.h>
创建、销毁bufferevent
struct bufferent *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事件对象。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 reacb, bufferevent_data_cb writecb, bufferevent_data_cb eventcb , void *cbarg );bufev:bufferevent_socket_new()返回值readcb:设置bufferevent 度缓冲,对应回调 read_cb{ bufferevent_read() 读数据 }writecb:设置bufferevent 写缓冲,对应回调write_cb{ } ---给调用者,发送写成功通知。 可以NULLeventcb:设置事件回调。 也可以传NULL typedef void(*bufferevent_data_cb)(struct bufferevent *bev,void*ctx); void event_cb(struct bufferevent *bev, short events, void *cbarg) { 。。。。。 }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 bufferent_enable(event,EV_READ); --开启读缓冲
创建监听服务器:
socket();bind();listen();accept();struct evconnlistener *listnerstruct 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_basecb:回调函数。 一旦被回调,说明在其内部应该与客户端完成,数据读写操作,进行通信。ptr:回调函数的参数flags:LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLEbacklog:listen() 2参。 -1表最大值sa:服务器自己的地址结构体socklen:服务器自己的地址结构体大小。返回值:成功创建的监听器。
连接客户端:
socket(); connect();int bufferevent_socket_connect(struct bufferevent *bev, struct sockaddr *address, int addrlen); bev:bufferevent 事件对象(封装了fd) address、len:等同于connect()参2/3
服务器端libevent创建TCP连接:
1.创建event_base2.创建bufferevent事件对象。bufferevent_socket_new();3.使用bufferevent_setcb()函数给bufferevent的read、write、event设置回调函数。4.当监听的事件满足时,read_cb会被调用,在其内部bufferevent_read(); 读5.使用evconnlistener_new_bind创建监听服务器,设置其回调函数,当有客户端成功连接时,这个回调函数会被调用。6.封装listner_cb()在函数内部。完成与客户端通信。7.设置读缓冲、写缓冲的 使能状态 enable、disable8.启动循环event_base_dispath();9.释放连接
客户端libevent创建TCP连接:
1.创建event_base2.使用bufferevent_socket_new()创建一个用跟踪服务器通信的bufferevnet事件对象3.使用bufferevent_socket_connect()连接 服务器4.使用bufferevent_setcb()给bufferevnet对象的read、write、event设置回调5.设置bufferenet对象的读写缓冲区enable/disable7.启动循环event_base_dispath();8.释放连接
web——HTTP请求协议:
1.getline()获取http协议的第一行。2.从首行中拆分 GET、文件名、协议版本。获取用户请求的文件名。3.判断文件是否存在。stat()4.判断是文件还是目录。5.是文件--open--read --写会给浏览器6.先写http应答协议头:http/1.1 200 ok7.写文件数据。