第二章 C语言实例 —制作http服务器 - dennis - ITeye技术网站
任务:
1.制作http服务器,读取url提交的相关数据.
2.把读到的数据推入到队列中.
条件:
使用libevent的类库,所以先安装libevent
- tar zxvf libevent-2.0.12-stable.tar.gz
- cd libevent-2.0.12-stable/
- ./configure --prefix=/usr/local/libevent-2.0.12-stable/
- make
- make install
- cd ../
1.服务端简易代码如下
- #include <stdio.h>
- #include <stdlib.h>
- #include <err.h>
- #include <event.h>
- #include <evhttp.h>
- void http_handle(struct evhttp_request *req, void *arg); /* HTTP Request Handle */
- int main(){
- struct evhttp *httpd;
- event_init();
- httpd = evhttp_start("0.0.0.0", 2345);
- if (httpd == NULL) {
- fprintf(stderr, "Error: Unable to listen on %s:%d\n\n");
- exit(1);
- }
- evhttp_set_timeout(httpd, 2000);
- evhttp_set_gencb(httpd, http_handle, NULL);
- event_dispatch();
- evhttp_free(httpd);
- return 0;
- }
- void http_handle(struct evhttp_request *req, void *arg){
- struct evbuffer *buf;
- buf = evbuffer_new();
- /* Response the client */
- evhttp_send_reply(req, HTTP_OK, "OK", buf);
- //evbuffer_add_printf(buf, "%s", "HTTPSQS_AUTH_FAILED");
- /* Release the memory */
- evbuffer_free(buf);
- fprintf(stderr,"Send \n");
- }
编译:(编译时把libevent的类库中的.so文件和.h文件连接
进来)
- gcc http.c -L/usr/local/libevent-2.0.12-stable/lib/ -levent -I/usr/local/libevent-2.0.12-stable/include/
测试
在服务器端,执行编译后的文件a.out
- ./a.out
客户端进行访问(也可以使用浏览器访问,但是要打开端口号2345——vi /etc/sysconfig/iptables)
- [www@zhoubc data]$Snbsp;curl http://127.0.0.1:2345
此时再看服务端,变成如下状态
- [www@zhoubc queue]$Snbsp;./a.out
- Send
2.处理http请求,重写htt_handle方法
- void http_handle(struct evhttp_request *req, void *arg){
- struct evbuffer *buf;
- buf = evbuffer_new();
- /* Analyst the URI */
- char *decode_uri = strdup((char*) evhttp_request_uri(req));
- struct evkeyvalq http_query;
- evhttp_parse_query(decode_uri, &http_query);
- free(decode_uri);
- /* URI Parameter */
- const char *http_input_opt = evhttp_find_header (&http_query, "opt"); /* Operation Type */
- const char *http_input_name = evhttp_find_header (&http_query, "name"); /* Queue Name */
- const char *http_input_data = evhttp_find_header (&http_query, "data"); /* Data With GET */
- /* header */
- evhttp_add_header(req->output_headers, "Content-Type", "text/plain");
- evhttp_add_header(req->output_headers, "Connection", "keep-alive");
- evhttp_add_header(req->output_headers, "Cache-Control", "no-cache");
- evhttp_add_header(req->output_headers, "author", "Dennis .Z Ritchie");
- if(http_input_opt != NULL && http_input_name != NULL && strlen(http_input_name) < 300){
- /* GET Method,OUT The Queue */
- if(strcmp(http_input_opt,"put") == 0){
- int buffer_data_len = EVBUFFER_LENGTH(req->input_buffer);
- if(buffer_data_len > 0){ /* POST METHOD */
- char *input_value_data = EVBUFFER_DATA(req->input_buffer); /* Submited Data */
- fprintf(stderr,"%s \n",input_value_data);
- }else if(http_input_data != NULL){
- fprintf(stderr,"%s \n",http_input_data);
- }
- }else if(strcmp(http_input_opt,"get") == 0){
- }
- }
- /* Response the client */
- evhttp_send_reply(req, HTTP_OK, "OK", buf);
- //evbuffer_add_printf(buf, "%s", "HTTPSQS_AUTH_FAILED");
- /* Release the memory */
- evhttp_clear_headers(&http_query);
- evbuffer_free(buf);
- }