Libevent的使用介绍

Libevent的使用介绍

libevent是一个事件驱动的网络编程库,用于高效地管理网络连接并处理I/O事件。下面是libevent库的一些常用函数接口介绍和例子:

常用函数接口介绍

event_init()

在程序初始化时,需要调用event_init()函数来初始化libevent库。
返回一个event_base指针,如果初始化失败则返回NULL

struct event_base *base = event_init();
if (!base) {
    fprintf(stderr, "Could not initialize libevent!\n");
    return -1;
}

event_new()

创建新事件并返回一个事件对象,用于监听文件描述符的I/O事件.该函数可能返回NULL指针,表示创建事件失败。

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

base: 事件基础,重点是为了处理I/O多路复用等事件。
fd: 事件所关联的文件描述符,fd在被管理的时候会被设置成非阻塞模式。
events: 监听的事件类型,例如可读、可写等。
在这里插入图片描述

cb: 事件触发时的回调函数。
arg: 用于与回调函数进行通信的参数。回调函数的实参。可以在回调函数中强转成想要的类型

event_add()

将一个新的事件添加到事件管理器中,事件管理器在管理的文件描述符上等待事件发生。

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

ev: 指向要添加的事件的指针。
tv: 如果非NULL,则指定事件最多允许阻塞的时间;如果该事件处于活动状态,则会重新计时。

event_base_dispatch()

启动事件处理循环,直到事件队列为空或事件管理器被释放。此函数是事件通知的基础,通常用于服务器和长期运行的客户端应用程序。

int event_base_dispatch(struct event_base *base);

自己实现的基于libevent框架的服务器端的例子

#include <string.h> 
#include <unistd.h> 
#include <stdlib.h> 
#include<sys/signal.h>
#include<event.h>

void on_accept(evutil_socket_t listener, short event, void *arg)
{
    struct event_base *base = arg;
    struct sockaddr_storage ss;
    socklen_t slen = sizeof(ss);
    int fd = accept(listener, (struct sockaddr*)&ss, &slen);

    if (fd < 0) {
        fprintf(stderr, "Failed to accept client connection: %s\n",
                strerror(errno));
        return;
    }

    char ip[INET6_ADDRSTRLEN];
    void *addr;
    if (ss.ss_family == AF_INET) {
        struct sockaddr_in *s = (struct sockaddr_in *)&ss;
        addr = &(s->sin_addr);
    } else {
        struct sockaddr_in6 *s = (struct sockaddr_in6 *)&ss;
        addr = &(s->sin6_addr);
    }
    inet_ntop(ss.ss_family, addr, ip, sizeof(ip));

    printf("Accepted connection from %s\n", ip);

    // 将新连接加入事件循环,等待读取数据
    struct event *ev = event_new(base, fd, EV_READ | EV_PERSIST, on_read, base);
    event_add(ev, NULL);
}

void on_read(evutil_socket_t fd, short event, void *arg)
{
    struct event_base *base = arg;
    char buf[1024];
    size_t n = recv(fd, buf, sizeof(buf), 0);

    if (n == 0) {
        printf("Connection closed.\n");
    } else if (n < 0) {
        fprintf(stderr, "Error on read: %s\n", strerror(errno));
    } else {
        printf("Received %zu bytes: %.*s\n", n, (int)n, buf);

        // 回写给客户端
        send(fd, buf, n, 0);
    }

    // 从事件循环中删除这个事件
    event_del(event_get_struct_eventarg((struct event*)arg));
    event_free((struct event*)arg);
    close(fd);
}

int main()
{   
    //创建用于监听的文件描述符sockfd,并进行bind,listen
    //这里我是伪代码
    int sockfd=Sock_Init();
    //创建libevent实例
    struct event_base*base=event_init();
    //为用于监听的文件描述创建事件对象,如果该文件描述符对应事件发生则会执行回调函数

    //需要把base传入,发生事件(有客户端连接)在回调函数中需要接受该描述符并添加到base(libevent实例中)
    struct event*p=event_new(base,sockfd,EV_READ||EV_PERSIST,on_accept,base);

    event_add(p,0);
//启动事件循环
    event_base_dispatch(base);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值