1.简介
libevent是一个事件驱动的网络库,主要用于构建可扩展的网络服务器。它提供了跨平台的API,支持多种事件通知机制,如select、poll、epoll、kqueue等。
主要组件
- event: 表示一个具体的事件,包括事件类型、事件回调等。
- event_base: 用于管理所有的事件,负责事件的添加、删除和分发。
- buffer: 提供缓冲区操作,用于网络数据的读写。
- evbuffer: 提供增强的缓冲区操作,支持链式缓冲区。
- bufferevent: 基于buffer和evbuffer的更高层次的抽象,用于简化网络数据的读写。
2.工作原理
libevent的工作原理基于事件驱动模型。
事件循环(Event Loop)
libevent的核心是一个事件循环,它不断地检查是否有事件发生,并在事件发生时调用相应的回调函数。这个循环是由event_base_dispatch()函数启动的,它会一直运行直到被明确地要求退出。
事件(Events)
在libevent中,事件可以是多种类型,包括:
- I/O事件:文件描述符变得可读、可写或发生异常。
- 定时器事件:在指定的时间间隔后触发。
- 信号事件:当特定的信号发生时触发。
- 持续事件:定期触发,用于执行周期性的任务。
事件驱动模型(Event-Driven Model)
libevent使用事件驱动模型来管理事件。它将事件与回调函数关联起来,当事件发生时,libevent会调用相应的回调函数来处理事件。
事件处理器(Event Handler)
事件处理器是libevent中用于管理事件的内部结构。它包含了事件的信息,如文件描述符、事件类型、回调函数和用户数据。libevent提供了event和bufferevent两种主要的事件处理器:
- event:用于处理基本的I/O事件、定时器和信号。
- bufferevent:提供了更高层次的抽象,用于处理带缓冲的I/O操作,简化了读写操作。
3.常用接口介绍
event_base 相关接口:
-
struct event_base *event_base_new(void);
创建一个新的event_base结构,这是使用libevent的第一步。 -
int event_base_dispatch(struct event_base *base);
开始event_base的事件循环,这个函数会一直运行,直到没有活动的事件或者调用了event_base_loopbreak()或event_base_loopexit()。 -
void event_base_free(struct event_base *base);
释放event_base结构及其所有关联的资源。 -
int event_base_set(struct event_base *base, struct event *ev);
设置event使用的event_base。
event 相关接口:
-
struct event *event_new(struct event_base *base, evutil_socket_t fd,
short events,event_callback_fn callback, void *callback_arg);
创建一个新的event,指定事件base、文件描述符、事件类型、回调函数和用户数据。 -
int event_add(struct event*ev, const struct timeval *tv);
将event添加到其event_base中,可以指定一个timeval结构来设置事件的超时时间。 -
int event_del(structevent *ev);
从event_base中删除一个event。 -
void event_free(struct event *ev);
释放event结构及其所有关联的资源。
bufferevent 相关接口:
-
struct bufferevent *bufferevent_socket_new(struct event_base *base,
evutil_socket_t fd, int options);
创建一个新的bufferevent,它封装了socket操作,可以用于读写网络数据。 -
int bufferevent_setcb(struct bufferevent *bev, bufferevent_data_cb
readcb, bufferevent_data_cb writecb, bufferevent_event_cb eventcb,
void *cbarg);
设置bufferevent的回调函数,包括读回调、写回调和事件回调。 -
int bufferevent_enable(struct bufferevent *bev, short event);
启用bufferevent的特定事件,如读事件、写事件。 -
int bufferevent_disable(struct bufferevent *bev, short event);
禁用bufferevent的特定事件。 -
int bufferevent_free(struct bufferevent *bev);
释放bufferevent及其所有关联的资源。
HTTP服务器相关接口:
-
struct evhttp *evhttp_new(struct event_base *base);
创建一个新的HTTP服务器。 -
void evhttp_set_gencb(struct evhttp *http, void (*cb)(struct evhttp_request *, void *), void *arg);
设置HTTP服务器的通用请求回调函数。 -
struct evhttp_bound_socket *evhttp_bind_socket_with_handle(struct
evhttp *http, const char *address, ev_uint16_t port);
将HTTP服务器绑定到指定的地址和端口。 -
void evhttp_free(struct evhttp *http);
释放HTTP服务器及其所有关联的资源。
4.环境搭建
下载地址:https://github.com/libevent/libevent
下载完成,进行解压,然后使用cmake编译。
生成库如下图所示:
拷贝如下文件和lib文件到我们的demo工程中。
源码目录的下的include目录和编译后的include目录,以及lib、dll库。
配置visual studio环境,请看Jsoncpp介绍。如何配置include、lib目录。
5.示例
下面是一个简单的libevent服务器示例,监听TCP连接,接收客户端数据并回显。
#include <stdio.h>
#include <string.h>
#include <event.h>
#include <evhttp.h>
void request_handler(struct evhttp_request *req, void *arg)
{
struct evbuffer *buf;
const char *uri = evhttp_request_get_uri(req);
printf("Received a request: %s\n", uri);
buf = evbuffer_new();
evbuffer_add_printf(buf, "Hello, World! Your request uri is: %s", uri);
evhttp_send_reply(req, HTTP_OK, "OK", buf);
evbuffer_free(buf);
}
int main()
{
struct event_base *base;
struct evhttp *http;
struct evhttp_bound_socket *handle;
base = event_base_new();
if (!base) {
fprintf(stderr, "Failed to create event base\n");
return 1;
}
http = evhttp_new(base);
if (!http) {
fprintf(stderr, "Failed to create evhttp\n");
return 1;
}
evhttp_set_gencb(http, request_handler, NULL);
handle = evhttp_bind_socket_with_handle(http, "127.0.0.1", 8080);
if (!handle) {
fprintf(stderr, "Failed to bind socket\n");
return 1;
}
printf("Listening on 8080\n");
event_base_dispatch(base);
evhttp_free(http);
event_base_free(base);
return 0;
}
6.更多参考
libVLC 专栏介绍-CSDN博客
Qt+FFmpeg+opengl从零制作视频播放器-1.项目介绍_qt opengl视频播放器-CSDN博客
QCharts -1.概述-CSDN博客
压缩和归档库-LZ4介绍