这篇文章主要介绍了libevent库的使用方法实例,有需要的朋友可以参考一下
接写一个很简单的时间服务器来当作例子:当你连上去以后计算机网络服务器端直接提供时间,然后结束连线event_init()表示初始化libevent所使用到的变数事件集(ev,s,ev_READ | ev_PERSIST,connection_accept,EV)把s这个文件描述放入电动汽车(第一个参数与第二个参数),并且告知当事件(第三个参数的EV_READ)发生时要呼叫连接接受() (第四个参数),呼叫时要把电子伏特当作参数丢进去(第五个参数)。其中的EV _持久表示当呼叫进去的时候不要把这个事件拿掉(继续保留在事件队列里面),这点可以跟连接接受()内在注册连接时间()的代码做比较。而event_add(ev,NULL)就是把电子伏特注册到事件队列里面,第二个参数指定的是超时时间,设定成空表示忽略这项设定。注:这段代码来自于网络,虽然很粗糙,但是对libevent的使用方法已经说明的很清楚了。附源码:复制代码代码如下:#包含netinet/in。h #包含系统/插座。h #包含系统/类型。h #包含事件。h #包含stdio。h #包括时间。h
void connection_time(int fd,short event,struct event * arg){ char buf[32];struct TM t;现在时间
时间(现在);本地时间_r(现在,t);asctime_r(t,buf);
write(fd,buf,strlen(buf));关机(fd,SHUT _ RDWR);
免费(arg);}
void connection_accept(int fd,short event,void *arg) { /*用于调试*/fprintf(stderr, %s(): fd=%d,event=%d,n ,__func__,fd,event);
/*接受新连接. s _ in */struct sockaddr _ in s _ in;socklen _ t len=sizeof(s _ in);int ns=accept(fd,(struct sockaddr *) s_in,len);if(ns 0){ perror( accept );返回;}
/*安装时间服务器. */struct event * ev=malloc(size of(struct event));event_set(ev,ns,EV_WRITE,(void *) connection_time,EV);event_add(ev,NULL);}
int main(void) { /*请求套接字. s */int s=socket(PF _ INET,SOCK_STREAM,0);if(s 0){ perror( socket );出口(1);}
/* bind()*/struct sockaddr _ in s _ in;bzero(s_in,sizeof(s _ in));s _ in.sin _ family=AF _ INETs _ in。sin _ port=htons(7000);s _ in。sin _ addr。s _ addr=in addr _ ANYif (bind(s,(struct sockaddr *) s_in,sizeof(s _ in))0){ perror( bind );出口(1);}
/* listen() */if (listen(s,5)0){ perror( listen );出口(1);}
/*初始libevent .*/event_init().
/*创建事件.事件ev;event_set(ev,s,EV_READ | EV_PERSIST,connection_accept,EV);
/*添加事件. event */event _ add(ev,NULL);
事件分派().
返回0;}
在写非阻塞网络程序通常要处理减轻的问题,但并不好写,主要是因为阅读()或接收()不保证可以一次读到一行的份量进来。在libevent里面提供相当不错的缓冲库可以用,完整的说明在男子项目的时候可以看到,最常用的应该就是以evbuffer_add()、evbuffer_readline()这两个功能,其他的知道存在就可以了,需要的时候再去看详细的用法。下面直接提供libevent-buff.c当作范例,编译后看执行结果,再回头来看源代码应该就有感觉了:复制代码代码如下:#包含系统/时间。h #包含事件。h #包含stdio。h
void print buf(struct ev buff * ev buf){ for(;){ char * buf=ev buffer _ readline(ev buf);printf(* buf=%p,string= e[1;33m%se[mn ,buf,buf);if(buf==NULL)break;免费(buf);} }
int main(void){ struct ev buff * ev buf;
ev buf=ev buffer _ new();if (evbuf==NULL) { fprintf(stderr, %s(): evbuffer_new()失败. n ,_ _ func _ _);出口(1);}
/*将“葛丝琳”添加到缓冲区中*/u _ char * buf 1= GS Lin ;printf( * Add e[1;33百万分之南方的,东方的.n ,buf 1);evbuffer_add(evbuf,buf1,strlen(buf 1));print buf(ev buf);
u_char *buf2=正在读取% 22 n他在家% 22 n最后。printf( * Add e[1;33百万分之南方的,东方的.n ,buf 2);evbuffer_add(evbuf,buf2,strlen(buf 2));print buf(ev buf);
ev buff _ free(ev buf);} 最后的事件分派()表示进入事件循环,当长队里面的任何一个文件描述发生事件的时候就会进入回调函数执行。