libevent 网络库

本文详细介绍了libevent,一种基于epoll的轻量级网络开发库,涉及event结构体、event_base管理,以及如何使用evconnlistener简化服务器搭建和bufferevent处理读写操作,特别强调了线程安全和事件回调的配置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

libevent是一种支持i/o多路复用技术,epoll技术的轻量级网络开发库。

1. 两个重要的结构体 :

struct event :指一个事件(fd或者信号),供接下来监听使用。

struct event_base :统一管理所有事件,认为是所有事件的集合。

2.libevent 常用接口:

2.1 event_init :用于初始化事件集合

2.2 event_base_new 创建event_base对象

2.3 event_assign 给event对象赋值

2.5 event_add 将事件添加到集合中

2.4 event_set: 初始化事件, 将fd与事件ev绑定在一起,

函数原型:event_set( struct  event *env, int fd, shorts events,   void(callback*)(evutil_socket_t ,short,void*), void* arg)     事件   关联的文字描述符   事件类型  回调函数   回调函数参数 

事件类型:1  EV_TIMEOUT 定时器事件

                  2  EV_READ 可读事件  fd上有可以读取的数据

                  3   EV_WRITE 可写数据 表示fd 可写

                  4   EV_SIGNAL 信号事件   表示有信号到达

                  5   EV_PERSIST  事件持续化标志   事件处理后继续保持监听

callback 事件发生时调用的回调函数的指针

3. 搭建高并发服务器

3.1 之前在搭建服务器时,我们一般经过以下4个步骤:

1. socket() 创建套接字

2.  bind() 绑定信息

3.  listen()监听

4. accept()接受连接

libevent将4个步骤封装在一起,这就是evconnlistener_new_bind()函数,其作用就是创建监听tcp or udp对象,用于接受传入得数据或者连接。

其函数原型为

struct evconnlistener* evconnlistener_new_bind(struct event_base* base, evconnlistener_cb cb, void* ptr, unsigned flags, int backlog, const struct sockaddr *sa, int socklen)

struct event_base* base : 和监听器关联得事件集合

evconnlistener_cb cb:当新连接到达时会触发调用函数,如果设置为NULL,则监听器视为禁用直至回调函数被调用,回调函数的原型是:

void (*evconnlistener_cb) (struct evconnlistener * ,evutil_socket_t , struct sockaddr* ,int socklen, void *)

struct evconnlistener * :用于表示监听器的结构体,这个结合体中包括监听操作所需的信息与状态。

evutil_socket_t   :新连接或接受数据的文件描述符

struct sockaddr* :新连接的客户端地址信息或接收数据的对端地址信息。

int socklen: 上面结构体的大小

void *  :传递给回调函数的用户自定义参数

void* ptr  传递给回调函数的自定义的参数

unsigned flags:一组标志,用于指定监听器的行为和特性。其主要包括:

1. LEV_OPT_CLOSE_ON_FREE: 当事件基础被释放,自动关闭监听器,并自动释放相关资源。

2. LEV_OPT_REUSEABLE: 使地址具有重用的功能,即使之前的连接任处于time_out 的状态,也可以立即重用监听地址。

3. LEV_OPT_THREADSAFE:将监听器设置为线程安全模式,以支持多线程下并发操作。

4. LEV_OPT_DISABLED:将创建的监听器视为禁用状态,必须调用evconnlistener_enable()来解禁

5.  LEV_OPT_ LEAVE_SOCKETS_BLOCKING:在接受连接后,将套接字阻塞。

6.  LEV_OPT_CLOSE_ON_EXEC: 将套接字视为在exec系统调用时关闭。

这些可以通过 | 来组合使用

backlog:  设置监听队列的长度

const struct sockaddr *sa  指向sockaddr结构体的指针,存储服务器的ip以及端口。

我们现在一般使用的是 sockaddr_in 结构体,因此需要强转,(struct sockaddr*)&sockaddr_in;

该结构体需要我们填写以下3个方面:

sockaddr_in.sin_family = AF_INET;//地址族 iv4

sockaddr_in.sin_port = 端口;

sockaddr_in.sin_addr.s_addr = inet_addr(" ");//inet_addr是将字符串形式的地址转为网络字节序的二进制。

3.2 处理读取和写入数据的操作

bufferevent是提供一个缓冲区,用以后续处理读取和写入数据的操作,

一般步骤为:

1. 创建一个与回调函数中套接字文件描述符相关联的bufferevent对象

这里用到bufferevent_socket_new()

函数原型为:struct bufferevent* bufferevent_socket_new(struct event_base* base, evutil_socket_t fd, enum buffererevent_options)

struct event_base* base : 事件集合

fd:套接字文件描述符

buffererevent_options:bufferevent选项标志,控制其行为。以下有几种选择项:

BEV_OPT_CLOSE_ON_FREE:释放bufferevent对象时,关闭套接字,并释放相资源。

BEV_OPT_THREADSAFE: 启用线程安全,当多线程操作时,启用这一项来保证线程安全。

BEV_OPT_DEFER_CALLBACKS: 推迟回调,当设置此选项后,只有在执行event_base_loop或者event_base_dispatch()后,才执行回调函数。

BEV_OPT_UNLOCK_CALLBACKS: 解锁回调,当启用线程安全时,使用此选项可以在执行回调函数前解锁回调锁,可以减少回调函数执行期间的锁竞争。

BEV_OPT_CLOSE_ON_EXEC: 当利用exec函数执行新程序时,会关闭套接字,不会继承到新的进程中。

BEV_OPT_IGNORE_WATERMARKS: 启用后会忽略高水位和低水位,继续读取和写入数据。

BEV_OPT_SET_TIMEOUTS:启用超时设置,启动后,可以使用bufferevent_set_timeout()函数来设置读取写入数据的超时时间。

2. 给bufferevent对象设置回调函数

这里用到bufferevent_setcb函数,其函数原型为:void bufferevent_setcb(struct bufferevent *,

bufferevent_data_cb readcb, bufferevent_data_cb writecb, bufferevent_event_cb eventcb,void *cbarg)  参数意思分别为buffer对象,读事件回调函数,写事件回调函数,其他事件回调函数(比如异常事件),自定义参数。前面两种事件不需要哪个,就用NULL代替。

void readcb(struct bufferevent*bev,void* ctx)

void writecb(struct bufferevent*bev,void* ctx)

void eventcb(struct bufferevent*bev,short event ,void* ctx)  short event包括:"

1. BEV_EVENT_CONNECTED:连接已经建立

2. BEV_EVENT_ERROR: 发生错误。

3. BEV_EVENT_EOF:连接已经关闭。

4. BEV_EVENT_TIMEOUT: 超时事件。 

3. 激活buffer对象

这里用到bufferevent_enable函数来使能。其函数原型如下:

int buffererevent_enable (struct bufferevent*,short event)

第一个参数:buffer对象

第二个参数:EV_READ | EV_WRITE 的任意组合

         

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值