zoukankan      html  css  js  c++  java
  • libevent简述

    一。libevent概念

    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.进入解压目录 

    4. ./congifure

    5. make

    5.sudo make install

    6.以上完成后会在/usr/local/lib下生成库文件,将/usr/local/lib加入到 /etc/ls.so.conf内

    7.sudo ldconfig -v

    三。基本函数

    1.创建事件处理框架

    2.创建事件

    what的参数可以设为:

     

    3.将事件加入到事件处理框架中(让事件处于未决状态)

    4.事件处理框架循环处理事件(事件触发后执行事件的回调函数)

    5.将事件从事件处理框架中卸下(将事件设置为非未决)

    6.释放事件

     7.释放事件处理 框架

     

    8.libevent读写管道

     //写管道
    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 ",++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 ",buf); 17 printf("read event:%s ",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

    1。概念

    bufferevent是libevent基于套接字创建的IO缓冲区,分为读缓冲区和写缓冲区。

       当读缓冲区有数据时,会调用相应的读回调函数。

       当有数据写入写缓冲区时,会调用相应的写回调函数

    bufferevent相当于服务器与客户端建立连接之后(accept之后),对读写事件进行监听并处理。

    2.函数

    1.创建带缓冲区的事件

    2.缓冲区链接(客户端)

    3.设置事件回调函数

    4.设置缓冲区可读,可写

    5.释放缓冲区

     

    五。evconnlistener 连接监听器

    1.简述

    evconnlistener在服务端可以代替socket,bind,listen,accept的操作,并且可以设置监听的回调函数,当有客户端连接后执行回调函数。

    2.函数

    1.创建连接监听器

     2.启用和禁用evconnlistener

    服务端实现

     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]!='')
    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("数据已发送
    ");
    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
    ");
    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
    ", buf);
    16 }
    17 
    18 void write_cb(struct bufferevent *bev, void *arg)
    19 {
    20     printf("I am Write_cb function....
    ");
    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
    ");  
    28     }
    29     else if(events & BEV_EVENT_ERROR)   
    30     {
    31         printf("some other error
    ");
    32     }
    33     else if(events & BEV_EVENT_CONNECTED)
    34     {
    35         printf("成功连接到服务器, O(∩_∩)O哈哈~
    ");
    36         return;
    37     }
    38     
    39     bufferevent_free(bev);
    40     printf("free bufferevent...
    ");
    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("请输入要发送的数据: 
    ");
    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 }
  • 相关阅读:
    最有影响力的计算机视觉会议及期刊论文
    计算机视觉与图像处理方面的顶级期刊
    总结一下国内搞机器学习和数据挖掘的大牛
    戴尔▪卡耐基《人性的弱点》阅读笔记(1)
    Python GUI之tkinter窗口视窗教程大集合(看这篇就够了)
    自控力极差的人如何自救?
    非技术人员也能看懂云计算,大数据,人工智能
    保罗·多兰《设计幸福》阅读笔记
    神经网络浅讲:从神经元到深度学习----以简单循序的方式带你聊聊深度学习
    从机器学习谈起----极好的一篇机器学习全貌入门文章
  • 原文地址:https://www.cnblogs.com/sclu/p/11318153.html
Copyright © 2011-2022 走看看