哪家公司可以做网站,网站构建建设案例展示,尚层装饰,wordpress启用收费下载无效libevent是一个基于事件触发的网络库#xff0c;memcached底层也是使用libevent库#xff0c;今天学习下。总体来说#xff0c;libevent有下面一些特点和优势#xff1a;* 统一数据源#xff0c; 统一I/O事件#xff0c;信号和定时器这三种事件#xff1b;* 可移植…libevent是一个基于事件触发的网络库memcached底层也是使用libevent库今天学习下。总体来说libevent有下面一些特点和优势* 统一数据源 统一I/O事件信号和定时器这三种事件* 可移植跨平台支持多种I/O多路复用技术 epoll、poll、dev/poll、select 和kqueue 等 * 对并发编程支持避免竞态条件
* 高性能由事件驱动* 轻量级专注于网络 libevent有下面几大部分组成 * 事件管理包括各种IOsocket、定时器、信号等事件也是libevent应用最广的模块 * 缓存管理是指evbuffer功能 * DNS是libevent提供的一个异步DNS查询功能 * HTTP是libevent的一个轻量级http实现包括服务器和客户端 一些资料 * libevent官网http://libevent.org/ * libevent APIhttp://www.monkey.org/~provos/libevent/doxygen-2.0.1/index.html * CSDN上剖析得很赞的文章http://blog.csdn.net/sparkliang/article/details/4957667 // 下面写了2个简单的使用例子一个是定时器一个是TCP服务器都只涉及到libevent的事件管理模块。 一、简单定时器实现程序每秒输出一个“Game Over!” event_init() evtimer_set() event_add() event_dispatch() [cpp] view plaincopy #include stdio.h #include iostream // libevent头文件 #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 evTime; // 设置定时事件 evtimer_set(evTime, onTime, evTime); struct timeval tv; tv.tv_sec 1; tv.tv_usec 0; // 添加定时事件 event_add(evTime, tv); // 事件循环 event_dispatch(); return 0; } 编译并执行编译加 -levent[cpp] view plaincopy gapp_devnet_1:/data/home/andyawang/code/2013_11/LibeventTest # mv time.cpp timer.cpp gapp_devnet_1:/data/home/andyawang/code/2013_11/LibeventTest # g -o timer timer.cpp -levent gapp_devnet_1:/data/home/andyawang/code/2013_11/LibeventTest # ./timer Game Over! Game Over! Game Over! Game Over! 二、TCP服务器
实现监听本机8888端口并输出客户端发送过来的信息 event_base_new()event_set()event_base_set()event_add()event_base_dispatch() [cpp] view plaincopy #include stdio.h #include string.h #include iostream #include sys/socket.h #include netinet/in.h #include arpa/inet.h #include netdb.h #include event.h using namespace std; // 事件base struct event_base* base; // 读事件回调函数 void onRead(int iCliFd, short iEvent, void *arg) { int iLen; char buf[1500]; iLen recv(iCliFd, buf, 1500, 0); if (iLen 0) { cout Client Close endl; // 连接结束(0)或连接错误(0)将事件删除并释放内存空间 struct event *pEvRead (struct event*)arg; event_del(pEvRead); delete pEvRead; close(iCliFd); return; } buf[iLen] 0; cout Client Info: buf endl; } // 连接请求事件回调函数 void onAccept(int iSvrFd, short iEvent, void *arg) { int iCliFd; struct sockaddr_in sCliAddr; socklen_t iSinSize sizeof(sCliAddr); iCliFd accept(iSvrFd, (struct sockaddr*)sCliAddr, iSinSize); // 连接注册为新事件 (EV_PERSIST为事件触发后不默认删除) struct event *pEvRead new event; event_set(pEvRead, iCliFd, EV_READ|EV_PERSIST, onRead, pEvRead); event_base_set(base, pEvRead); event_add(pEvRead, NULL); } int main() { int iSvrFd; struct sockaddr_in sSvrAddr; memset(sSvrAddr, 0, sizeof(sSvrAddr)); sSvrAddr.sin_family AF_INET; sSvrAddr.sin_addr.s_addr inet_addr(127.0.0.1); sSvrAddr.sin_port htons(8888); // 创建tcpSocketiSvrFd监听本机8888端口 iSvrFd socket(AF_INET, SOCK_STREAM, 0); bind(iSvrFd, (struct sockaddr*)sSvrAddr, sizeof(sSvrAddr)); listen(iSvrFd, 10); // 初始化base base event_base_new(); struct event evListen; // 设置事件 event_set(evListen, iSvrFd, EV_READ|EV_PERSIST, onAccept, NULL); // 设置为base事件 event_base_set(base, evListen); // 添加事件 event_add(evListen, NULL); // 事件循环 event_base_dispatch(base); return 0; } 三. HTTP服务器 C代码 #include stdio.h #include stdlib.h #include unistd.h #include event.h #include evhttp.h void reqHandler(struct evhttp_request *req,void *arg) { struct evbuffer *buf evbuffer_new(); // 发送响应 evbuffer_add_printf(buf, Thanks for the request); evhttp_send_reply(req,HTTP_OK,Client,buf); evbuffer_free(buf); return; } void http_handle(struct evhttp_request* req, void* arg) { struct evbuffer* buffer evbuffer_new(); // 获取客户端请求的URL const char* url; url evhttp_request_uri(req); evbuffer_add_printf(buffer, url %s\n, url); // 解析url的参数(即GET方法的参数) struct evkeyvalq params; evhttp_parse_query(url, params); evbuffer_add_printf(buffer, a %s\n, evhttp_find_header(params, a)); evbuffer_add_printf(buffer, b %s\n, evhttp_find_header(params, b)); // 设置HTTP表头 evhttp_add_header(req-output_headers, Server, mytest http server 0.1); evhttp_add_header(req-output_headers, Content-Type, text/plain;charsetUTF-8); evhttp_add_header(req-output_headers, Connection, close); // 返回数据 evhttp_send_reply(req, HTTP_OK, OK, buffer); evbuffer_free(buffer); } int main(int argc,char **argv) { short port 8000; const char *addr 192.168.1.11; struct evhttp *httpserv NULL; event_init(); // 启动http服务 httpserv evhttp_start(addr,port); // 设置回调 evhttp_set_gencb(httpserv, reqHandler,NULL); printf(Server started on port %d\n,port); event_dispatch(); return 0; } 浏览器访问: http://192.168.1.11:8000 会显示 Thanks for the request #include stdio.h #include stdlib.h #include unistd.h #include event.h #include evhttp.h void reqHandler(struct evhttp_request *req,void *arg) { struct evbuffer *buf evbuffer_new(); // 发送响应 evbuffer_add_printf(buf, Thanks for the request); evhttp_send_reply(req,HTTP_OK,Client,buf); evbuffer_free(buf); return; } void http_handle(struct evhttp_request* req, void* arg) { struct evbuffer* buffer evbuffer_new(); // 获取客户端请求的URL const char* url; url evhttp_request_uri(req); evbuffer_add_printf(buffer, url %s\n, url); // 解析url的参数(即GET方法的参数) struct evkeyvalq params; evhttp_parse_query(url, params); evbuffer_add_printf(buffer, a %s\n, evhttp_find_header(params, a)); evbuffer_add_printf(buffer, b %s\n, evhttp_find_header(params, b)); // 设置HTTP表头 evhttp_add_header(req-output_headers, Server, mytest http server 0.1); evhttp_add_header(req-output_headers, Content-Type, text/plain;charsetUTF-8); evhttp_add_header(req-output_headers, Connection, close); // 返回数据 evhttp_send_reply(req, HTTP_OK, OK, buffer); evbuffer_free(buffer); } int main(int argc,char **argv) { short port 8000; const char *addr 192.168.1.11; struct evhttp *httpserv NULL; event_init(); // 启动http服务 httpserv evhttp_start(addr,port); // 设置回调 evhttp_set_gencb(httpserv, reqHandler,NULL); printf(Server started on port %d\n,port); event_dispatch(); return 0; }