libevent学习——辅助类型和函数

辅助类型和函数

文章目录

    • 基本类型
      • `evutil_socket_t`
      • 标准整数类型
      • 各种兼容性类型
    • 定时器可移植函数
    • 套接字 API 兼容性
    • 可移植的字符串操作函数
    • 区域无关的字符串操作函数
    • IPv6辅助和兼容性函数
    • 结构体可移植性函数
    • 安全随机数发生器

<event2/util.h>定义了很多在实现可移植应用时有用的函数, libevent 内部也使用这些类型和函数。

基本类型

evutil_socket_t

在除 Windows 之外的大多数地方,套接字是个整数,操作系统按照数值次序进行处理。然而,使用 Windows 套接字 API 时,socket 具有类型 SOCKET,它实际上是个类似指针的句柄,收到这个句柄的次序是未定义的。在 Windows 中,libevent 定义 evutil_socket_t 类型为整型指针,可以处理 socket()或者 accept()的输出,而没有指针截断的风险。

#ifdef WIN32
#define evutil_socket_t intptr_t
#else
#define evutil_socket_t int
#endif

标准整数类型

落后于21世纪的 C 系统常常没有实现 C99标准规定的 stdint.h 头文件。考虑到这种情况,libevent 定义了来自于 stdint.h 的、位宽度确定(bit-width-specific)的整数类型:

TypeWidthSignedMaximumMinimum
ev_uint64_t64NoEV_UINT64_MAX0
ev_int64_t64YesEV_INT64_MAXEV_INT64_MIN
ev_uint32_t32NoEV_UINT32_MAX0
ev_int32_t32YesEV_INT32_MAXEV_INT32_MIN
ev_uint16_t16NoEV_UINT16_MAX0
ev_int16_t16YesEV_INT16_MAXEV_INT16_MIN
ev_uint8_t8NoEV_UINT8_MAX0
ev_int8_t8YesEV_INT8_MAXEV_INT8_MIN
跟 C99标准一样,这些类型都有明确的位宽度。

各种兼容性类型

在有 ssize_t(有符号的 size_t)类型的平台上,ev_ssize_t 定义为 ssize_t;而在没有的平台上,则定义为某合理的默认类型。ev_ssize_t 类型的最大可能值是 EV_SSIZE_MAX;最小可能值是 EV_SSIZE_MIN。(在平台没有定义 SIZE_MAX 的时候,size_t 类型的最大可能值是 EV_SIZE_MAX)
ev_off_t 用于代表文件或者内存块中的偏移量。在有合理 off_t 类型定义的平台,它被定义为 off_t;在 Windows 上则定义为 ev_int64_t
某些套接字 API 定义了 socklen_t 长度类型,有些则没有定义。在有这个类型定义的平台中,ev_socklen_t 定义为 socklen_t,在没有的平台上则定义为合理的默认类型。
ev_intptr_t 是一个有符号整数类型,足够容纳指针类型而不会产生截断;而 ev_uintptr_t 则是相应的无符号类型。

定时器可移植函数

不是每个平台都定义了标准 timeval 操作函数,所以 libevent 也提供了自己的实现。

#define evutil_timeradd(tvp, uvp, vvp) /* ... */
#define evutil_timersub(tvp, uvp, vvp) /* ... */

这些宏分别对前两个参数进行加或者减运算,将结果存放到第三个参数中。

#define evutil_timerclear(tvp) /* ... */
#define evutil_timerisset(tvp) /* ... */

清除 timeval 会将其值设置为0。evutil_timerisset 宏检查 timeval 是否已经设置,如果已经设置为非零值,返回 ture,否则返回 false。

#define evutil_timercmp(tvp, uvp, cmp)

evutil_timercmp 宏比较两个 timeval,如果其关系满足 cmp 关系运算符,返回 true。比如说,evutil_timercmp(t1,t2,<=)的意思是“是否 t1<=t2?”。注意:与某些操作系统版本不同的是,libevent 的时间比较支持所有 C 关系运算符(也就是<、>、==、!=、<=>=)。

int evutil_gettimeofday(struct timeval *tv, struct timezone *tz);

evutil_gettimeofdy()函数设置 tv 为当前时间,tz 参数未使用。

例子:

struct timeval tv1, tv2, tv3;/* Set tv1 = 5.5 seconds */
tv1.tv_sec = 5; tv1.tv_usec = 500*1000;/* Set tv2 = now */
evutil_gettimeofday(&tv2, NULL);/* Set tv3 = 5.5 seconds in the future */
evutil_timeradd(&tv1, &tv2, &tv3);/* all 3 should print true */
if (evutil_timercmp(&tv1, &tv1, ==))  /* == "If tv1 == tv1" */puts("5.5 sec == 5.5 sec");
if (evutil_timercmp(&tv3, &tv2, >=))  /* == "If tv3 >= tv2" */puts("The future is after the present.");
if (evutil_timercmp(&tv1, &tv2, <))   /* == "If tv1 < tv2" */puts("It is no longer the past.");

套接字 API 兼容性

本节由于历史原因而存在: Windows 从来没有以良好兼容的方式实现 Berkeley 套接字 API。

int evutil_closesocket(evutil_socket_t s);#define EVUTIL_CLOSESOCKET(s) evutil_closesocket(s)

这个接口用于关闭套接字。在 Unix 中,它是 close()的别名;在 Windows 中,它调用closesocket() 。(在Windows中不能将 close() 用于套接字, 也 没有其他系统定义了closesocket())

#define EVUTIL_SOCKET_ERROR()
#define EVUTIL_SET_SOCKET_ERROR(errcode)
#define evutil_socket_geterror(sock)
#define evutil_socket_error_to_string(errcode)

这些宏访问和操作套接字错误代码。EVUTIL_SOCKET_ERROR()返回本线程最后一次套接字操作的全局错误号,evutil_socket_geterror()则返回某特定套接字的错误号。(在类 Unix 系统中都是 errno)EVUTIL_SET_SOCKET_ERROR()修改当前套接字错误号(与设置 Unix 中的 errno 类似),evutil_socket_error_to_string()返回代表某给定套接字错误号的字符串(与 Unix 中的 strerror()类似)。
(因为对于来自套接字函数的错误, Windows 不使用 errno,而是使用 WSAGetLastError(),所以需要这些函数。)
注意:Windows 套接字错误与从 errno 看到的标准 C 错误是不同的。

int evutil_make_socket_nonblocking(evutil_socket_t sock);

用 于 对 套 接 字 进 行 非 阻 塞 IO 的 调 用 也 不 能 移 植 到 Windows 中 。evutil_make_socket_nonblocking()函数要求一个套接字(来自 socket()或者 accept())作为参数,将其设置为非阻塞的。 (设置 Unix 中的 O_NONBLOCK 标志和 Windows 中的 FIONBIO标志)

int evutil_make_listen_socket_reuseable(evutil_socket_t sock);

这个函数确保关闭监听套接字后,它使用的地址可以立即被另一个套接字使用 。(在 Unix中它设置 SO_REUSEADDR 标志,在 Windows 中则不做任何操作。不能在 Windows 中使用 SO_REUSEADDR 标志:它有另外不同的含义(译者注:多个套接字绑定到相同地址))

int evutil_make_socket_closeonexec(evutil_socket_t sock);

这个函数告诉操作系统,如果调用了 exec(),应该关闭指定的套接字。在 Unix 中函数设置FD_CLOEXEC 标志,在 Windows 上则没有操作。

int evutil_socketpair(int family, int type, int protocol,evutil_socket_t sv[2]);

这个函数的行为跟 Unix 的 socketpair()调用相同:创建两个相互连接起来的套接字,可对其使用普通套接字 IO 调用。函数将两个套接字存储在 sv[0]sv[1]中,成功时返回0,失败时返回-1。
在 Windows 中,这个函数仅能支持 AF_INET 协议族、SOCK_STREAM类型和0协议的套接字。注意:在防火墙软件明确阻止127.0.0.1,禁止主机与自身通话的情况下,函数可能失败。

可移植的字符串操作函数

ev_int64_t evutil_strtoll(const char *s, char **endptr, int base);

这个函数与 strtol 行为相同,只是用于64位整数。在某些平台上,仅支持十进制。

int evutil_snprintf(char *buf, size_t buflen, const char *format, ...);
int evutil_vsnprintf(char *buf, size_t buflen, const char *format, va_list ap);

这些 snprintf 替代函数的行为与标准 snprintfvsnprintf 接口相同。函数返回在缓冲区足够长的情况下将写入的字节数,不包括结尾的 NULL 字节。(这个行为遵循 C99的 snprintf()标准,但与 Windows 的_snprintf()相反:如果字符串无法放入缓冲区,_snprintf()会返回负数)

区域无关的字符串操作函数

实现基于 ASCII 的协议时,可能想要根据字符类型的 ASCII 记号来操作字符串,而不管当前的区域设置。libevent 为此提供了一些函数:

int evutil_ascii_strcasecmp(const char *str1, const char *str2);
int evutil_ascii_strncasecmp(const char *str1, const char *str2, size_t n);

这些函数与 strcasecmp()strncasecmp()的行为类似,只是它们总是使用 ASCII 字符集进行比较,而不管当前的区域设置。

IPv6辅助和兼容性函数

const char *evutil_inet_ntop(int af, const void *src, char *dst, size_t len);
int evutil_inet_pton(int af, const char *src, void *dst);

这些函数根据 RFC 3493的规定解析和格式化 IPv4与 IPv6地址,与标准 inet_ntop()inet_pton()函数行为相同。要格式化 IPv4地址,调用 evutil_inet_ntop(),设置 afAF_INET,src 指向 in_addr 结构体,dst 指向大小为 len 的字符缓冲区。对于 IPv6地址,af 应该是AF_INET6,src 则指向 in6_addr 结构体。要解析 IP 地址,调用 evutil_inet_pton(),设置afAF_INET 或者 AF_INET6,src 指向要解析的字符串, dst 指向一个 in_addr 或者in_addr6结构体。
失败时 evutil_inet_ntop()返回 NULL,成功时返回到 dst 的指针。成功时 evutil_inet_pton()返回0,失败时返回-1。

int evutil_parse_sockaddr_port(const char *str, struct sockaddr *out,int *outlen);

这个接口解析来自 str 的地址,将结果写入到 out 中。outlen 参数应该指向一个表示 out 中可用字节数的整数;函数返回时这个整数将表示实际使用了的字节数。成功时函数返回0,失败时返回-1。函数识别下列地址格式:

  • [ipv6]:端口号(如[ffff::]:80)
  • ipv6(如 ffff:😃
  • [ipv6](如[ffff::])
  • ipv4:端口号(如1.2.3.4:80)
  • ipv4(如1.2.3.4)
    如果没有给出端口号,结果中的端口号将被设置为0。
int evutil_sockaddr_cmp(const struct sockaddr *sa1,const struct sockaddr *sa2, int include_port);

evutil_sockaddr_cmp()函数比较两个地址,如果 sa1在 sa2前面,返回负数;如果二者相等,则返回0;如果 sa2在 sa1前面,则返回正数。函数可用于 AF_INETAF_INET6地址;对于其他地址,返回值未定义。函数确保考虑地址的完整次序,但是不同版本中的次序可能不同。
如果 include_port 参数为 false,而两个地址只有端口号不同,则它们被认为是相等的。否则,具有不同端口号的地址被认为是不等的。

结构体可移植性函数

#define evutil_offsetof(type, field) /* ... */

跟标准 offsetof 宏一样,这个宏返回从 type 类型开始处到 field 字段的字节数。

安全随机数发生器

很多应用(包括 evdns)为了安全考虑需要很难预测的随机数。

void evutil_secure_rng_get_bytes(void *buf, size_t n);

这个函数用随机数据填充 buf 处的 n 个字节。
如果所在平台提供了 arc4random(),libevent 会使用这个函数。否则,libevent 会使用自己的 arc4random() 实现 , 种子则来自操作系统的熵池( entropy pool )( Windows中的CryptGenRandom,其他平台中的/dev/urandom)

int evutil_secure_rng_init(void);
void evutil_secure_rng_add_bytes(const char *dat, size_t datlen);

不需要手动初始化安全随机数发生器,但是如果要确认已经成功初始化,可以调用evutil_secure_rng_init()。函数会播种 RNG(如果没有播种过),并在成功时返回0。函数返回-1则表示 libevent 无法在操作系统中找到合适的熵源(source of entropy),如果不自己初始化 RNG,就无法安全使用 RNG 了。
如果程序运行在可能会放弃权限的环境中(比如说,通过执行 chroot()),在放弃权限前应该调用 evutil_secure_rng_init()
可以调用 evutil_secure_rng_add_bytes()向熵池加入更多随机字节,但通常不需要这么做。

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

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

相关文章

Learn Prompt- Midjourney 图片生成:Image Prompts

Prompt 自动生成 前不久&#xff0c;Midjourney 宣布支持图片转 prompt 功能。 原始图片​ blueprint holographic design of futuristic Midlibrary --v 5Prompt 生成​ 直接输入 /describe 指令通过弹出窗口上传图像并发送&#xff0c;Midjourney 会根据该图像生成四种可…

完成“重大项目”引进签约,美创科技正式落户中国(南京)软件谷

近日&#xff0c;美创科技正式入驻中国&#xff08;南京&#xff09;软件谷&#xff0c;并受邀出席中国南京“金洽会"之“雨花台区数字经济创新发展大会”。美创科技副总裁罗亮亮作为代表&#xff0c;在活动现场完成“重大项目”引进签约。 作为国家重要的软件产业与信息服…

关于ubuntu设置sh文件开机自启动python3和sudo python3问题

关于ubuntu设置sh文件开机自启动python3和sudo python3问题 说明系统为 ubuntu22.04python是python3.10.12ros系统为ros2 humble 背景解决方法补充 说明 系统为 ubuntu22.04 python是python3.10.12 ros系统为ros2 humble 背景 将一个py文件设置为开机自启动&#xff0c;服…

css-边框原理教程

1. CSS中边框原理 他不是一条直线&#xff0c;根据盒子原理&#xff0c;当边框宽度大于元素的长和宽时&#xff0c;呈现一个梯形和三角形的形状&#xff0c;用如下的代码来实地理解一下边框画法实现的原理 注&#xff1a;学习网址&#xff1a; CSS画几种图形的方法_css画图_老…

贪心算法总结归类(图文解析)

贪心算法实际上并没有什么套路可言&#xff0c;贪心的关键就在于它的思想&#xff1a; 如何求出局部最优解&#xff0c;通过局部最优解从而推导出全局最优解 常见的贪心算法题目 455. 分发饼干 这题的解法很符合“贪心”二字 如果使用暴力的解法&#xff0c;那么本题是通过…

Windows--Python永久换下载源

1.新建pip文件夹&#xff0c;注意路径 2.在上述文件中&#xff0c;新建文件pip.ini 3.pip.ini记事本打开&#xff0c;输入内容&#xff0c;保存完事。 [global] index-url https://pypi.douban.com/simple

【记录文】Android自定义Dialog实现圆角对话框

圆角的dialog还是蛮常用的&#xff0c;demo中正好用上了 自定义Dialog&#xff0c;代码中可以设置指定大小与位置 /*** author : jiangxue* date : 2023/9/25 13:21* description :圆角的矩形*/internal class RoundCornerView(context: Context,view: Int, StyleRes theme…

开机自启动Linux and windows

1、背景 服务器由于更新等原因重启&#xff0c;部署到该服务上的响应的应用需要自启动 2、Linux 2.1 方式一 编写启动应用的sh脚本授权该脚本权限 chmod 777 xxx.sh 修改rc.loacl 位置&#xff1a;/etc/rc.local 脚本&#xff1a;sh /home/xxxx.sh & 授权rc.local …

Elasticsearch—(MacOs)

1⃣️环境准备 准备 Java 环境&#xff1a;终端输入 java -version 命令来确认版本是否符合 Elasticsearch 要求下载并解压 Elasticsearch&#xff1a;前往&#xff08;https://www.elastic.co/downloads/elasticsearch&#xff09;选择适合你的 Mac 系统的 Elasticsearch 版本…

python使用蓝牙库选择

蓝牙库选择 pybluez 项目地址&#xff1a;https://github.com/pybluez/pybluez 文档地址&#xff1a;https://pybluez.readthedocs.io/en/latest/index.html 蓝牙支持&#xff1a;经典蓝牙 / BLE蓝牙【仅Linux】 平台支持&#xff1a; LinuxRaspberry PimacOSWindows✔️✔️…

分享40个Python源代码总有一个是你想要的

分享40个Python源代码总有一个是你想要的 源码下载链接&#xff1a;https://pan.baidu.com/s/1PNR3_RqVWLPzSBUVAo2rnA?pwd8888 提取码&#xff1a;8888 下面是文件的名字。 dailyfresh-天天生鲜 Django-Quick-Start freenom-自动续期域名的脚本 Full Stack Python简体中…

ADC数模转化器

简介 • ADC &#xff08; Analog-Digital Converter &#xff09;模拟 - 数字转换器 • ADC 可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量&#xff0c;建立模拟电路到数字电路的桥梁 • 12 位逐次逼近型 ADC &#xff0c; 1us 转换时间 &#xff08;12位:分辨率…

02 MIT线性代数-矩阵消元 Elimination with matrices

一, 消元法 Method of Elimination 消元法是计算机软件求解线形方程组所用的最常见的方法。任何情况下&#xff0c;只要是矩阵A可逆&#xff0c;均可以通过消元法求得Axb的解 eg: 我们将矩阵左上角的1称之为“主元一”&#xff08;the first pivot&#xff09;&#xff0c;第…

MySQL库表操作

开始之前分享一个数据库远程连接工具&#xff1a; Navicat Premium 15 可以远程连接数据库&#xff0c;并且查看表的结构等&#xff0c;非常好用。 SQL语句基础 SQL&#xff1a;结构化查询语言(Structured Query Language)&#xff0c;在关系型数据库上执行数据操作、数据检索…

景联文数据标注:AI大模型产生幻觉该如何应对?

大语言模型在诸多下游任务中展现出令人瞩目的能力&#xff0c;然而在运用过程中仍然存在一些问题。幻觉现象是目前阻碍大模型成功应用的关键问题之一。 什么是大模型幻觉问题&#xff1f; 大模型幻觉问题是指一些人工智能模型在面对某些输入时&#xff0c;会生成不准确、不完整…

算法 寻找第k大数-(快速排序+双指针)

牛客网: BM47 题目: 数组第K大的数 思路: 见最小的k个数&#xff0c;将num[right] > pivot的元素左调&#xff0c;最终返回num[k-1] 代码: // gopackage main // import "fmt"/*** 代码中的类名、方法名、参数名已经指定&#xff0c;请勿修改&#xff0c;直接…

Visual Studio Cpp CLR C# 替换

1、首先将文件中所有都替换 你需要的名字 替换为整个解决方案 2、新建工程取名 Laserbeam_upper 3、把原工程下的cpp放进来&#xff0c;并改名Laserbeam_upper 4、在这里逐步添加 属性表配置opencv 5、cpp需要修改的两个地方 6、CLR新建和添加 选类库新建、然后直接粘贴进来…

leetcodetop100(28) 两两交换链表中的节点

两两交换链表中的节点 给你一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题&#xff08;即&#xff0c;只能进行节点交换&#xff09; package TOP21_30;import Util.ListNode;//两两交换链表…

阿里云七代云服务器实例、倚天云服务器及通用算力型和经济型实例规格介绍

在目前阿里云的云服务器产品中&#xff0c;既有五代六代实例规格&#xff0c;也有七代和八代倚天云服务器&#xff0c;同时还有通用算力型及经济型这些刚推出不久的新品云服务器实例&#xff0c;其中第五代实例规格目前不在是主推的实例规格了&#xff0c;现在主售的实例规格是…

php实现分页功能跳转和ajax方式实现

实现效果 准备工作 创建数据表和导入测试数据 CREATE TABLE users ( id int(10) unsigned NOT NULL AUTO_INCREMENT, username varchar(30) DEFAULT NULL COMMENT 账号, email varchar(30) DEFAULT NULL COMMENT 密码, PRIMARY KEY (id) ) ENGINEMyISAM AUTO_INCREM…