Libevent 是一个用C语言编写的、轻量级的开源高性能事件通知库,主要有如下几个亮点:事件驱动( event-driven),高性能;轻量级,专一于网络,不如 ACE 那么臃肿庞大;源代码至关精炼、易读;跨平台,支持 Windows、 Linux、 *BSD 和 Mac Os;支持多种 I/O 多路复用技术, epoll、 poll、 dev/poll、 select 和 kqueue 等;支持 I/O,定时器和信号等事件;注册事件优先级。服务器
1.从官网下载安装包libevent-2.1.8-stable.tar.gz网络
2.解压 jar zxvf libevent-2.1.8-stable.tar.gz框架
3.进入解压目录 socket
4. ./congifure函数
5. make性能
5.sudo make installthis
6.以上完成后会在/usr/local/lib下生成库文件,将/usr/local/lib加入到 /etc/ls.so.conf内spa
7.sudo ldconfig -v3d
what的参数能够设为:code
//写管道
1 #include<stdio.h> 2 #include<unistd.h> 3 #include<stdlib.h> 4 #include<sys/types.h> 5 #include<sys/stat.h> 6 #include<string.h> 7 #include<fcntl.h> 8 #include<event2/event.h> 9 10 //事件回调函数 11 void write_call_back(evutil_socket_t fd,short what,void *arg) 12 { 13 //写管道 14 char buf[BUFSIZ]; 15 static int num=0; 16 sprintf(buf,"this is the %d data\n",++num); 17 write(fd,buf,sizeof(buf)); 18 return ; 19 } 20 //写管道 21 int main() 22 { 23 //openfile 24 int fd=open("myfifo",O_WRONLY|O_NONBLOCK); 25 if(fd==-1) 26 { 27 perror("open err"); 28 exit(1); 29 } 30 //写管道 31 struct event_base* base=NULL; 32 base=event_base_new(); 33 //建立事件 34 struct event* event=NULL; 35 //检测写缓冲区是否有空间写 36 event=event_new(base,fd,EV_WRITE|EV_PERSIST,write_call_back,NULL); 37 //添加事件 38 event_add(event,NULL); //阻塞等待事件发生 39 //事件循环 40 event_base_dispatch(base); 41 //释放事件 42 event_free(event); 43 //释放框架 44 event_base_free(base); 45 close(fd); 46 return 0; 47 }
//读管道
1 #include<stdio.h> 2 #include<unistd.h> 3 #include<stdlib.h> 4 #include<sys/types.h> 5 #include<sys/stat.h> 6 #include<string.h> 7 #include<fcntl.h> 8 #include<event2/event.h> 9 10 //事件回调函数 11 void read_call_back(evutil_socket_t fd,short what,void *arg) 12 { 13 //读管道 14 char buf[BUFSIZ]; 15 int len=read(fd,buf,sizeof(buf)); 16 printf("buf:%s\n",buf); 17 printf("read event:%s\n",what&EV_READ?"yes":"no"); 18 return ; 19 } 20 //读管道 21 int main() 22 { 23 unlink("myfifo"); 24 //建立有名管道 25 mkfifo("myfifo",0664); 26 27 //openfile 28 int fd=open("myfifo",O_RDONLY|O_NONBLOCK); 29 if(fd==-1) 30 { 31 perror("open err"); 32 exit(1); 33 } 34 //读管道 35 struct event_base* base=NULL; 36 base=event_base_new(); 37 //建立事件 38 struct event* event=NULL; 39 event=event_new(base,fd,EV_READ|EV_PERSIST,read_call_back,NULL); 40 //添加事件 41 event_add(event,NULL); //阻塞等待事件发生 42 //事件循环 43 event_base_dispatch(base); 44 //释放事件 45 event_free(event); 46 //释放框架 47 event_base_free(base); 48 close(fd); 49 return 0; 50 }
bufferevent是libevent基于套接字建立的IO缓冲区,分为读缓冲区和写缓冲区。
当读缓冲区有数据时,会调用相应的读回调函数。
当有数据写入写缓冲区时,会调用相应的写回调函数
bufferevent至关于服务器与客户端创建链接以后(accept以后),对读写事件进行监听并处理。
evconnlistener在服务端能够代替socket,bind,listen,accept的操做,而且能够设置监听的回调函数,当有客户端链接后执行回调函数。
1 #include<stdio.h> 2 #include<unistd.h> 3 #include<stdlib.h> 4 #include<sys/types.h> 5 #include<sys/stat.h> 6 #include<string.h> 7 #include<ctype.h> 8 #include<event2/event.h> 9 #include<event2/bufferevent.h> //带缓冲区的事件 10 #include<event2/listener.h> //链接监听器 11 #define PORT 8888 12 13 //读回调 14 void readcb(struct bufferevent* bev,void* arg) 15 { 16 char buf[1024]={0}; 17 //读缓冲区的数据 18 bufferevent_read(bev,buf,sizeof(buf)); 19 int i=0; 20 while(buf[i]!='\0') 21 { 22 buf[i]=toupper(buf[i]); 23 i++; 24 } 25 //往缓冲区发送数据 26 bufferevent_write(bev,buf,sizeof(buf)); 27 28 } 29 30 //写回调 31 void writecb(struct bufferevent* bev,void* arg) 32 { 33 printf("数据已发送\n"); 34 } 35 36 //事件回调 37 void eventcb(struct bufferevent* bev,short events,void *arg) 38 { 39 if(events&BEV_EVENT_EOF) 40 { 41 printf("connection cloased"); 42 }else if(events&BEV_EVENT_ERROR) 43 { 44 printf("err\n"); 45 } 46 //释放bufferevent资源 47 bufferevent_free(bev); 48 } 49 50 //链接完成以后对应的通讯操做 51 void listen_call_back(struct evconnlistener* listener,evutil_socket_t fd,struct sockaddr* addr,int len,void *ptr) 52 { 53 //接收base 54 struct event_base *base=(struct event_base*)ptr; 55 //接收数据 - 发送数据 56 //将fd封装成带缓冲区的事件 57 struct bufferevent* bev=bufferevent_socket_new(base,fd,BEV_OPT_CLOSE_ON_FREE); 58 //给bufferevent对应的读写缓冲区设置回调函数 59 bufferevent_setcb(bev,readcb,writecb,eventcb,NULL); 60 //设置独缓冲区的回调可用 61 bufferevent_enable(bev,EV_READ); 62 } 63 int main() 64 { 65 //建立事件处理框架 66 struct event_base* base=event_base_new(); 67 //设置服务器地址信息 68 struct sockaddr_in serv; 69 memset(&serv,0,sizeof(serv)); 70 serv.sin_family=AF_INET; 71 serv.sin_port=htons(PORT); 72 serv.sin_addr.s_addr=htonl(INADDR_ANY); 73 //建立监听的套接字 74 //绑定 75 //监听 76 //等待并接收链接 77 //有链接时listen_call_back被调用 78 struct evconnlistener* listen=evconnlistener_new_bind(base,listen_call_back,base,LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE,-1,(struct sockaddr*)&serv,sizeof(serv)); 79 //开始事件循环 80 event_base_dispatch(base); 81 //释放资源 82 evconnlistener_free(listen); 83 event_base_free(base); 84 return 0; 85 }
1 #include <stdio.h> 2 #include <unistd.h> 3 #include <stdlib.h> 4 #include <sys/types.h> 5 #include <sys/stat.h> 6 #include <string.h> 7 #include <event2/event.h> 8 #include <event2/bufferevent.h> 9 10 11 void read_cb(struct bufferevent *bev, void *arg) 12 { 13 char buf[1024] = {0}; 14 bufferevent_read(bev, buf, sizeof(buf)); 15 printf("Server say: %s\n", buf); 16 } 17 18 void write_cb(struct bufferevent *bev, void *arg) 19 { 20 printf("I am Write_cb function....\n"); 21 } 22 23 void event_cb(struct bufferevent *bev, short events, void *arg) 24 { 25 if (events & BEV_EVENT_EOF) 26 { 27 printf("connection closed\n"); 28 } 29 else if(events & BEV_EVENT_ERROR) 30 { 31 printf("some other error\n"); 32 } 33 else if(events & BEV_EVENT_CONNECTED) 34 { 35 printf("成功链接到服务器, O(∩_∩)O哈哈~\n"); 36 return; 37 } 38 39 bufferevent_free(bev); 40 printf("free bufferevent...\n"); 41 } 42 43 void send_cb(evutil_socket_t fd, short what, void *arg) 44 { 45 char buf[1024] = {0}; 46 struct bufferevent* bev = (struct bufferevent*)arg; 47 printf("请输入要发送的数据: \n"); 48 read(fd, buf, sizeof(buf)); 49 bufferevent_write(bev, buf, strlen(buf)+1); 50 } 51 52 53 int main(int argc, const char* argv[]) 54 { 55 struct event_base* base; 56 base = event_base_new(); 57 58 59 struct bufferevent* bev; 60 bev = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE); 61 62 // 链接服务器 63 struct sockaddr_in serv; 64 memset(&serv, 0, sizeof(serv)); 65 serv.sin_family = AF_INET; 66 serv.sin_port = htons(9876); 67 evutil_inet_pton(AF_INET, "127.0.0.1", &serv.sin_addr.s_addr); 68 bufferevent_socket_connect(bev, (struct sockaddr*)&serv, sizeof(serv)); 69 70 // 设置回调 71 bufferevent_setcb(bev, read_cb, write_cb, event_cb, NULL); 72 bufferevent_enable(bev, EV_READ | EV_PERSIST); 73 74 // 建立一个事件 75 struct event* ev = event_new(base, STDIN_FILENO, 76 EV_READ | EV_PERSIST, 77 send_cb, bev); 78 event_add(ev, NULL); 79 80 event_base_dispatch(base); 81 82 event_base_free(base); 83 84 return 0; 85 }