Libevent:6辅助函数以及类型

         在头文件<event2/util.h>中定义了许多有用的函数和类型来帮助实现可移植的程序。Libevent在内部使用这些类型和函数。

 

一:基本类型

evutil_socket_t

         除了Windows之外的大多数系统,socket就是一个整数,而且操作系统按照数值顺序对它们进行处理。而在Windows socket API中,socket是SOCKET类型,该类型是一个类似于指针的OS句柄,而且得到它们的顺序也是未定义的。Libevent定义evutil_socket_t类型为一个整数,该整数可以表示socket或者accept函数的返回值,并且可以在Windows上避免指针截断的风险。

#ifdef WIN32

#define evutil_socket_t  intptr_t

#else

#define evutil_socket_t  int

#endif

 

标准整数类型

         有时你的C系统可能落后于21世纪,因此并没有实现C99标准的stdint.h头文件。这种情况下,Libevent自己定义了stdint.h中的,确定位宽度(bit-width-specific)的整数。

Type

Width

Signed

Maximum

Minimum

ev_uint64_t

64

No

EV_UINT64_MAX

0

ev_int64_t

64

Yes

EV_INT64_MAX

EV_INT64_MIN

ev_uint32_t

32

No

EV_UINT32_MAX

0

ev_int32_t

32

Yes

EV_INT32_MAX

EV_INT32_MIN

ev_uint16_t

16

No

EV_UINT16_MAX

0

ev_int16_t

16

Yes

EV_INT16_MAX

EV_INT16_MIN

ev_uint8_t

8

No

EV_UINT8_MAX

0

ev_int8_t

8

Yes

EV_INT8_MAX

EV_INT8_MIN

         类似于C99标准,这些类型都有确定的位宽度。

 

各种兼容性类型 

         在那些具有ssize_t的类型的平台上,ev_ssize_t就被定义为ssize_t(signedsize_t),对于没有这种类型的平台,ev_ssize_t会被定义为合理的默认值。ev_ssize_t类型可能的最大值是EV_SSIZE_MAX;最小值为EV_SSIZE_MIN。(在平台没有定义SIZE_MAX的时候,size_t类型的最大可能值是EV_SIZE_MAX)

         ev_off_t类型用来表示一个文件或一段内存中的偏移值。在那些具有合理的off_t类型定义的系统上,ev_off_t被定义为off_t,在Windows上被定义为ev_int4_t。

 

         某些socket API的实现提供了长度类型socklen_t,而某些却没有提供。在那些提供该类型的平台上,ev_uintptr_t就被定义为socklen_t,而那些没有定义的平台,ev_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) /* ... */

         evutil_timerclear将一个timeval清空是将其值置为0。evutil_timerisset检查timeval,如果timeval的值为非0,则该宏返回true,否则返回false。
 

#define evutil_timercmp(tvp, uvp, cmp)

         evutil_timercmp比较两个timeval,并且如果它们之间的相对关系符合关系操作符cmp定义的比较关系的话,该宏返回true。比如:evutil_timercmp(t1, t2, <=)意味着“Is t1 <= t2。注意,不像某些操作系统,Libevent的timercmp支持所有的C关系操作符(即是<, >, ==, !=, <= 和 >=)。
 

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

         evutil_gettimeofday函数设置tv为当前时间,参数tz无用。
 

struct timeval  tv1, tv2, tv3;

 

/* Settv1 = 5.5 seconds */

tv1.tv_sec= 5;  tv1.tv_usec = 500*1000;

 

/*Set tv2 = now */

evutil_gettimeofday(&tv2, NULL);

 

/* Settv3 = 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 thepresent.");

if(evutil_timercmp(&tv1, &tv2, <))  /* == "If tv1 < tv2" */

   puts("It is no longer the past.");


三:Socket API兼容性

         由于历史原因,Windows从未真正的以良好的兼容性实现伯克利Socket API。下面的函数可以规避这种情况:

int  evutil_closesocket(evutil_socket_t  s);

#define EVUTIL_CLOSESOCKET(s)  evutil_closesocket(s)

         这些函数用来关闭socket,在Unix上,它就是close函数的别名。在Windows上,它调用closesocket。(在Windows上,不能在socket上调用close,也没有其他系统定义closesocket函数。)

 

#define EVUTIL_SOCKET_ERROR()

#define EVUTIL_SET_SOCKET_ERROR(errcode)

#define evutil_socket_geterror(sock)

#define evutil_socket_error_to_string(errcode)

         这些宏访问并操作socket错误码。EVUTIL_SOCKET_ERROR返回本线程最近一次的socket操作的全局错误码。evutil_socket_geterror针对某个特定socket做同样的事。(在类Unix系统上,全局错误码就是errno)。EVUTIL_SET_SOCKET_ERROR改变当前的socket错误码(类似于在Unix上设置errno),evutil_socket_error_to_string返回给定错误码的字符串描述。(类似于Unix上的strerror)

         (之所以需要这些函数,是因为Windows没有为socket函数的错误定义errno,而是使用函数WSAGetLastError)

         注意:在windows上,套接字错误码与标准C错误码errno是不同的。

 

int  evutil_make_socket_nonblocking(evutil_socket_t sock);

         对套接字IO的非阻塞设置也不能移植到Windows中。evutil_make_socket_nonblocking函数将一个新的socket描述符(由socket或accept返回),设置为非阻塞的。(在Unix上,置为O_NONBLOCK,在Windows上置为FIONBIO。)

 

int  evutil_make_listen_socket_reuseable(evutil_socket_t  sock);

         该函数使得关闭一个监听套接字后,它使用的地址可以立即被另一个套接字使用。(在Unix上,是设置SO_REUSEADDR,而在Windows上,该标志却有其他意义。)

 

int  evutil_make_socket_closeonexec(evutil_socket_t sock);

         该函数使得操作系统在调用exec之后,会关闭该socket描述符。在Unix上是设置FD_CLOEXEC 标志,而在Windows上什么也不做。

 

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

         该函数类似于Unix上的socketpair函数:它在两个socket上创建一个相互连接的管道,而且可以使用普通的socket io函数。该函数将这两个socket保存在sv[0]和sv[1]中,该函数返回0表示成功,-1表示失败。

         在Windows上,该函数仅支持AF_INET协议族,SOCK_STREAM类型以及协议0. 注意:在某些Windows主机上,防火墙软件明确阻止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替代函数与标准的snprintf和vsnprintf接口类似。它们返回写入到buffer缓冲区的字节数,不包括末尾的NULL字节。(这种行为符合C99标准,但与Windows上的_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);

         这些函数类似于标准的inet_ntop和inet_pton函数,根据RFC3493中的规定,解析和格式化IPv4和IPv6地址。格式化一个IPv4地址,调用evutil_inet_ntop,af置为AF_INET,src指向in_addr结构,dst指向一个len长度的字符缓冲区。而对于IPv6地址,则af置为AF_INET6,src指向in6_addr结构。

         要解析一个IPv4或一个IPv6地址,调用evutil_inet_pton函数,af置为AF_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]:port (as in "[ffff::]:80")

·       ipv6 (as in "ffff::")

·       [ipv6] (as in "[ffff::]")

·       ipv4:port (as in "1.2.3.4:80")

·       ipv4 (as in "1.2.3.4")

         如果没有给定port,则在sockaddr的结果中,port被置为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_INET和AF_INET6地址族,而对于其他地址则是未定义的。它保证给出一个所有地址的总排序,但是不同的Libevent版本可能会有不同的排序结果。

         如果include_port置为false,那么如果两个sockaddrs仅在port不同的情况下,该函数将他们视为相同的。否则,如果include_port置为true,则会视为不同的。

 

七:结构体可移植函数

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

         类似于标准的offsetof宏,该宏返回field域在type中的偏移字节。

 

八:安全的随机数生成器

         很多应用都需要一个难以预测的随机数源来保证它们的安全性。

void  evutil_secure_rng_get_bytes(void * buf,  size_t  n);

         该接口将n个字节的随机数据填充到buf中。如果平台提供了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()函数。它会seed RNG(随机数生成器)(如果还没有seed过),并且在成功时返回0。如果返回-1,表明Libevent无法在系统上找到好的熵源,而且在没有自己初始化时,不能安全的使用RNG。

         如果程序运行在可能会放弃权限的环境中(比如说,通过执行chroot()),在放弃权限前应该调用evutil_secure_rng_init()。

         可以调用evutil_secure_rng_add_bytes()向熵池加入更多随机字节,但通常不需要这么做。

 

 

http://www.wangafu.net/~nickm/libevent-book/Ref5_evutil.html

转载于:https://www.cnblogs.com/gqtcgq/p/7247257.html

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

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

相关文章

enable_if

typedef struct {int a; }TestType;int main() {enable_if <1, TestType>::type test1; //正确test1.a 100;enable_if <is_integral<int>::value, TestType>::type test2; //正确test1.a 100;enable_if <0, TestType>::type test3; //错…

一. NSIS介绍

概述 最近需要写一个安装程序&#xff0c;比对了一下现有的安装工具&#xff0c;最后选定了NSIS&#xff0c;最主要的原因一是开源、二是灵活。 下面把我的要求简单列举下&#xff1a; 1、需要检查系统环境是否满足要求 2、需要界面友好的安装过程 3、需要一些自定义界面&…

HDU-1008

水题 Description The highest building in our city has only one elevator. A request list is made up with N positive numbers. The numbers denote at which floors the elevator will stop, in specified order. It costs 6 seconds to move the elevator up one floor,…

二. 简单的NSIS安装包

新建脚本&#xff1a;向导 我们先从一个简单的NSIS安装包开始吧&#xff0c;就像前面&#xff08;NSIS介绍&#xff09;所说&#xff0c;我们虽然看过用户手册&#xff0c;可要写安装脚本无从下手&#xff0c;那我们的编辑工具HM NIS Edit就派上用场了。 打开HM NIS Edit&…

Ubuntu 14.04 LAMP搭建(Apache 2.47+MySQL 5.5+PHP5.5)

Ubuntu 14.04 LAMP搭建(Apache 2.47MySQL 5.5PHP5.5) 原文:Ubuntu LAMP搭建 为了数据库课程设计&#xff0c;只好自己搭一个数据库系统&#xff0c;采用LAMP方式。 一、安装 1.安装Apache sudo apt-get install apache2 Apache在安装期间会新建一个目录&#xff1a;/var/www&am…

C++变量未初始的后果

#include <iostream> using namespace std;void dummy(int &a) {}int main() {int i 2;while (i--){int a;dummy(a);if (i 1){a 100;}cout << a << endl;cout << &a << endl;}getchar(); } 上面程序&#xff0c;如果变量a没有初始化…

NSIS 查找文件是否存在,并设置安装路径

Var GIT Function .onInit!insertmacro MUI_LANGDLL_DISPLAYStrCpy $GIT "false"MessageBox MB_OK $9IfFileExists "C:\Program Files\Git\git-cmd.exe" 0 4MessageBox MB_OK "Git已安装"StrCpy $INSTDIR "C:\Program Files\Git"StrCp…

国内主流云主机比较

随着国内云主机技术日趋成熟&#xff0c;云主机的优势越来越明显&#xff0c;用户对云主机的态度也由观望变为乐于尝试。国内各大云主机商也放低姿态&#xff0c;产品设置和定价上逐渐迎合个人用户和中小型企业用户的需求。 云主机的诸多好处&#xff1a;集群计算、处理能力可弹…

30 个很棒的 PHP 开源 CMS 内容管理系统

本文汇集了30个优秀的开源CMS建站系统&#xff0c;采用PHP开发。以下列表不分先后顺序。 1. AdaptCMS AdaptCMS Lite 是一个开源的CMS系统&#xff0c;主要特点是易用&#xff0c;而且可以轻松和其他系统接驳&#xff0c;提供简单的扩展定制途径&#xff0c;一个简单而且功能强…

Alwayson常用脚本

1、修改实例下所有节点的数据同步模式&#xff0c;在master数据库下运行 --查找所有异步提交的辅助节点&#xff0c;修改为同步提交模式 -- SYNCHRONOUS_COMMIT 同步提交模式 -- ASYNCHRONOUS_COMMIT 异步提交模式 select ALTER AVAILABILITY GROUP [a.name] MODIFY REPLICA…

Package ‘*****‘ has no installation candidate

如果在apt源中未找到软件&#xff0c;去ubuntu的软件包搜索页面中去搜索该软件 Ubuntu – Ubuntu Packages Search https://packages.ubuntu.com/ 前面红字找到对应ubuntu版本的软件版本名称&#xff0c;后面中括号为仓库名称&#xff0c;然后写入到/etc/apt/sources.list中 …

Oracle 客户端连接服务器[转]

很多朋友在开发项目中并不是每个人用一个数据库&#xff0c;而是有单独的一台主机作为开发的数据库服务器&#xff0c;这样&#xff0c;就需要我们的开发人员去连接它。 首先是进入oracle的 Net Mananger&#xff1b; 接下来就是进行简单的设置了。。 &am…

p3d gauge 尺寸问题

1. 在panel.cfg中&#xff0c;每个window可以有多个gauge&#xff0c;window是gauge的容器 2. 在panel.cfg中&#xff0c;background_color为window背景色&#xff0c;如果设置为0&#xff0c;0&#xff0c;0&#xff0c;未被gauge覆盖的 部分会透明 3. 在panel.cfg中&#…

BZOJ2199 [Usaco2011 Jan]奶牛议会

首先建立一个2-SAT的裸模型&#xff0c;然后发现。。。tarjan没法判断?的情况 于是暴力对每一个议案check一下&#xff0c;直接dfs即可 1 /**************************************************************2 Problem: 21993 User: rausen4 Language: C5 Resu…

ubuntu 远程桌面

1. apt-get install xrdp 2. apt-get install dconf-editor 3. 启动 dconf-editor&#xff0c;org->gnome->desktop->remote-access&#xff0c;取消 “requlre-encryption”的勾选 4. 打开系统左上角的"Search your computer"&#xff0c;然后找到“Des…

记录:Android中StackOverflow的问题

最近新作的项目上线&#xff0c;出现了一个让人抓狂的问题。在此记录一下&#xff01; 现在的项目中&#xff0c;制作了一个界面非常复杂。整个结构是最外层一个Layout&#xff0c;封装了Menu键吊起的菜单&#xff0c;整个内容使用一个FrameLayout装载&#xff0c;这个layout中…

OpenDrive记录

1. junction里面只有一半的链接关系&#xff0c;也就是只有road进入junction的链接关系&#xff0c;没有junction出 去的链接关系。 拿路径搜索方法举例&#xff0c; 1&#xff09; 如果当前road的前方是junction&#xff0c;即当前road的predecessor或者successor是juncti…

JavaWeb高性能开发(一)

今日要闻: 淘宝删差评产业链 在你给出“差评”“中评”后不久&#xff0c;有人会偷偷登录你的淘宝账户&#xff0c;把你之前给过的评价删除或改成“好评”。而这种人就是“职业修改差评师” 案发前&#xff0c;李骏杰在杭州市滨江区一家科技公司上班。5 人当中&#xff0c;他主…