2008年8月14日 星期四

An event notification library - libevent

libevent
The libevent API provides a mechanism to execute a callback function when a specific event occurs on a file descriptor or after a timeout has been reached. Furthermore, libevent also support callbacks due to signals or regular timeouts.
libevent is meant to replace the event loop found in event driven network servers. An application just needs to call event_dispatch() and then add or remove events dynamically without having to change the event loop.
簡單的講就是可以變成事件驅動的方式寫程式

1. 從官網下載libevent的tarball後
2. ./configure && make && make install
3. echo "/usr/local/lib" >> /etc/ld.so.conf
4. ldconfig
5. 下載下面那個範例程式就可以試玩囉!

然後可以下載http://www.zhongguowen.com/demo/fhttpd/fhttpd.tar.gz
基於libevent的http server程式碼如下:

/**
* http server example, supported by libevent
*
* @autor lowellzhong<at>gmail<dot>com
* @website http://www.zhongguowen.com/
*/
#include <stdio.h>
#include <event.h>
#include <evhttp.h>


void fhttpd_gencb(struct evhttp_request * evreq, void * arg);


int main(int argc, char** argv)
{
struct event_base *evbase = NULL;
struct evhttp *evhttp = NULL;
unsigned short port = 8080;
const char *host = "0.0.0.0";


/* 1). event initialization */
evbase = event_init();
if(NULL == evbase)
{
perror("event_base_new");
return 1;
}


/* 2). event http initialization */
evhttp = evhttp_new(evbase);
if(NULL == evhttp)
{
perror("evhttp_new");
return 2;
}


/* 3). set general callback of http request */
evhttp_set_gencb(evhttp, &fhttpd_gencb, NULL);


/* 4). bind socket */
if(0 != evhttp_bind_socket(evhttp, host, port))
{
perror("evhttp_bind_socket");
return 3;
}
fprintf(stderr, "http server is running (%s:%d)\n", host, port);


/* 5). start http server */
if(0 == event_base_dispatch(evbase))
{
perror("event_base_dispatch");
return 4;
}


/* 6). free resource before exit */
evhttp_free(evhttp);
event_base_free(evbase);


return 0;
}


void fhttpd_gencb(struct evhttp_request * evreq, void * arg)
{
struct evbuffer *evbuff = NULL;


fprintf(stderr, "[%s] %s\n", evreq->remote_host, evreq->uri);


/* create a evbuffer variable for response */
evbuff = evbuffer_new();
if(NULL == evbuff)
{
perror("evbuffer_new");
return;
}


/* store response html in evbuffer */
evbuffer_add_printf(
evbuff,
"<html>\n<meta http-equiv=\"Content-Type\" content=\"text/html;"
"charset=GB2312\" />\n<head>\n<title>Welcome %s</title>\n</head>\n<body>\n"
"<h1>Welcome %s</h1>\n<p>your ip:%s, port %d</p>\n"
"<p>request uri: %s</p>\n<p><a href=\"<A href='http://wwww.zhongguowen.com\">www.zhongguowen.com</a></p></body>\n</html>",
evreq->remote_host, evreq->remote_host, evreq->remote_host,
evreq->remote_port, evreq->uri
);


/* change response charset, 'text/html; charset=ISO-8859-1' by default */
evhttp_add_header(evreq->output_headers, "Content-Type", "text/html; charset=GB2312");

/* send response html to client */
evhttp_send_reply(evreq, HTTP_OK, "", evbuff);


/* don't forget to release evbuffer */
evbuffer_free(evbuff);
}

browser連接上的執行結果

但也有人說libevent不好,要改用libev@@
libev官網如下:http://software.schmorp.de/pkg/libev.html

資料及參考來源:
libevent
http://www.monkey.org/~provos/libevent/
Gea-Suan Lin's Blog
http://blog.gslin.org/archives/2005/11/24/220/
羅威爾的博客 - 基於libevent的http server範例
http://www.zhongguowen.com/blog/?p=142
有簡易版DNS及http server的程式碼
http://unx.ca/log/2006/10/17/new-libevent-dns-and-http-support/

沒有留言:

一個小故事讓我們明白資金流通的意義

“又是炎熱小鎮慵懶的一天。太陽高掛,街道無人,每個人都債台高築,靠信用度日。這時,從外地來了一位有錢的旅客,他進了一家旅館,拿出一張1000 元鈔票放在櫃檯,說想先看看房間,挑一間合適的過夜,就在此人上樓的時候---- 店主抓了這張1000 元鈔,跑到隔壁屠戶那裡支付了他欠的肉錢...