使用libevent编写高并发HTTP server
来源:互联网 发布:人工智能带来的问题 编辑:程序博客网 时间:2024/05/18 02:33
http://www.cnblogs.com/keepsimple/archive/2013/05/06/3063251.html
http://blog.csdn.net/liuhongxiangm/article/details/14230763
libevent库使得高并发响应HTTP Server的编写变得很容易。整个过程包括如下几部:初始化,创建HTTP Server, 指定callback, 进入事件循环。另外在回调函数中,可以获取客户端请求(request的HTTP Header和参数等),进行响应的处理,再将结果发送给客户端(response的HTTP Header和内容,如html代码)。
libevent除了设置generic的callback,还可以对特定的请求路径设置对应的callback(回调/处理函数)。
示例代码(方便日后参考编写需要的HTTP server)
#include <stdio.h> #include <stdlib.h> #include <unistd.h> //for getopt, fork #include <string.h> //for strcat //for struct evkeyvalq #include <sys/queue.h> #include <event.h> //for http #include <evhttp.h> #include <signal.h> #define MYHTTPD_SIGNATURE "myhttpd v 0.0.1" //处理模块 void httpd_handler(struct evhttp_request *req, void *arg) { char output[2048] = "\0"; char tmp[1024]; //获取客户端请求的URI(使用evhttp_request_uri或直接req->uri) const char *uri; uri = evhttp_request_uri(req); sprintf(tmp, "uri=%s\n", uri); strcat(output, tmp); sprintf(tmp, "uri=%s\n", req->uri); strcat(output, tmp); //decoded uri char *decoded_uri; decoded_uri = evhttp_decode_uri(uri); sprintf(tmp, "decoded_uri=%s\n", decoded_uri); strcat(output, tmp); //解析URI的参数(即GET方法的参数) struct evkeyvalq params; evhttp_parse_query(decoded_uri, ¶ms); sprintf(tmp, "q=%s\n", evhttp_find_header(¶ms, "q")); strcat(output, tmp); sprintf(tmp, "s=%s\n", evhttp_find_header(¶ms, "s")); strcat(output, tmp); free(decoded_uri); //获取POST方法的数据 char *post_data = (char *) EVBUFFER_DATA(req->input_buffer); sprintf(tmp, "post_data=%s\n", post_data); strcat(output, tmp); /* 具体的:可以根据GET/POST的参数执行相应操作,然后将结果输出 ... */ /* 输出到客户端 */ //HTTP header evhttp_add_header(req->output_headers, "Server", MYHTTPD_SIGNATURE); evhttp_add_header(req->output_headers, "Content-Type", "text/plain; charset=UTF-8"); evhttp_add_header(req->output_headers, "Connection", "close"); //输出的内容 struct evbuffer *buf; buf = evbuffer_new(); evbuffer_add_printf(buf, "It works!\n%s\n", output); evhttp_send_reply(req, HTTP_OK, "OK", buf); evbuffer_free(buf); } void show_help() { char *help = "written by Min (http://54min.com)\n\n" "-l <ip_addr> interface to listen on, default is 0.0.0.0\n" "-p <num> port number to listen on, default is 1984\n" "-d run as a deamon\n" "-t <second> timeout for a http request, default is 120 seconds\n" "-h print this help and exit\n" "\n"; fprintf(stderr, help); } //当向进程发出SIGTERM/SIGHUP/SIGINT/SIGQUIT的时候,终止event的事件侦听循环 void signal_handler(int sig) { switch (sig) { case SIGTERM: case SIGHUP: case SIGQUIT: case SIGINT: event_loopbreak(); //终止侦听event_dispatch()的事件侦听循环,执行之后的代码 break; } } int main(int argc, char *argv[]) { //自定义信号处理函数 signal(SIGHUP, signal_handler); signal(SIGTERM, signal_handler); signal(SIGINT, signal_handler); signal(SIGQUIT, signal_handler); //默认参数 char *httpd_option_listen = "0.0.0.0"; int httpd_option_port = 8080; int httpd_option_daemon = 0; int httpd_option_timeout = 120; //in seconds //获取参数 int c; while ((c = getopt(argc, argv, "l:p:dt:h")) != -1) { switch (c) { case 'l' : httpd_option_listen = optarg; break; case 'p' : httpd_option_port = atoi(optarg); break; case 'd' : httpd_option_daemon = 1; break; case 't' : httpd_option_timeout = atoi(optarg); break; case 'h' : default : show_help(); exit(EXIT_SUCCESS); } } //判断是否设置了-d,以daemon运行 if (httpd_option_daemon) { pid_t pid; pid = fork(); if (pid < 0) { perror("fork failed"); exit(EXIT_FAILURE); } if (pid > 0) { //生成子进程成功,退出父进程 exit(EXIT_SUCCESS); } } /* 使用libevent创建HTTP Server */ //初始化event API event_init(); //创建一个http server struct evhttp *httpd; httpd = evhttp_start(httpd_option_listen, httpd_option_port); evhttp_set_timeout(httpd, httpd_option_timeout); //指定generic callback evhttp_set_gencb(httpd, httpd_handler, NULL); //也可以为特定的URI指定callback //evhttp_set_cb(httpd, "/", specific_handler, NULL); //循环处理events event_dispatch(); evhttp_free(httpd); return 0; }
- 编译:
gcc -o myhttpd -Wall -levent myhttpd.c
- 运行:
./test
- 测试:
在浏览器中输入http://54min.com:8080/index.php?q=test&s=some thing
,显示内容如下:
It works! uri=/index.php?q=test&s=some%20thing uri=/index.php?q=test&s=some%20thing decoded_uri=/index.php?q=test&s=some thing q=test s=some thing post_data=(null)
并使用Live Http Headers(Firefox addons)查看HTTP headers。
HTTP/1.1 200 OK Server: myhttpd v 0.0.1 Content-Type: text/plain; charset=UTF-8 Connection: close Date: Tue, 21 Jun 2011 06:30:30 GMT Content-Length: 72
原文地址:http://www.cnblogs.com/keepsimple/archive/2013/05/06/3063251.html
0 0
- 使用libevent编写高并发HTTP server
- 使用libevent编写高并发HTTP server
- 使用libevent编写高并发HTTP server
- 使用libevent编写高并发HTTP server
- 使用libevent编写高并发HTTP server
- 使用libevent编写高并发HTTP server
- 使用libevent编写高并发HTTP server
- 使用libevent编写高并发HTTP server
- linux c++使用libevent编写http server + http client
- libevent 实现http server
- libevent实现http server
- libevent实现http server
- libevent http server multithread
- libevent 多线程实现高并发
- 使用libevent编写定时器
- 使用libevent实现最简单的android http-server
- 使用libevent实现最简单的android http-server
- http libevent的使用
- CMakeListx.txt 编辑语法学习
- java开发常用工具类
- Fragment中使用listview
- 【图论知识点】【学习笔记】ICM-ICPC程序设计系列-图论及应用——第一章、图【未更新完毕】
- 读书笔记,不定期更新,复习一下基础概念
- 使用libevent编写高并发HTTP server
- sql 优化
- Android动画——Tween动画之Translate
- 彭博士谈伤精与养精 -精有多么重要?
- 【vi】与【vim】编辑器详解
- C++第三次实验—静态成员应用
- App工程结构搭建:几种常见Android代码架构分析
- 1868: UP UP UP:
- js 二分法查找