socket属性设置与初始化操

来源:互联网 发布:mac mysql phpmyadmin 编辑:程序博客网 时间:2024/06/05 17:22

http://www.cnblogs.com/coder2012/p/4259118.html

socket属性设置与初始化操作

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 <event2/event.h>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 <event2/event.h>/* 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



0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 小婴儿体重不长怎么办 2岁半宝宝不说话怎么办 米兰叶子掉光了怎么办 qq雷霆战机闪退怎么办 微信限额20万怎么办 欧拉方程x<0怎么办 柿子核吃下去了怎么办 橡胶底白色变黄怎么办 20了丁丁还很小怎么办 5角硬币吞进肚子怎么办 孩子吞了5角硬币怎么办 左腿比右腿微粗怎么办 一个腿长一个腿短怎么办 刚买的毛笔很硬怎么办 我哥哥太爱我了怎么办 如果婚姻无法维持该怎么办 捡了一只流浪狗怎么办 微博加载不出来怎么办 我的脾气很暴躁怎么办 歌单恢复已删除怎么办 家里破产了我该怎么办 对付有心计的人怎么办 上嘴唇无故肿了怎么办 下嘴唇肿了一半怎么办 狗狗早上叫不停怎么办 狗在家乱咬东西怎么办 狗狗晚上一直叫怎么办 金毛幼犬晚上叫怎么办 金毛晚上老是叫怎么办 5岁宝宝总尿裤子怎么办 2岁宝宝尿裤子怎么办 2周岁宝宝尿裤子怎么办 5岁宝宝尿裤子怎么办 模拟人生4不怀孕怎么办 狗狗的毛打结怎么办 狗狗生病了不吃东西怎么办 给领导送礼不收怎么办 国外弃货,货代怎么办 不小心拜了阴庙怎么办 要考试了不想考怎么办? 刚怀孕喝了红酒怎么办