libevent(12)bufferevent的基础知识

news2024/11/25 13:01:18

一、bufferevent的基本概念

bufferevent 是 libevent 中的一个事件缓冲 IO,内部实现了基本 socket recv/send 操作 ,用户只需要调用 bufferevent 的 API 即可实现数据的读写。

(1)缓冲区:每个 bufferevent 都有一个读缓冲区(input)和写缓冲区(output),数据结构为 evbuffer ,它是一个数据缓冲区,用于缓存网络上发送或接收的数据。

(2)回调:

// 读取和写入回调
typedef void (*bufferevent_data_cb)(struct bufferevent *bev, void *ctx);

// 事件回调,其中what表示发生的事件,具体后面有说明
typedef void (*bufferevent_event_cb)(struct bufferevent *bev, short what, void *ctx);

(3)水位:可以通过设置水位来调节回调函数的调用。

(3.1)读取低水位:输入缓冲区的数据量达到或超过此水位时,调用回调函数,即数据量达不到水位要求,则不会调用回调;

(3.2)读取高水位:输入缓冲区的数据量达到此水位时,bufferevent 将停止读取,直到输入缓冲区中的数据被读取,使得数据量低于此水位。注意用于限制一次读取的最大数据量。

(3.3)写入低水位:输出缓冲区中的数据量达到或低于此水位时,写入回调将被调用;

(3.4)写入高水位:不设置,直接写入即可,一般不用。

默认情况下,读取低水位和高水位都为 0,表示有数据就读取,且不会限定最大读取数量。写入的水位也是一样,表示可写即会全部写入。

 (4)事件回调函数中多了一个 what 参数,表示发生的事件:

// 读取错误
#define BEV_EVENT_READING	0x01	/**< error encountered while reading */

// 写入错误
#define BEV_EVENT_WRITING	0x02	/**< error encountered while writing */

// 到达文件结尾
#define BEV_EVENT_EOF		0x10	/**< eof file reached */

// 不可恢复的错误
#define BEV_EVENT_ERROR		0x20	/**< unrecoverable error encountered */

// 到达直到的超时时间
#define BEV_EVENT_TIMEOUT	0x40	/**< user-specified timeout reached */

// 连接操作完成
#define BEV_EVENT_CONNECTED	0x80	/**< connect operation finished. */

二、bufferevent的基本接口

bufferevent 的接口都位于头文件 <event2/bufferevent.h> 中。

1、创建 bufferevent 上下文接口

struct bufferevent *bufferevent_socket_new(
	struct event_base *base, evutil_socket_t fd, int options);

参数说明:

(1)base :libevent 上下文;
(2)fd :socket 描述符,bufferevent 的读写操作都基于此描述符;
(3)options :可选项,定义如下:

enum bufferevent_options {
	// 释放bufferevent时,关闭底层socket传输
	BEV_OPT_CLOSE_ON_FREE = (1<<0),

	// 线程安全,即在bufferevent中使用lock,此时callback也会被加锁
	BEV_OPT_THREADSAFE = (1<<1),

	// 在事件循环中延迟回调
	BEV_OPT_DEFER_CALLBACKS = (1<<2),

	// 不对回调函数加锁,即便设置了BEV_OPT_THREADSAFE也不加锁
    // 此选项需要与BEV_OPT_DEFER_CALLBACKS一起使用,未来可能会移除这一要求
	BEV_OPT_UNLOCK_CALLBACKS = (1<<3)
};

一般使用 BEV_OPT_CLOSE_ON_FREE 选项,表示在 在 bufferevent_free 时也会关闭 socket 。

2、开启/关闭 bufferevent 操作

// 开启
int bufferevent_enable(struct bufferevent *bufev, short event);
// 关闭
int bufferevent_disable(struct bufferevent *bufev, short event);

event :指定使能事件,一般就是读写事件 EV_READ | EV_WRITE;

3、设置 bufferevent 的回调函数

void bufferevent_setcb(struct bufferevent *bufev,
    bufferevent_data_cb readcb, bufferevent_data_cb writecb,
    bufferevent_event_cb eventcb, void *cbarg);

包括 read、write、event 三个回调函数。

4、读取 bufferevent 缓冲区

size_t bufferevent_read(struct bufferevent *bufev, void *data, size_t size); 

参数说明:

(1)data :存储数据的缓冲区;
(2)size :存储数据的缓冲区长度。

5、写入 bufferevent 缓冲区

int bufferevent_write(struct bufferevent *bufev, const void *data, size_t size); 

返回值:成功返回 0,失败返回 -1。

6、设置 bufferevent 超时时间

int bufferevent_set_timeouts(struct bufferevent *bufev,
    const struct timeval *timeout_read, const struct timeval *timeout_write); 

参数说明:

(1)timeout_read :读超时,NULL 表示不超时;
(2)timeout_write :写超时,NULL 表示不超时。
返回值:成功返回 0,失败返回 -1。

可以使用如下方法判断是否为读写超时:

if ((what & BEV_EVENT_TIMEOUT) && (what & BEV_EVENT_READING)) { /* 读超时 */ }

if ((what & BEV_EVENT_TIMEOUT) && (what & BEV_EVENT_WRITING)) { /* 写超时 */ }

7、释放bufferevent

void bufferevent_free(struct bufferevent *bufev);

bufferevent_free 函数内部有引用计数,它会尽快的关闭,即在判断没有引用后才会闭关,不会立即关闭。如果设置了 BEV_OPT_CLOSE_ON_FREE 标志,在 bufferevent_free 时也会将 socket 关闭。

另外,需要注意,如果用 bufferevent_write 发送后立马调用 bufferevent_free 可能会导致部分数据没有发出去 ,所以不要过早关闭 bufferevent。

8、连接服务端 socket

一般用于客户端程序。

int bufferevent_socket_connect(struct bufferevent *bufev, 
	const struct sockaddr *addr, int socklen);

在调用此函数时,bufferevent 中的 socket fd 必须设置为 nonblock 。正常情况下,若连接成功,会引起 BEV_EVENT_CONNECTED 的事件回调。

 

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

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

相关文章

Effective第三版 中英 | 避免使用终结方法和清理方法

文章目录 Effective第三版前言避免使用终结方法和清理方法&#xff08;Avoid finalizers and cleaners&#xff09;总结 Effective第三版 前言 大家好&#xff0c;这里是 Rocky 编程日记 &#xff0c;喜欢后端架构及中间件源码&#xff0c;目前正在阅读 effective-java 书籍。…

基于SpringBoot+vue的家乡特色推荐系统设计与实现

博主介绍&#xff1a; 大家好&#xff0c;我是一名在Java圈混迹十余年的程序员&#xff0c;精通Java编程语言&#xff0c;同时也熟练掌握微信小程序、Python和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架…

【C语言督学训练营 第十五天】常用的查找算法----顺序查找、二分查找、二叉排序树

文章目录 前言一、顺序查找1,思想2.代码实战 二、二分查找1.思想2.代码实战 三、二叉排序树1.建树思想2.删除节点思想3.代码实战 考研真题实战 前言 本篇博客会介绍到数据结构中常用到的查找算法&#xff0c;合理的使用查找算法可以让我们很轻松找到自己想要的答案。本小节必须…

Java异常面试题

什么是Java异常机制 Java异常机制是java语言为我们提供一种异常处理机制&#xff0c;在java语言中&#xff0c;异常本身是一个类&#xff0c;产生异常就是创建异常对象并抛出这个异常对象&#xff0c;程序发生异常情况之后程序会抛出封装了错误信息的异常对象&#xff0c;程序…

python-线性规划

线性规划&#xff1a;定义&#xff1a;1 线性规划&#xff08;Linear programming,简称LP&#xff09;&#xff0c;是运筹学中研究较早、发展较快、应用广泛、方法较成熟的一个重要分支&#xff0c;是辅助人们进行科学管理的一种数学方法&#xff0c;是研究线性约束条件下线性…

WPF 零基础入门笔记(2):控件模板+数据模版

文章目录 文章合集地址WPF控价模版解决重复嵌套标签书写的问题实战 WPF数据绑定解决界面和业务数据沟通的问题 WPF数据模版数据模板解决数据的样式设置&#xff08;以CellTemplate为例&#xff09;数据模板和控件模板的区别ItemTemplate 元素模板ItemTemplate是用于绝大部分控件…

CAT1模块 EC800M HTTP使用总结记录

分享记录一下 CAT1 模块EC800 HTTP 协议使用流程 ...... by 矜辰所致目录 前言一、基础说明1.1 CAT1 与 4G1.2 EC800M 模块1.3 HTTP 二、开始使用2.1 硬件设计部分2.2 模块上电流程2.3 PDP 上下文2.3.1 什么是 SGSN 和 GGSN &#xff1f; 三、 HTTP 流程3.1 客户端3.1.1 PDP 上…

UFS 13 - Logical Unit Management

UFS 13 - Logical Unit Management 1 Introduction2 Logical Unit features3 Logical Unit Configuration 基于UFS 3.1 标准文档阐述 UFS 1-UFS架构简介1 UFS 2 -UFS架构简介2 UFS 3 - UFS RPMB UFS 4 - UFS Boot UFS 5 - UFS UIC Layer: MIPI M-PHY UFS 6 - UAP – SCSI Comma…

机器人工程创新类课程补充说明-2023-2

仅供参考 之前一篇&#xff1a;机器人工程创新类课程补充说明-2023- 自主学习→自主研究→自主创新&#xff0c;这是一个循序渐进的过程&#xff0c;着急没用的&#xff0c;大部分学生&#xff0c;都卡在第一个阶段&#xff0c;自主学习的效率比较低&#xff0c;并且成果不突出…

【C++ 程序设计】第 6 章:多态与虚函数

目录 一、多态的基本概念 &#xff08;1&#xff09;多态 &#xff08;2&#xff09;虚函数 &#xff08;3&#xff09;通过基类指针实现多态 &#xff08;4&#xff09;通过基类引用实现多态 &#xff08;5&#xff09;* 多态的实现原理 二、多态实例 三、多态的使用 …

docker启动的jenkins拉取gitee项目构建并部署

docker启动的jenkins拉取gitee项目构建并部署 docker 拉取jenkins https://hub.docker.com/r可以search不同的jenkins版本docker pull jenkins/jenkins创建挂载目录 /home/jenkins_home加权限chmod 777 /home/jenkins_homedocker run -di --namejenkins -p 9999:8080 -v /hom…

【json-server】centos线上环境搭建全攻略

▒ 目录 ▒ &#x1f6eb; 问题描述环境 1️⃣ 安装json-server安装nvm安装node安装json-server 2️⃣ json-server 使用创建json数据踩坑&#xff1a;指定host关闭防火墙云后台修改安全组规则最终命令行 &#x1f6ec; 结论&#x1f4d6; 参考资料 &#x1f6eb; 问题 描述 开…

【虚拟机搭建-VMware设置固定IP】VMWare中CentOS如何设置固定IP【不成功手把手教学】

背景 在日常工作学习中&#xff08;比如博主在之前学习k8s过程中&#xff0c;windows本地搭建虚拟机&#xff0c;重启windows后&#xff09;虚拟机的IP会发生变化&#xff0c;所以该篇文章详细记录VMWare中CentOS如何设置固定IP 虚拟机安装 参考&#xff1a; https://rundr…

尚硅谷Docker2022版学习笔记(基础篇 上)

目录 一、Docker简介 1.1、是什么&#xff1f; 问题&#xff1a;为什么会有Docker出现&#xff1f; Docker理念 一句话 1.2、容器与虚拟机比较 传统虚拟机技术 容器虚拟机技术 容器虚拟机技术 1.3、去哪下&#xff1f; 二、Docker安装 2.1、前提说明 2.2、Docker的…

Rust语言从入门到入坑——(8)Rust泛型与特性

文章目录 0、引入1、泛型1.1、在函数中使用1.2、在结构体中使用 2、特性2.1 默认特性2.2 特性做参数2.3 特性做返回值2.4 有条件实现方法 3、总结 0、引入 泛型是一个编程语言不可或缺的机制。 C 语言中用"模板"来实现泛型&#xff0c;而 C 语言中没有泛型的机制&am…

MySQL数据库——备份与恢复

MySQL数据库——备份与恢复 一、数据备份的重要性二 、数据库备份的分类和备份策略1 数据库备份的分类2 数据库的备份策略3常见的备份方法 三、MySQL完全备份1 什么是完全备份2 完全备份的优缺点3 完全备份的方法 四、完全备份的操作1.物理冷备份与恢复2.mysqldump 备份与恢复3…

Arduino IDE 2.1.0 下安装ESP32

很久没玩Arduino了。新装了一台电脑&#xff0c;想重新捡起ESP32-WROOM-32开发板玩玩。官网上下了Arduino IDE 2.1.0&#xff0c;然后配置ESP32开发环境。 下载及安装Arduino IDE略过不谈。装完后还是老规矩&#xff0c;文件 -> 首选项&#xff0c;先把自定义板管理地址填入…

如何与西门子200 PLC建立连接

更多关于西门子S7-200PLC内容请查看&#xff1a;西门子200系列PLC学习课程大纲 与西门子200 PLC建立连接很简单&#xff0c;分为以下几步&#xff1a; 1.给S7-200PLC通电 按下图1-1所示连接PLC端口&#xff0c;然后给PLC供电&#xff0c;有直流24V和交流220V两种供电方式&am…

力扣----环形链表

&#x1f388;个人主页:&#x1f388; :✨✨✨初阶牛✨✨✨ &#x1f43b;推荐专栏1: &#x1f354;&#x1f35f;&#x1f32f;C语言初阶 &#x1f43b;推荐专栏2: &#x1f354;&#x1f35f;&#x1f32f;C语言进阶 &#x1f511;个人信条: &#x1f335;知行合一 金句分享:…

9i物联网浏览器(cef_114.2.110114.2.100支持H264视频)WinForm-CefSharp114(5735)视频版本体验

更新:2023.6.25 版本:Cef_114.2.110和114.2.100+chromium-114.0.5735.134的32位和64位 说明:支持图片,mp3,mp4(H264)多媒体 测试环境:windows server 2019 测试网址:www.html5test.com 1.包下载地址 1.1 https://www.nuget.org/packages/CefSharp.Common/ 1.2 https…