libevent介绍和使用

news2024/11/26 14:31:27

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) 消息事件循环

在这里插入图片描述
在网络事件框架中,我们主要关注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对象来进行操作的。

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/525281.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

最全面的ChatGPT镜像网址:值得三连~~~

ChatGPT是一个基于人工智能的聊天机器人&#xff0c;它可以与用户进行自然语言交互。ChatGPT使用了最新的自然语言处理技术&#xff0c;包括深度学习和神经网络&#xff0c;以便更好地理解用户的意图和回答用户的问题。 ChatGPT可以回答各种问题&#xff0c;包括但不限于常见问…

69.建立手风琴组件第二部分

上节课我们构建了下图一样的基本样式&#xff0c;这节课我们来构建布局&#xff01; ● 建立阴影&#xff0c;并生成grid布局 .item {box-shadow: 0 0 32px rgba(0,0,0,0.1);#添加外阴影&#xff0c;为半透明黑色&#xff0c;大小为0&#xff0c;0&#xff0c;32pxpadding: 24p…

C++编译Boost库读写和解析JSON文件和XML文件(2023.5.14)

C编译Boost读写并解析JSON文件和XML文件 需求分析前提环境&#xff08;Win11、VS 2015&#xff09;1、Boost简介1.1 为何使用Boost&#xff1f;1.2 Boost快速上手&#xff08;Windows系统&#xff09; 2、Boost 安装和使用2.1 自己下载源码编译生成Boost库(v 1.82.0)2.2 从官网…

基于微信平台教务管理系统的设计与实现(论文+源码)_kaic

摘 要 网络技术的快速发展也使得越来越多的研究学者将计算机技术应用到停车、医疗、商业、旅游等各行各业&#xff0c;这些传统行业在计算机技术的催动下&#xff0c;正在快速发展。为了顺应时代发展的变化&#xff0c;将计算机技术应用到教务管理领域显得极为重要。 本文设计…

哈希表+unordered_map封装

目录 1&#xff1a;hashtable.h 2&#xff1a;unordered_map.h 3&#xff1a;unordered_set 4&#xff1a;讲解 1&#xff1a;hashtable.h #pragma once #include<vector> using namespace std; namespace OpenAdress {enum State{EXIST,DELETE,EMPTY,};template<c…

redis淘汰策略

8种淘汰策略 volatile-lru&#xff0c;针对设置了过期时间的key&#xff0c;使用lru算法进行淘汰。 allkeys-lru&#xff0c;针对所有key使用lru算法进行淘汰。 volatile-lfu&#xff0c;针对设置了过期时间的key&#xff0c;使用lfu算法进行淘汰。 allkeys-lfu&#xff0c;针…

『C++』特殊类设计

「前言」文章是关于C特殊类设计方面的 「归属专栏」C嘎嘎 「笔者」枫叶先生(fy) 「座右铭」前行路上修真我 「枫叶先生有点文青病」 「每篇一句」 一点浩然气&#xff0c;千里快哉风。 ——苏轼《水调歌头黄州快哉亭赠张偓佺》 目录 一、请设计一个类&#xff0c;不能被拷贝 …

IDEA开发实现Maven+Servlet+Mybatis实现CRUD管理系统-Mapper代理开发

Mapper代理开发概述 之前我们写的代码是基本使用方式&#xff0c;它也存在硬编码的问题&#xff0c;如下&#xff1a; 这里调用 selectList() 方法传递的参数是映射配置文件中的 namespace.id值。这样写也不便于后期的维护。如果使用 Mapper 代理方式&#xff08;如下图&…

stm32之hal库学习(3)---STM32 启动模式分析

启动模式 我们知道的复位方式有三种&#xff1a;上电复位&#xff0c;硬件复位和软件复位。当产生复位&#xff0c;并且离开复 位状态后&#xff0c;CM3 内核做的第一件事就是读取下列两个 32 位整数的值&#xff1a; &#xff08;1&#xff09;从地址 0x0000 0000 处取出堆栈…

Linux基本指令----下

Linux基本指令----下 date指令cal指令find指令which指令whereis指令grep指令du指令zip/unzip指令tar指令bc指令uname -r指令关机指令重要热键结语 date指令 语法&#xff1a; date 指定格式显示时间&#xff1a; date %Y:%m:%d&#xff0c;date 用法&#xff1a;date [OPTION]…

【FPGA零基础学习之旅#5】产生非等占空比信号

&#x1f389;欢迎来到FPGA专栏~产生非等占空比信号 ☆* o(≧▽≦)o *☆嗨~我是小夏与酒&#x1f379; ✨博客主页&#xff1a;小夏与酒的博客 &#x1f388;该系列文章专栏&#xff1a;FPGA学习之旅 文章作者技术和水平有限&#xff0c;如果文中出现错误&#xff0c;希望大家能…

字节跳动 测试开发工程师 面试总结,小伙伴可以参考一下

目录 一面 二面 三面 个人总结&#xff1a; 一面 自我介绍 操作系统 虚拟内存的概念 进程和线程 线程同步 如何实现线程同步 计算机网络 说一下TCP 为什么是四次挥手呢 说一个ip地址&#xff0c;如果第一字节是269行不行 说一下HTTP&#xff08;自己讲了GET POST&…

[abc复盘] abc301 20230514

[abc复盘] abc301 20230514 总结A - Overall Winner1. 题目描述2. 思路分析3. 代码实现 B - Fill the Gaps1. 题目描述2. 思路分析3. 代码实现 C - AtCoder Cards1. 题目描述2. 思路分析3. 代码实现 D - Bitmask1. 题目描述2. 思路分析3. 代码实现 E - Pac-Takahashi1. 题目描…

Azure描述云服务类型

Azure描述云服务类型 基础结构即服务&#xff08;IaaS&#xff09;共担责任模型方案 介绍平台即服务&#xff08;PaaS&#xff09;共担责任模型方案 描述软件即服务&#xff08;SaaS&#xff09;共担责任模型方案 描述责任共担模型知识检查题目 基础结构即服务&#xff08;IaaS…

pyqt实现文件批量操作

代码逻辑 https://download.csdn.net/download/Lynqwest/87783077 文件打包 一、安装UPX 在https://github.com/upx/upx/releases/tag/v3.96下载相关版本&#xff0c;该网址无法进入&#xff0c;可参考https://download.csdn.net/download/Lynqwest/87783084 下载后将 upx…

谓词逻辑与推理演算

谓词逻辑 辖域 变元的约束—换自由变元 不容易出错 枚举 前束范式 量词例子 全称量词 ( ∀ x ) 条件前件加入 → (\forall x) 条件前件加入 \to (∀x)条件前件加入→ 存在量词 ( ∃ x ) 和取式 ∧ (\exists x) 和取式 \wedge (∃x)和取式∧ ∀ x P ( x ) ⟺ ∃ x P ( x ) \…

Mac M2芯片免安装版mysql

文章目录 1、下载mysql安装包2、移动解压目录并授权3、初始化mysql4、启动mysql5、启动错误处理6、登录mysql7、重置mysql密码 1、下载mysql安装包 先看一下本机mac信息 左上角&#xff0c;单机苹果的logo&#xff0c;然后单击“关于本机”&#xff0c;可以看到当前mac的信息 …

【JAVA进阶】Set集合、Map集合

&#x1f4c3;个人主页&#xff1a;个人主页 &#x1f525;系列专栏&#xff1a;JAVASE基础 目录 一、Set系列集合 1.HashSet 2.LinkedHashSet 3.TreeSet 二、补充知识 1.可变参数 2.集合工具类Collections 三、Map集合体系 1.Map集合的概述 2.Map集合体系特点 3.Map…

mybatis plus自动生成代码(代码生成器)

参考 05_尚硅谷_搭建项目环境&#xff08;代码生成器&#xff09;_哔哩哔哩_bilibili 调用mp的AutoGenerator可以生成代码&#xff0c;就像java脚本一样&#xff0c;运行即可生成 要求代码生成器脚本不用会写&#xff0c;会修改其中条项生成我们预期的代码即可。 项目整体结构…

前端 之 FormData对象浅谈

一、简介 ​ 通常情况下&#xff0c;前端在使用post请求提交数据的时候&#xff0c;请求都是采用application/json 或 application/x-www-form-urlencoded编码类型&#xff0c;分别是借助JSON字符串来传递参数或者keyvalue格式字符串&#xff08;多参数通过&进行连接&…