博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
socket属性设置与初始化操作
阅读量:6293 次
发布时间:2019-06-22

本文共 4920 字,大约阅读时间需要 16 分钟。

libevent是一个事件触发的网络库,适用于windows、linux、bsd等多种平台,内部使用select、epoll、kqueue等系统调用管理事件机制。著名分布式缓存软件memcached也是libevent based,而且libevent在使用上可以做到跨平台,而且根据libevent官方网站上公布的数据统计,似乎也有着非凡的性能。

event_base

在使用Libevent之前,需要初始化一个event_base结构。每一个event_base结构提包含了events集合并选择事件类型。如果选择locking方式,会保证交互是线程安全的。如果需要使用多线程模型的话,需要为每一个线程建立一个event_base。

method种类

select、poll、epoll、kqueue、devpoll、evport、win32

接口

#include 
struct event_base *event_base_new(void);

`event_base_new`会根据默认的配置参数返回一个`event_base`结构体,失败返回`NULL`。

配置方法

struct event_config *event_config_new(void);struct event_base *event_base_new_with_config(const struct event_config *cfg);void event_config_free(struct event_config *cfg);

`event_config_new`可以返回一个配置信息的结构体,通过修改结构提内容,并作为参数传递给`event_base_new_with_config`可以生成目标`event_base`,而`event_config_free`使用来是放掉config配置信息的。

那么event_config到底是什么样的?

struct event_config {    TAILQ_HEAD(event_configq, event_config_entry) entries;    int n_cpus_hint; //cpu数量    enum event_method_feature require_features;//指定IO复用的条件    enum event_base_config_flag flags;};

可以使用`event_config_set_num_cpus_hint(struct event_config *cfg, int cpus)`设置`n_cpu_hint`,但是目前只支持使用IOCP的情况下。

`require_features`的具体结构如下:

//event.h文件enum event_method_feature {    //支持边沿触发    EV_FEATURE_ET = 0x01,    //添加、删除、或者确定哪个事件激活这些动作的时间复杂度都为O(1)    //select、poll是不能满足这个特征的.epoll则满足    EV_FEATURE_O1 = 0x02,    //支持任意的文件描述符,而不能仅仅支持套接字    EV_FEATURE_FDS = 0x04};

通过`event_config_require_features(struct event_config *cfg, int features)`函数来设置`require_features`。

需要注意的是,当需要设置多个参数的时候需要使用 `EV_FEATURE_O1 | EV_FEATURE_FDS`操作,而不是多次调用该函数。如果设置不当,找不当对应的事件方法method,`event_base_new_with_config(cfg)会返回NULL`。

最后一个参数`flag`指定其他的配置:

enum event_base_config_flag {    //不分配锁(如果设置,保证线程安全)    EVENT_BASE_FLAG_NOLOCK = 0x01,    //不检测EVENT_*环境变量?    EVENT_BASE_FLAG_IGNORE_ENV = 0x02,    //win下的iocp    EVENT_BASE_FLAG_STARTUP_IOCP = 0x04,     //?    EVENT_BASE_FLAG_NO_CACHE_TIME = 0x08,    //如果决定使用epoll这个多路IO复用函数,可以安全地使用更快的基于    changelist 的多路IO复用函数    EVENT_BASE_FLAG_EPOLL_USE_CHANGELIST = 0x10,    //?    EVENT_BASE_FLAG_PRECISE_TIMER = 0x20};

通过`event_config_set_flag(struct event_config *cfg, enum event_base_config_flag flag)`进行设置。

获取支持的配置

//获取当前系统支持的IO复用方法const char **event_get_supported_methods(void);//获取配置的IO复用方法const char *event_base_get_method(const struct event_base *);int event_base_get_features(const struct event_base *base);//指明某个参数是否被禁用static int event_config_is_avoided_method(const struct event_config *cfg, const char *method)

设置IO优先级

默认情况下会设置相同的优先级。

int event_base_priority_init(struct event_base *base, int n_priorities);int event_base_get_npriorities(struct event_base *base);

fork使用parent进程中的event_base

int event_reinit(struct event_base *base);#include 
/* example */struct event_base *base = event_base_new();/* ... add some events to the event_base ... */if (fork()) { /* In parent */ continue_running_parent(base); /*...*/} else { /* In child */ event_reinit(base); continue_running_child(base); /*...*/}

 

libevent 函数

考虑到多个平台的兼容性(并不是所有平台都支持某一函数功能),`libevent`自身提供了很多函数以及数据类型,下面的函数均是是跨平台的,在Unix以及windows都可以正常运行。

定时函数

#define evutil_timeradd(tvp, uvp, vvp) /* 增加 vvp=tvp+uvp */#define evutil_timersub(tvp, uvp, vvp) /* 减少 vvp=tvp-uvp */#define evutil_timercmp(tvp, uvp, cmp) /* 比较 if (cmp=='<'), then ("tvp < uvp") */int evutil_gettimeofday(struct timeval *tv, struct timezone *tz);/* Set tv = now */evutil_gettimeofday(&tv, NULL);

 

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.")

兼容的Socket接口

关闭socket:在`unix`中,只需要调用`close()`,而在`windows`中需要调用`closesocket()`。

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

获取socket错误信息

#define EVUTIL_SOCKET_ERROR() /* 获取最新的全局错误信息 */#define EVUTIL_SET_SOCKET_ERROR(errcode) /* 改变错误信息,等于设置错误 */#define evutil_socket_geterror(sock) /* 指定sockfd,同1 */#define evutil_socket_error_to_string(errcode) /* 把errcode转换为字符串 */

设置非阻塞模式

int evutil_make_socket_nonblocking(evutil_socket_t sock);

地址重用

int evutil_make_listen_socket_reuseable(evutil_socket_t sock);

socketpair

该函数和unix中的socketpair一样,它会产生两个连接socket,一个用于输入,一个用于输出。注意,在windows中,只支持family=AF_INET,type=SOCK_STREAM,protocol=0。

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

随机数生成

该函数生成n长度的buf数据

void evutil_secure_rng_get_bytes(void *buf, size_t n);

参考

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

http://www.tuicool.com/articles/jaQ7vmZ

本文 由  创作,采用 进行许可。欢迎转载,请注明出处:
转载自: 

你可能感兴趣的文章
闲扯下午引爆乌云社区“盗窃”乌云币事件
查看>>
02@在类的头文件中尽量少引入其他头文件
查看>>
JAVA IO BIO NIO AIO
查看>>
input checkbox 复选框大小修改
查看>>
BOOT.INI文件参数
查看>>
vmstat详解
查看>>
新年第一镖
查看>>
unbtu使用笔记
查看>>
OEA 中 WPF 树型表格虚拟化设计方案
查看>>
Android程序开发初级教程(一) 开始 Hello Android
查看>>
使用Gradle打RPM包
查看>>
“我意识到”的意义
查看>>
淘宝天猫上新辅助工具-新品填表
查看>>
再学 GDI+[43]: 文本输出 - 获取已安装的字体列表
查看>>
nginx反向代理
查看>>
操作系统真实的虚拟内存是什么样的(一)
查看>>
hadoop、hbase、zookeeper集群搭建
查看>>
python中一切皆对象------类的基础(五)
查看>>
modprobe
查看>>
android中用ExpandableListView实现三级扩展列表
查看>>