libevent介绍和使用

这篇具有很好参考价值的文章主要介绍了libevent介绍和使用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

libevent介绍

libevent 是一个开源的事件通知库,它提供了一个跨平台的抽象接口,libevnet处理的事件包括网络IO事件,定时事件以及信号事件。它可以在不同的操作系统上使用,包括Linux、Windows和Mac OS X等。libevent 的主要目的是提供高效的事件通知机制,用户无需关注平台检测处理事件的机制的差异,只需关注事件的具体处理。它可以用于编写服务器、客户端和其他网络应用程序。

libevent使用

网络中有很多说明libevent如何编译的文章,我就不介绍libevent的如何编译安装,首先我们使用一段代码来直观的展示libevent是如何使用的,然后在介绍libevent的流程和libevent的关键API。下面这段代码展示的是服务器接收客户端的消息,并返回消息给客户端。

#include<stdio.h>
#include<string.h>
#include<errno.h>
#include<unistd.h>
#include "event2/event.h"
void socket_read_cb(int fd, short events, void *arg);
//接收到客户端的回调处理
void socket_accept_cb(int fd, short events, void* arg)
{
    struct sockaddr_in addr;
    socklen_t len = sizeof(addr);
    evutil_socket_t clientfd = accept(fd, (struct sockaddr*)&addr, &len);
    evutil_make_socket_nonblocking(clientfd);//设置客户端socket为非阻塞模式
    printf("accept a client %d\n", clientfd);
    struct event_base* base = (struct event_base*)arg;
    struct event *ev = event_new(NULL, -1, 0, NULL, NULL);//分配一个事件
    event_assign(ev, base, clientfd, EV_READ | EV_PERSIST,
                 socket_read_cb, (void*)ev);
    event_add(ev, NULL);//将事件加入到事件管理器中进行管理
}
 
 //客户端发送数据的回调处理
void socket_read_cb(int fd, short events, void *arg)
{
    char msg[4096];
    struct event *ev = (struct event*)arg;
    int len = read(fd, msg, sizeof(msg) - 1);
    if( len <= 0 )
    {
        printf("client fd:%d disconnect\n", fd);
        event_free(ev);
        close(fd);
        return;
    }
    msg[len] = '\0';
    printf("recv the client msg: %s", msg);
    char reply_msg[4096] = "recvieced msg: ";
    strcat(reply_msg + strlen(reply_msg), msg);
    write(fd, reply_msg, strlen(reply_msg));
}
 
int socket_listen(int port)
{
    int errno_save;
    evutil_socket_t listenfd = socket(AF_INET, SOCK_STREAM, 0);
    if (listenfd == -1)
        return -1;
    evutil_make_listen_socket_reuseable(listenfd);//设置端口和地址为复用
    struct sockaddr_in sin;
    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = 0;
    sin.sin_port = htons(port);
    if (bind(listenfd, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
        evutil_closesocket(listenfd);
        return -1;
    }
    if (listen(listenfd, 5) < 0) {
        evutil_closesocket(listenfd);
        return -1;
    }
    evutil_make_socket_nonblocking(listenfd);//设置socket未非阻塞模式
    return listenfd;
}

int main(int argc, char** argv)
{
    int listenfd = socket_listen(8080);
    if (listenfd == -1)
    {
        printf("socket_listen error\n");
        return -1;
    }
    struct event_base* base = event_base_new();//创建事件管理器对象
    struct event* ev_listen = event_new(base, listenfd, EV_READ | EV_PERSIST,
                                        socket_accept_cb, base);//创建监听事件对象
    event_add(ev_listen, NULL);//将监听事件对象加入到事件管理器中进行管理
    event_base_dispatch(base);//消息循环(代码会被阻塞到此处)
    return 0;
}

libevent流程

Libevent框架本质上是一个典型的Reactor模式,所以只需要弄懂Reactor模型,libevent就八九不离十了。
Reactor模式,是一种事件驱动机制。应用程序需要提供相应的接口并注册到Reactor上,如果相应的事件发生,Reactor将主动调用应用程序注册的接口,这些接口又称为“回调函数”。
在Libevent中也是一样,向Libevent框架注册相应的事件和回调函数;当这些事件发生时,Libevent会调用这些回调函数处理相应的事件(I/O读写、定时和信号)。

(1) 创建事件管理器对象
(2) 创建事件对象,并将事件加入到事件管理器对象中
(3) 消息事件循环

libevent介绍和使用
在网络事件框架中,我们主要关注2个问题:事件的检测和事件的处理,同样,libevent也主要关注这2个方面,我们使用libevent,可以仅仅使用libevent的事件检测,事件处理的逻辑由我们自己来写,或者事件检测和事件处理都使用libevent提供的方式。
(1)事件的检测
事件管理器对象负责检测事件是否发生,比如是否发生了IO事件(比如是否有客户端的连接,客户端是否发送了数据),定时器事件是否超时等。
(2)事件的处理
当检测到事件发生时,我们应该对事件进行处理,以下是一些示例
a.连接建立时:构建黑白名单,限制最大连接数
b.连接断开时:释放连接和对应的资源
c.数据到达时:数据的处理
因此我们将libevent的API分为这2个方面

libevent API

事件检测相关

事件管理器API

event_base_new();//创建事件管理器对象
event_base_new_with_config();//带配置的事件管理器对象
event_base_free();//销毁事件管理器对象
event_base_loop();//事件循环
event_base_loopbreak();//事件循环退出
event_base_loopexit();//事件循环退出

事件API

event_new();//构建事件对象
event_free();//销毁事件对象
event_add();//注册事件
event_del();//注销事件
event_assign();//修改事件

事件操作API

连接接收

事件监听器对象用于服务器监听客户端的对象,对象为evconnlisterner

evconnlisterner_new();//创建事件监听器对象
evconnlisterner_new_bind();//创建事件监听器对象
evconnlisterner_free();//销毁事件监听器对象
evconnlisterner_set_error_cb();//设置错误回调

读,写,连接操作

libevent的读写和客户端连接操作主要使用bufferevent对象来进行操作的。文章来源地址https://www.toymoban.com/news/detail-444876.html

bufferevent_socket_new();//创建bufferevent对象
bufferevent_setcb();//设置bufferevent对象的事件回调(读,写,错误回调)
bufferevent_enable();//注册事件类型
bufferevent_disable();//注销事件类型
bufferevent_get_input();//获取读缓冲区
bufferevent_get_output();//获取写缓冲区
bufferevent_read();//读缓冲区
bufferevent_write();//写缓冲区
bufferevent_socket_connect();//连接操作

到了这里,关于libevent介绍和使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 介绍一个强大的免费开源.net反编译工具

    dnSpy 是一个用C#开发,开源的调试器和.NET 汇编编辑器。 即使您没有任何可用的源代码,也可以使用它来编辑和调试程序,并可以把代码导出成.net工程。

    2024年01月17日
    浏览(44)
  • libevent:windows环境配置+QT使用

    目录 libevent是什么 编译 QT使用 测试代码 Fast portable non-blocking network programming with Libevent http://www.wangafu.net/~nickm/libevent-book/TOC.html 这篇文档讲的很清楚,尤其是Chapter 1: A tiny introduction to asynchronous IO.,基本上讲清楚了大多数的内容 环境: 1、win10 64位 2、vs2015专业版(nmake)/Cmake 3、

    2024年02月16日
    浏览(32)
  • 【嵌入式开源库】MultiButton的使用,简单易用的事件驱动型按键驱动模块

    MultiButton 是一个小巧简单易用的事件驱动型按键驱动模块,可无限量扩展按键,按键事件的回调异步处理方式可以简化你的程序结构,去除冗余的按键处理硬编码,让你的按键业务逻辑更清晰。 本章使用环境: 正点原子stm32F4探索者 代码工程使用正点原子HAL库实验三-按键输

    2024年02月02日
    浏览(51)
  • 105-Linux_Libevent库的安装与使用

    Libevent 是开源社区的一款高性能的 I/O 框架库,使用 Libevent 的著名案例有:高性能的分布式内存对象缓存软件 memcached,Google 浏览器 Chromium 的 Linux 版本。 跨平台支持。 Libevent 支持 Linux、Unix 和 Windows。 统一事件源。Libevent 对 I/O 事件、信号和定时事件提供统一的处理。 线程

    2024年02月02日
    浏览(31)
  • Unity UGUI的EventSystem(事件系统)组件的介绍及使用

    EventSystem是Unity UGUI中的一个重要组件,用于处理用户输入事件,如点击、拖拽、滚动等。它负责将用户输入事件传递给合适的UI元素,并触发相应的事件回调函数。 EventSystem组件通过射线检测来确定用户输入事件发生的位置,并将事件传递给最合适的UI元素。它会根据UI元素的

    2024年02月16日
    浏览(123)
  • 如何在 Android 应用中使用 RecyclerView 实现一个列表显示,并实现点击事件?

    首先,需要在项目的 build.gradle 文件中添加 RecyclerView 的依赖: 接下来,在布局文件中添加 RecyclerView: 接着,需要创建一个 Adapter 类,用于将数据绑定到 RecyclerView 上,如下所示: 在 onBindViewHolder() 方法中,我们可以将数据绑定到 ViewHolder 中的视图上。 需要注意的是,在 V

    2024年02月05日
    浏览(49)
  • Unity UGUI的EventTrigger (事件监听器)组件的介绍及使用

    EventTrigger是Unity UGUI中的一个组件,用于监听和响应UI元素的各种事件,例如点击、拖拽、进入、离开等。通过EventTrigger组件,我们可以方便地为UI元素添加各种交互行为。 EventTrigger组件通过监听UI元素上的事件,并在事件触发时执行相应的回调函数。每个UI元素可以添加多个

    2024年02月15日
    浏览(50)
  • 使用Vue.js框架的指令和事件绑定实现一个购物车的页面布局

    使用了v-model指令来实现全选/全不选的功能,当全选框被点击时,isAllChecked的值会被改变。 使用了v-if指令来判断购物车中是否有商品,如果有商品则渲染商品列表,否则显示购物车为空的提示。 使用了v-for指令来遍历datalist数组,渲染每个商品项。 使用了@change事件来监听商

    2024年02月12日
    浏览(53)
  • TCP服务器的演变过程:C++使用libevent库开发服务器程序

    手把手教你从0开始编写TCP服务器程序,体验开局一块砖,大厦全靠垒。 为了避免篇幅过长使读者感到乏味,对【TCP服务器的开发】进行分阶段实现,一步步进行优化升级。 在上一章节介绍了如何使用epoll构建reactor网络模型开发高效的服务器,有了上一节的基础,本节将介绍

    2024年01月23日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包