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/

沒有留言: