程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 基於Libevent的HTTP Server

基於Libevent的HTTP Server

編輯:C++入門知識

簡單的Http Server

使用Libevent內置的http相關接口,可以很容易的構建一個Http Server,一個簡單的Http Server如下:

#include <event2/.h><event2/buffer.h><event2/http.h><Winsock2.h><stdlib.h><stdio.h>

(WSAStartup(MAKEWORD(,) , &wsaData) !=  -  generic_handler( evhttp_request *req,  * evbuffer *buf =(! main( argc, *

              http_port =           *http_addr =  event_base *  = evhttp * http_server = evhttp_new((! - ret =(ret!= - 

通過Libevent的接口構建一個Http Server的過程如下:

(1)初始化:在event_base上新建一個evhttp,將這個evhttp綁定到監聽的IP和端口號。

(2)設置Http回調函數:使用evhttp_set_gencb設置Http Server的處理請求的回調函數。

(3)啟動Http Server:等待請求進入事件循環。

在Http Server中使用定時器提供更新服務

#include <event2/.h><event2/buffer.h><event2/http.h><sys/stat.h><Winsock2.h><assert.h><.h><stdlib.h><stdio.h>

 DEFAULT_FILE "F:\\Libevent\\LibeventTest\\Debug\\sample.txt"

 *=  filename[ counter =   * size =  *(stat(filename,&buf)< (buf.st_mtime > (counter++*f = fopen(filename,  (f ==== ( *)malloc(size+,size+(= read_file_timer_cb(evutil_socket_t listener,  ,  * (!& load_file( event_base * = = 
    loadfile_event = evtimer_new(
    evtimer_add(loadfile_event,& generic_handler( evhttp_request *req,  * evbuffer *buf =(!(WSAStartup(MAKEWORD(,) , &wsaData) !=  -  main( argc, *

              http_port =           *http_addr =  (argc >  event_base *  = evhttp * http_server = evhttp_new((! - ret =(ret!= - 

在這個Http Server中提供了一個每5秒觸發一次的定時器,讀取一個文件,如果這個文件被更新過,則讀取更新後的內容。

當訪問這個Http Server時,提供這個文件中最新的內容。

多線程的Http Server

在上面的Http Server中,處理Http請求的回調函數generic_handler和定時器讀取文件的回調函數read_file_timer_cb都在同一個event_base的dispatch中,並且都在同一個進程中,使用多線程可以改善程序的性能,下面是一個來自網絡的多線程Http Server:

#include <.h><evhttp.h><pthread.h><errno.h><.h><fcntl.h><sys/socket.h><sys/types.h><netinet/.h>
 
 httpserver_bindsocket( port,  httpserver_start( port,  nthreads, * httpserver_Dispatch( * httpserver_GenericHandler( evhttp_request *req,  * httpserver_ProcessRequest( evhttp_request * httpserver_bindsocket( port, = socket(AF_INET, SOCK_STREAM,  (nfd < )  - one = = setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, ( *)&one, (&addr, , ==== bind(nfd, ( sockaddr*)&addr,  (r < )  -= (r < )  - ((flags = fcntl(nfd, F_GETFL, )) < 
      || fcntl(nfd, F_SETFL, flags | O_NONBLOCK) <  - httpserver_start( port,  nthreads,  nfd = (nfd < )  - (i = ; i < nthreads; i++ event_base * = ( == NULL)  - evhttp *httpd = evhttp_new( (httpd == NULL)  -= (r != )  -= pthread_create(&ths[i], NULL, httpserver_Dispatch,  (r != )  - (i = ; i < nthreads; i++* httpserver_Dispatch( * event_base* httpserver_GenericHandler( evhttp_request *req,  * httpserver_ProcessRequest( evhttp_request * evbuffer *buf = (buf == NULL) 
 main(, , 

上面的代碼基於Libevent 1.X版本的,不過很容易很看懂:在一個監聽socket上創建了多個event_base實例和evhttp實例,在不同的線程中調度不同的event_base,繼而可以在不同的線程中處理http請求。

這裡還有一個基於Libevent的多線程Http Server:https://sourceforge.net/projects/libevent-thread/,看源代碼處理的過程和上面類似,只是每次在監聽的socket上accept一個連接請求時,將對應的處理放到一個工作隊列裡,在隊列裡由多線程處理相應的回調函數。

 

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved