1. 程式人生 > >libevent源碼分析-介紹、安裝、使用

libevent源碼分析-介紹、安裝、使用

ont write net clas pretty string his har oot

  • 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 811 00:04 libevent-2.0.so.5 -> libevent-2.0.so.5.1.9 -rwxr-xr-x 1 root root 920932 811 00:04 libevent-2.0.so.5.1.9 -rw-r--r-- 1 root root 1309268 811 00:04 libevent.a lrwxrwxrwx 1 root root 26 811 00:04 libevent_core-2.0.so.5 -> libevent_core-2.0.so.5
.1.9 -rwxr-xr-x 1 root root 557242 811 00:04 libevent_core-2.0.so.5.1.9 -rw-r--r-- 1 root root 821804 811 00:04 libevent_core.a -rwxr-xr-x 1 root root 974 811 00:04 libevent_core.la lrwxrwxrwx 1 root root 26 811 00:04 libevent_core.so -> libevent_core-2.0.so.5.1.9 lrwxrwxrwx 1 root root 27 811 00:04 libevent_extra-2.0.so.5 -> libevent_extra-2.0.so.5.1.9 -rwxr-xr-x 1 root root 379504 811 00:04 libevent_extra-2.0.so.5.1.9 -rw-r--r-- 1 root root 487536 811 00:04 libevent_extra.a -rwxr-xr-x 1 root root 981 811 00:04 libevent_extra.la lrwxrwxrwx 1 root root 27 811 00:04 libevent_extra.so -> libevent_extra-2.0.so.5.1.9 -rwxr-xr-x 1 root root 939 811 00:04 libevent.la lrwxrwxrwx 1 root root 29 811 00:04 libevent_openssl-2.0.so.5 -> libevent_openssl-2.0.so.5.1.9 -rwxr-xr-x 1 root root 90317 811 00:04 libevent_openssl-2.0.so.5.1.9 -rw-r--r-- 1 root root 110340 811 00:04 libevent_openssl.a -rwxr-xr-x 1 root root 1010 811 00:04 libevent_openssl.la lrwxrwxrwx 1 root root 29 811 00:04 libevent_openssl.so -> libevent_openssl-2.0.so.5.1.9 lrwxrwxrwx 1 root root 30 811 00:04 libevent_pthreads-2.0.so.5 -> libevent_pthreads-2.0.so.5.1.9 -rwxr-xr-x 1 root root 20571 811 00:04 libevent_pthreads-2.0.so.5.1.9 -rw-r--r-- 1 root root 14322 811 00:04 libevent_pthreads.a -rwxr-xr-x 1 root root 1002 811 00:04 libevent_pthreads.la lrwxrwxrwx 1 root root 30 811 00:04 libevent_pthreads.so -> libevent_pthreads-2.0.so.5.1.9 lrwxrwxrwx 1 root root 21 811 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;
}

libevent源碼分析-介紹、安裝、使用