libevent源码分析-介绍、安装、使用

  • Libevent介绍
  • 安装
  • 样例

Libevent介绍

在include\event2\event.h中有关于Libevent的介绍,这里简单翻译介绍一下:

Libevent是以事件为驱动的开发可扩展的网络服务端的库。

开放的API设置事件的回调函数,当事件来暂时调用这个回调函数。它还支持信号和定时器。

开发人员仅仅须要简单的add/remove来将事件加入到event loop中,通过event_dispatch驱动event。

Libevent支持 /dev/poll, kqueue(2), select(2), poll(2),

epoll(4), and evports。

内部的事件机制和应用接口相互独立,因此内部实现的更新不影响应用程序。

Libevent能够用于多线程。

安装

在官网下载http://libevent.org。我下载了最新版本号libevent-2.0.22-stable.tar.gz。放到文件夹,解压缩tar -zxvf ibevent-2.0.22-stable.tar.gz。

解压后进入文件夹,进行配置。把库安装到/usr文件夹下

./configure --prefix=/usr

编译安装

sudo make
sudo make install

查看是否成功安装:

ls -al /usr/lib|grep libevent
lrwxrwxrwx   1 root root           21  8月 11 00:04 libevent-2.0.so.5 -> libevent-2.0.so.5.1.9
-rwxr-xr-x   1 root root       920932  8月 11 00:04 libevent-2.0.so.5.1.9
-rw-r--r--   1 root root      1309268  8月 11 00:04 libevent.a
lrwxrwxrwx   1 root root           26  8月 11 00:04 libevent_core-2.0.so.5 -> libevent_core-2.0.so.5.1.9
-rwxr-xr-x   1 root root       557242  8月 11 00:04 libevent_core-2.0.so.5.1.9
-rw-r--r--   1 root root       821804  8月 11 00:04 libevent_core.a
-rwxr-xr-x   1 root root          974  8月 11 00:04 libevent_core.la
lrwxrwxrwx   1 root root           26  8月 11 00:04 libevent_core.so -> libevent_core-2.0.so.5.1.9
lrwxrwxrwx   1 root root           27  8月 11 00:04 libevent_extra-2.0.so.5 -> libevent_extra-2.0.so.5.1.9
-rwxr-xr-x   1 root root       379504  8月 11 00:04 libevent_extra-2.0.so.5.1.9
-rw-r--r--   1 root root       487536  8月 11 00:04 libevent_extra.a
-rwxr-xr-x   1 root root          981  8月 11 00:04 libevent_extra.la
lrwxrwxrwx   1 root root           27  8月 11 00:04 libevent_extra.so -> libevent_extra-2.0.so.5.1.9
-rwxr-xr-x   1 root root          939  8月 11 00:04 libevent.la
lrwxrwxrwx   1 root root           29  8月 11 00:04 libevent_openssl-2.0.so.5 -> libevent_openssl-2.0.so.5.1.9
-rwxr-xr-x   1 root root        90317  8月 11 00:04 libevent_openssl-2.0.so.5.1.9
-rw-r--r--   1 root root       110340  8月 11 00:04 libevent_openssl.a
-rwxr-xr-x   1 root root         1010  8月 11 00:04 libevent_openssl.la
lrwxrwxrwx   1 root root           29  8月 11 00:04 libevent_openssl.so -> libevent_openssl-2.0.so.5.1.9
lrwxrwxrwx   1 root root           30  8月 11 00:04 libevent_pthreads-2.0.so.5 -> libevent_pthreads-2.0.so.5.1.9
-rwxr-xr-x   1 root root        20571  8月 11 00:04 libevent_pthreads-2.0.so.5.1.9
-rw-r--r--   1 root root        14322  8月 11 00:04 libevent_pthreads.a
-rwxr-xr-x   1 root root         1002  8月 11 00:04 libevent_pthreads.la
lrwxrwxrwx   1 root root           30  8月 11 00:04 libevent_pthreads.so -> libevent_pthreads-2.0.so.5.1.9
lrwxrwxrwx   1 root root           21  8月 11 00:04 libevent.so -> libevent-2.0.so.5.1.9

样例

写各測试程序,编译时要设置參数-levent,连接libevent的库。

echoServer.cc

#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include <event.h>
#include <stdlib.h>
#include <unistd.h>

#define PORT        8000
#define BACKLOG     5
#define MEM_SIZE    1024

struct event_base* base;
struct sockEvent
{
    struct event* readEvent;
    struct event* writeEvent;
    char* buffer;
};

void releaseSockEvent(struct sockEvent* ev)//delete from base and free it
{
    event_del(ev->readEvent);
    free(ev->readEvent);
    free(ev->writeEvent);
    free(ev->buffer);
    free(ev);
}

void handleWrite(int sock, short event, void* arg)
{
    char* buffer = (char*)arg;
    send(sock, buffer, strlen(buffer), 0);

    free(buffer);
}

void handldRead(int sock, short event, void* arg)
{
    struct event* writeEvent;
    int size;
    struct sockEvent* ev = (struct sockEvent*)arg;
    ev->buffer = (char*)malloc(MEM_SIZE);
    bzero(ev->buffer, MEM_SIZE);
    size = recv(sock, ev->buffer, MEM_SIZE, 0);
    printf("receive data:%s, size:%d\n", ev->buffer, size);
    if (size == 0) //client has send FIN
    {
        releaseSockEvent(ev);
        close(sock);
        return;
    }
    //add event to base to send the received data
    event_set(ev->writeEvent, sock, EV_WRITE, handleWrite, ev->buffer);
    event_base_set(base, ev->writeEvent);
    event_add(ev->writeEvent, NULL);
}

void handleAccept(int sock, short event, void* arg)//when new connection coming, calling this func
{
    struct sockaddr_in cli_addr;
    int newfd;
    socklen_t sinSize;
    struct sockEvent* ev = (struct sockEvent*)malloc(sizeof(struct sockEvent));
    ev->readEvent = (struct event*)malloc(sizeof(struct event));
    ev->writeEvent = (struct event*)malloc(sizeof(struct event));
    sinSize = sizeof(struct sockaddr_in);
    newfd = accept(sock, (struct sockaddr*)&cli_addr, &sinSize);
    //set the new coming connection event
    event_set(ev->readEvent, newfd, EV_READ|EV_PERSIST, handldRead, ev);
    event_base_set(base, ev->readEvent);
    event_add(ev->readEvent, NULL);
}

int main(int argc, char* argv[])
{
    struct sockaddr_in serverAddr;
    int sock;

    sock = socket(AF_INET, SOCK_STREAM, 0);
    int on = 1;
    setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(int));
    //memset(&serverAddr, 0, sizeof(serverAddr));
    bzero(&serverAddr, sizeof(serverAddr));
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(PORT);
    serverAddr.sin_addr.s_addr = INADDR_ANY;
    bind(sock, (struct sockaddr*)&serverAddr, sizeof(struct sockaddr));
    listen(sock, BACKLOG);

    struct event listenEvent;
    base = event_base_new();//Create new EventBase
    event_set(&listenEvent, sock, EV_READ|EV_PERSIST, handleAccept, NULL);//conbine listenEvent and  it‘s callback function
    event_base_set(base, &listenEvent);
    event_add(&listenEvent, NULL);
    event_base_dispatch(base);//start base

    return 0;
}
时间: 2024-08-29 07:19:47

libevent源码分析-介绍、安装、使用的相关文章

Libevent源码分析-timer和signal处理

timer处理 Signal处理 timerfd和signalfd timerfd signalfd timer处理 在Libevent源码分析-event处理流程中,使用了定时器,来看一下源码: evtimer_set(&ev, time_cb, NULL);//设置定时器事件 其中evtimer_set是个宏定义 #define evtimer_set(ev, cb, arg) event_set((ev), -1, 0, (cb), (arg)) //event_set原型 void ev

【转】libevent源码分析

libevent源码分析 转自:http://www.cnblogs.com/hustcat/archive/2010/08/31/1814022.html 这两天没事,看了一下Memcached和libevent的源码,做个小总结. 1.入门 1.1.概述Libevent是一个用于开发可扩展性网络服务器的基于事件驱动(event-driven)模型的网络库.Libevent有几个显著的亮点: (1)事件驱动(event-driven),高性能:(2)轻量级,专注于网络,不如 ACE 那么臃肿庞

Libevent源码分析 (1) hello-world

Libevent源码分析 (1) hello-world ⑨月份接触了久闻大名的libevent,当时想读读源码,可是由于事情比较多一直没有时间,现在手头的东西基本告一段落了,我准备读读libevent的源码,凡是我觉得有必要的内容均一一记录,与君共勉. 首先要说说什么是libevent: libevent是一个事件通知库,libevent API提供一种机制使得我们可以在一个文件描述符(file descriptor)发生特定事件时或者timeout发生时执行指定的回调函数.libevent意

libevent源码分析-event

event结构 event相关接口 Libevent对event的管理 event结构 event是Reactor模式中的最重要的组件.它包含了了一个句柄fd,并设置监听这个句柄上的哪些事件(读/写等),设置了对应的函数指针,在事件到来时,回调函数指针来处理事件. 先看一下event的结构.它位于include/event2/event_struct.h中 struct event { TAILQ_ENTRY(event) ev_active_next; TAILQ_ENTRY(event) e

[libevent源码分析] event_init

libevent采用的是经典的reactor网络框架,集成了信号.定时.网络事件于一体 首先对event_init进行源码剖析 event_init 主要创建event_base对象, struct event_base { const struct eventop *evsel; //lievent支持select epoll kequeue..等网络api,包括init.add.del.dispatch的接口,每种网络框架都支持 void *evbase; //支持相应网络api的 结构对象

[libevent源码分析] event_set

libevent使用event来封装网络事件回调,参数.fd...等一些信息,函数很简单 void event_set(struct event *ev, int fd, short events, void (*callback)(int, short, void *), void *arg) { /* Take the current base - caller needs to set the real base later */ ev->ev_base = current_base; /

[libevent源码分析] event_add

event_add 把event往当前event中的ev_base追加,如果需要定时,那么tv不能为空 int event_add(struct event *ev, const struct timeval *tv) { struct event_base *base = ev->ev_base; //event_add 会把event加入到他的ev_base成员里 const struct eventop *evsel = base->evsel; //对应linux的epoll相关函数

[libevent源码分析] event_base_dispatch

分析下事件循环 event_base_dispatch int event_base_dispatch(struct event_base *event_base) { return (event_base_loop(event_base, 0)); } int event_base_loop(struct event_base *base, int flags) { const struct eventop *evsel = base->evsel; void *evbase = base->

libevent源码分析一--io事件响应

这篇文章将分析libevent如何组织io事件,如何捕捉事件的发生并进行相应的操作.这里不会详细分析event与event_base的细节,仅描述io事件如何存储与如何响应. 1.  select libevent的实现io事件的backend实际上使用的是io复用接口,如select, poll, epoll等,这里以最简单的select为例进行说明.首先简单介绍一下select接口: int select(int nfds, fd_set *readfds, fd_set *writefds