libevent安装及使用

一、安装libevent

官网:http://libevent.org/

选择最新版本下载,我选择的是libevent-2.0.22-stable.tar.gz,然后安装README文件中描述的方法编译、安装即可。

./configure
make
make verify # 可选操作
make install

二、使用libevent

示例1:回显服务器

/*******************************************************************************
* File Name        : echo.c
* Author        : zjw
* Email            : emp3XzA3MjJAMTYzLmNvbQo= (base64 encode)
* Create Time    : 2015年07月14日 星期二 09时05分37秒
*******************************************************************************/
#include <event.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

#define SERVER_PORT 8080
int debug = 0;

struct client
{
    int fd;
    struct bufferevent *buf_ev;
};

int setnonblock(int fd)
{
    int flags;

    flags = fcntl(fd, F_GETFL);
    flags |= O_NONBLOCK;
    fcntl(fd, F_SETFL, flags);
}

void buf_read_callback(struct bufferevent *incoming, void *arg)
{
    struct evbuffer *evreturn;
    char *req;

    req = evbuffer_readline(incoming->input);
    if (req == NULL)
    {
        return ;
    }

    evreturn = evbuffer_new();
    evbuffer_add_printf(evreturn, "You said: %s\n", req);
    bufferevent_write_buffer(incoming, evreturn);
    evbuffer_free(evreturn);
    free(req);
}

void buf_write_callback(struct bufferevent *bev, void *arg)
{ }

void buf_error_callback(struct bufferevent *bev, short what, void *arg)
{
    struct client *client = (struct client*)arg;
    bufferevent_free(client->buf_ev);
    close(client->fd);
    free(client);
}

void accept_callback(int fd, short ev, void *arg)
{
    int client_fd;
    struct sockaddr_in client_addr;
    socklen_t client_len = sizeof(client_addr);
    struct client *client;

    client_fd = accept(fd, (struct sockaddr*)&client_addr, &client_len);

    if (client_fd < 0)
    {
        perror("Client: accept() failed");
        return ;
    }

    setnonblock(client_fd);

    client = calloc(1, sizeof(*client));
    if (client == NULL)
    {
        perror("1 malloc failed");
    }

    client->fd = client_fd;
    client->buf_ev = bufferevent_new(client_fd, buf_read_callback, buf_write_callback, buf_error_callback, client);

    bufferevent_enable(client->buf_ev, EV_READ);
}

int main(int argc, char **argv)
{
    int socketlisten;
    struct sockaddr_in addresslisten;
    struct event accept_event;
    int reuse = 1;

    event_init();
    
    socketlisten = socket(AF_INET, SOCK_STREAM, 0);
    if (socketlisten < 0)
    {
        fprintf(stderr, "Failed to create listen socket");
        return 1;
    }

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

    addresslisten.sin_family = AF_INET;
    addresslisten.sin_addr.s_addr = INADDR_ANY;
    addresslisten.sin_port = htons(SERVER_PORT);

    if (bind(socketlisten, (struct sockaddr*)&addresslisten, sizeof(addresslisten)) < 0)
    {
        fprintf(stderr, "Failed to bind");
        return 1;
    }

    if (listen(socketlisten, 5) < 0)
    {
        fprintf(stderr, "Failed to listen to socket");
        return 1;
    }

    setsockopt(socketlisten, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
    setnonblock(socketlisten);
    
    event_set(&accept_event, socketlisten, EV_READ | EV_PERSIST, accept_callback, NULL);
    event_add(&accept_event, NULL);
    event_dispatch();
    close(socketlisten);

    return 0;
}

编译并运行该回显服务器:

gcc -o echo ./echo.c -levent
./echo

但是在运行的时候提示找不到动态链接库,那么肯定是库放的路径,链接器找不到,所以翻看执行make install命令时把库安装在什么地方了。

如果再./configure时不指定--prefix=/usr,则默认会安装在/usr/local/lib路径下。所以需要创建软链接。

我的是64位系统,所以软链接应该创建在/usr/lib64目录下: n -s /usr/local/lib/libevent-2.0.so.5 /usr/lib64/libevent-2.0.so.5 

然后再执行: ./echo 运行之后不会有提示,为了测试,可以保持该终端开着,另开一个终端,使用telnet来测试一下。

执行: telnet localhost 8080 

示例2:定时器

/*******************************************************************************
* File Name        : timer.c
* Author        : zjw
* Email            : emp3XzA3MjJAMTYzLmNvbQo= (base64 encode)
* Create Time    : 2015年07月14日 星期二 10时00分08秒
*******************************************************************************/
#include <stdio.h>
#include <iostream>
#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 evTimer;
    // 设置定时事件
    evtimer_set(&evTimer, OnTime, &evTimer);

    struct timeval tv;
    tv.tv_sec = 1;
    tv.tv_usec = 0;
    // 添加定时事件
    event_add(&evTimer, &tv);

    // 事件循环
    event_dispatch();

    return 0;
}

编译并运行该定时器: g++ -o timer ./timer.cpp -levent 

运行结果:

参考:

http://www.ibm.com/developerworks/cn/aix/library/au-libev/

http://www.open-open.com/lib/view/open1386510630330.html

posted @ 2015-07-14 09:52  冷冰若水  阅读(8642)  评论(0编辑  收藏  举报