The libevent library makes it easy to write highly concurrent responses to HTTP server. The entire process includes the following parts: initialization, creating an HTTP server, specifying callback, and entering the event loop. In addition, the callback function can obtain the client request (the HTTP header and parameters of the request), process the response, and then send the result to the client (the HTTP header and content of the response, such as HTML code ).
In addition to setting the callback of the generic, libevent can also set the corresponding callback (callback/processing function) for a specific request path ).
Sample Code (for more information, see compile the required HTTP server later)
# 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]; // obtain the URI requested by the client (using evhtt P_request_uri or direct 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 ); // parse URI parameters (that is, get method parameters) struct evkeyvalq Params; evhttp_parse_query (decoded_uri, & Params); sprintf (TMP, "q = % s \ n", evhttp_find_header (& Params, "Q"); strcat (output, TMP); sprintf (TMP, "s = % s \ n", evhttp_find_header (& Params, "S"); strcat (output, TMP); free (decoded_uri ); // obtain the data of the POST method char * post_data = (char *) evbuffer_data (req-> input_buffer); sprintf (TMP, "post_data = % s \ n", post_data ); strcat (output, TMP);/* Specific: You can perform the corresponding operation according to the get/post parameter, and then output the result... * // * output to the client * // HTTP header EV Http_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"); // output content 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" "-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 "; FP Rintf (stderr, help);} // when sigterm/sighup/SIGINT/sigquit is sent to the process, the event listening loop void signal_handler (INT sig) {Switch (SIG) {Case sigterm: Case sighup: Case sigquit: Case SIGINT: event_loopbreak (); // terminate the event listening loop listening for event_dispatch, code break after execution;} int main (INT argc, char * argv []) {// custom signal processing function signal (sighup, signal_handler); signal (sigterm, signal_handler); signal (SIGINT, signal_handler); signal (Si Gquit, signal_handler); // default parameter 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 // get the 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 );}} // determine whether-D is set and run if (httpd_option_daemon) {pid_t PID; pid = fork (); If (PID <0) with daemon) {perror ("fork failed"); exit (exit_failure);} If (pid> 0) {// child process generated successfully, exit parent process exit (exit_success );}} /* use libevent to create HTTP server * // initialize event API event_init (); // create an HTTP server struct evhttp * httpd; httpd = evhttp_start (httpd_option_listen, httpd_option_port ); evhttp_set_timeout (httpd, callback); // specify generic callback evhttp_set_gencb (httpd, httpd_handler, null); // You can also specify callback // evhttp_set_cb (httpd, httpd, "/", specific_handler, null); // cyclically process events event_dispatch (); evhttp_free (httpd); Return 0 ;}
- Compile:
gcc -o myhttpd -Wall -levent myhttpd.c
- Run:
./test
- Test:
Enterhttp://54min.com:8080/index.php?q=test&s=some thing, The content is as follows:
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)
Use live HTTP headers (Firefox Addons) to view 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
Address: http://www.cnblogs.com/keepsimple/archive/2013/05/06/3063251.html