libevent 安装与使用说明

1. 简介

  libevent是一个事件触发的网络库,适用于windows、linux、bsd等多种平台,内部使用select、epoll、kqueue、IOCP等系统调用管理事件机制。著名分布式缓存软件memcached也是基于libevent,而且libevent在使用上可以做到跨平台,而且根据libevent官方网站上公布的数据统计,似乎也有着非凡的性能。
  
  主要特点如下:

  • 事件驱动,高性能;
  • 轻量级,专注于网络;
  • 跨平台,支持 Windows、Linux、Mac Os等;
  • 支持多种 I/O多路复用技术, epoll、poll、dev/poll、select 和kqueue 等;
  • 支持 I/O,定时器和信号等事件;

2. 安装libevent

  本文默认的安装环境为Linux。
  

1). 可以到libevent官网下载安装包解压到本地目录,也可以从Github上clone到本地目录,然后进行安装。git clone https://github.com/libevent/libevent

2). 在libevent的目录下,输入一下命令进行安装。

$ ./configure
$ make
$ make verify # (optional)
$ sudo make install

3. libevent 在socket异步编程示例

  创建 libevent 服务器的基本方法是,注册当发生某一操作(比如接受来自客户端的连接)时应该执行的函数,然后调用主事件循环 event_dispatch() 或者 event_base_dispatch()。执行过程的控制现在由 libevent 系统处理。注册事件和将调用的函数之后,事件系统开始自治;在应用程序运行时,可以在事件队列中添加(注册)或删除(取消注册)事件。事件注册非常方便,可以通过它添加新事件以处理新打开的连接,从而构建灵活的网络处理系统。
  下例是用libevent库写了一个socket服务端程序,简单回显客户端发来的内容。
  
  socket_event_test.h文件:
  

#include <iostream>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>

#include <event.h>

#define MAX_SIZE 1024 //接收和发送缓冲区大小
define PORT     33288       //绑定端口

using namespace std;

struct event_base *base;
struct sock_event{
    struct event read_ev;
    struct event write_ev;
    char buffer[MAX_SIZE];

    sock_event(){}
    ~sock_event(){}
};
//响应事件函数
void on_write(int sock, short event, void *args);
void on_read(int sock, short event, void *args);
void on_accept(int sock, short event, void *args);

  socket_event_test.cc文件:
  

#include "socket_event_test.h"
#include <cstring>

void on_write(int sock, short event, void *args){
    char *buf = (char *)args;

    send(sock, buf, strlen(buf)+1, 0);

}

void on_read(int sock, short event, void *args){
    struct event write;
    int i_size;

    struct sock_event sv;
    i_size = recv(sock, sv.buffer,MAX_SIZE,0);

    if(i_size == 0) return ;

    printf("Received from client: %s\n",sv.buffer);

    char buf[MAX_SIZE+20];
    sprintf(buf,"You say :%s",sv.buffer);

    event_set(&sv.write_ev, sock, EV_WRITE, on_write, buf);
    event_base_set(base, &sv.write_ev);
    event_add(&sv.write_ev,NULL);
}

void on_accept(int sock, short event, void *args){
    struct sockaddr_in addr_in;
    struct sock_event sv;
    int fd;
    socklen_t addr_size;

    printf("Waiting for accept...\n");

    addr_size = sizeof(struct sockaddr_in);
    fd = accept(sock, (struct sockaddr*)&addr_in, &addr_size);

    if(fd < 0) {
        printf("Accept failed!\n");
        return ;
    }

    event_set(&sv.read_ev, fd, EV_READ|EV_PERSIST, on_read, &sv);
    event_base_set(base, &sv.read_ev);
    event_add(&sv.read_ev,NULL);
}

int main(){
    struct sockaddr_in addr_in;
    int sock, yes = 1,i_result;

    sock = socket(AF_INET, SOCK_STREAM, 0);
    //setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
    memset(&addr_in, 0, sizeof(addr_in));

    printf("Init socket ...\n");

    addr_in.sin_family = AF_INET;
    addr_in.sin_port = htons(PORT);
    addr_in.sin_addr.s_addr = INADDR_ANY;
    i_result = bind(sock, (struct sockaddr*)&addr_in, sizeof(struct sockaddr));

    if(i_result < 0) {
        printf("Bind error!\n");
        return -1;
    }

    listen(sock, 5);

    printf("Listening...\n");

    struct event listen_ev;
    base = event_base_new();

    event_init();

    event_set(&listen_ev, sock, EV_READ|EV_PERSIST, on_accept, NULL);
    event_base_set(base, &listen_ev);
    event_add(&listen_ev, NULL);
    event_base_dispatch(base);
    event_dispatch();

    event_base_free(base);

    return 0;
}

  使用如下命令进行编译,要加上-levent选项:

c++ socket_event_test.c -o socket_event_test -levent

  运行socket服务端程序,然后用Telnet命令进行测试,结果如下:
  
  socket服务端:
  

Init socket …
Listening…
Waiting for accept…
Received from client: hello,world
Received from client: Nice, it worked!

  Telnet端:
  

Trying 127.0.0.1…
Connected to localhost.
Escape character is ‘^]’.
hello,world
You say :hello,world
Nice, it worked!
You say :Nice, it worked!

4. 参考资料

  http://www.wangafu.net/~nickm/libevent-book/
  http://popozhu.github.io/2013/06/11/libevent_r2_%E5%88%9B%E5%BB%BAevent_base/
  https://www.ibm.com/developerworks/cn/aix/library/au-libev/
  http://www.cnblogs.com/cnspace/archive/2011/07/19/2110891.html

你可能感兴趣的:(libevent,Linux平台,高性能网络库)