libevent简单介绍和使用

<pre class="html" name="code">libevent接口的使用是简单easy的、关键还是一些其他技术须要深入了解、如epoll!
以下文章来自open经验库:


libevent是一个基于事件触发的网络库,memcached底层也是使用libevent库。

整体来说,libevent有以下一些特点和优势:
* 事件驱动,高性能;
* 轻量级,专注于网络; 
* 跨平台,支持 Windows、Linux、Mac Os等; 
* 支持多种 I/O多路复用技术, epoll、poll、dev/poll、select 和kqueue 等; 

* 支持 I/O,定时器和信号等事件;

 

libevent有以下几大部分组成:

* 事件管理包含各种IO(socket)、定时器、信号等事件,也是libevent应用最广的模块;

* 缓存管理是指evbuffer功能;

* DNS是libevent提供的一个异步DNS查询功能;

* HTTP是libevent的一个轻量级http实现,包含server和client

 

一些资料:
* libevent官网:http://libevent.org/ 
* libevent API:http://www.monkey.org/~provos/libevent/doxygen-2.0.1/index.html
* CSDN上剖析得非常赞的文章:http://blog.csdn.net/sparkliang/article/details/4957667

 

// =============================================================================================

 

以下写了2个简单的使用样例,一个是定时器,一个是TCPserver,都仅仅涉及到libevent的事件管理模块。

 

一、简单定时器:实现程序每秒输出一个“Game Over!”

event_init() => evtimer_set() => event_add() =>event_dispatch()

查看源代码打印?
#include <stdio.h>    

#include <iostream>    
   
// libevent头文件    

#include <event.h>    

using namespace std;    

     

// 定时事件回调函数    

void onTime(int sock, short event, void *arg)    

 {    

    cout << "Game Over!" << endl;    

     

    struct timeval tv;    
     tv.tv_sec = 1;    
    tv.tv_usec = 0;    
    // 又一次加入定时事件(定时事件触发后默认自己主动删除)    
   event_add((struct event*)arg, &tv);    
}    
    
 int main()    
 {    

     // 初始化    

     event_init();    

      

     struct event evTime;    

     // 设置定时事件    

     evtimer_set(&evTime, onTime, &evTime);    

      

    struct timeval tv;    

    tv.tv_sec = 1;    

     tv.tv_usec = 0;    

     // 加入定时事件    

     event_add(&evTime, &tv);    

      

     // 事件循环    

     event_dispatch();    

      

     return 0;    

 } 
编译并运行,编译加 -levent:
查看源代码打印?
1 gapp_devnet_1:/data/home/andyawang/code/2013_11/LibeventTest # mv time.cpp timer.cpp    

2 gapp_devnet_1:/data/home/andyawang/code/2013_11/LibeventTest # g++ -o timer timer.cpp -levent    

3 gapp_devnet_1:/data/home/andyawang/code/2013_11/LibeventTest # ./timer     

4 Game Over!    

5 Game Over!    

6 Game Over!    

7 Game Over! 
二、TCPserver:实现监听本机8888port并输出client发送过来的信息

event_base_new()=>event_set()=>event_base_set()=>event_add()=>event_base_dispatch()
 #include <stdio.h>    

 #include <string.h>    

 #include <iostream>    

 #include <sys/socket.h>        

 #include <netinet/in.h>        

 #include <arpa/inet.h>        

 #include <netdb.h>    

      

 #include <event.h>    
 using namespace std;    

      

 // 事件base    

 struct event_base* base;    

     

 // 读事件回调函数    

 void onRead(int iCliFd, short iEvent, void *arg)    

 {    

     int iLen;    

     char buf[1500];    

     

     iLen = recv(iCliFd, buf, 1500, 0);    

     

    if (iLen <= 0) {    

         cout << "Client Close" << endl;    

      

        // 连接结束(=0)或连接错误(<0),将事件删除并释放内存空间    

         struct event *pEvRead = (struct event*)arg;    

         event_del(pEvRead);    

         delete pEvRead;    

      

         close(iCliFd);    

         return;    

     }    

      

     buf[iLen] = 0;    

     cout << "Client Info:" << buf << endl;    

 }    

      

 // 连接请求事件回调函数    

 void onAccept(int iSvrFd, short iEvent, void *arg)    

 {    

     int iCliFd;    

    struct sockaddr_in sCliAddr;    

      

     socklen_t iSinSize = sizeof(sCliAddr);    

     iCliFd = accept(iSvrFd, (struct sockaddr*)&sCliAddr, &iSinSize);    

      

     // 连接注冊为新事件 (EV_PERSIST为事件触发后不默认删除)    

     struct event *pEvRead = new event;    

    event_set(pEvRead, iCliFd, EV_READ|EV_PERSIST, onRead, pEvRead);    

     event_base_set(base, pEvRead);    

     event_add(pEvRead, NULL);    

 }    

      

 int main()    

{    

      

     int iSvrFd;      

     struct sockaddr_in sSvrAddr;    

                    

     memset(&sSvrAddr, 0, sizeof(sSvrAddr));      

     sSvrAddr.sin_family = AF_INET;      

     sSvrAddr.sin_addr.s_addr = inet_addr("127.0.0.1");        

     sSvrAddr.sin_port = htons(8888);       

                                  

     // 创建tcpSocket(iSvrFd),监听本机8888port      

     iSvrFd = socket(AF_INET, SOCK_STREAM, 0);      

    bind(iSvrFd, (struct sockaddr*)&sSvrAddr, sizeof(sSvrAddr));      

     listen(iSvrFd, 10);    

      

     // 初始化base    
     base = event_base_new();    

     struct event evListen;    

    // 设置事件    

    event_set(&evListen, iSvrFd, EV_READ|EV_PERSIST, onAccept, NULL);    

     // 设置为base事件    

     event_base_set(base, &evListen);    

     // 加入事件    

     event_add(&evListen, NULL);    

          

     // 事件循环    

     event_base_dispatch(base);    

     

     return 0;    

 } 



 

原文地址:https://www.cnblogs.com/bhlsheji/p/4273882.html