GNU Libmicrohttpd是一個用來在項目中內嵌http服務器的C語言庫,它具備如下幾個很是鮮明的特色:html
這篇文章裏,咱們只編寫一個簡單的靜態服務器,對於用戶的全部請求咱們都只返回同一個html頁面, 該頁面顯示一串字符。windows
爲了使用Libmicrohttpd,咱們須要將其添加進VS項目中。這裏咱們選擇編譯源代碼生成靜態庫,由於官方給的下載靜態庫版本連接在使用時會有問題,多是運行庫版本不一致; 而且在使用靜態庫的狀況下,咱們只須要引用兩個文件就能夠了(一個頭文件、一個庫文件),項目結構不會混亂不清。瀏覽器
實際上Libmicrohttpd的源碼編譯很是簡單,它提供了VS編譯文件,基本上咱們只須要進入w32
目錄,在該目錄下選擇合適的VS子目錄下的sln文件,雙擊打開就能夠了。打開後,修改設置libmicrohttpd項目爲靜態庫項目(記得修改生成文件的後綴名,由於默認是dll),右擊生成就能夠編譯成功了。服務器
生成的文件包括一個頭文件和一個靜態庫文件,新建一個VS控制檯項目,並將它們添加到VS項目中。多線程
main函數很是簡單,核心調用只有2個函數:MHD_start_daemon
,MHD_stop_daemon
,分別開始和中止http服務器。函數
int main() { const int port = 8888; struct MHD_Daemon* daemon = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY, port , NULL, NULL, connectionHandler, NULL, MHD_OPTION_END); if (daemon == NULL) { std::cout << "cannot start server!\n"; return -1; } std::cin.get(); MHD_stop_daemon(daemon); return 0; }
MHD_start_daemon函數包含很是多的參數,這也意味着它集成了不少的功能,這裏咱們只關注四個參數,其它都爲NULL:url
MHD_stop_daemon函數比較簡單,這裏不介紹了。線程
全部的請求處理都發生在connectionHandler
中:code
int connectionHandler( void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls) { const char* pageBuffer = "<html><body>Hello, I'm lgxZJ!</body></html>"; struct MHD_Response *response; response = MHD_create_response_from_buffer(strlen(pageBuffer), (void*)pageBuffer, MHD_RESPMEM_PERSISTENT); if (MHD_add_response_header(response, "Content-Type", "text/html") == MHD_NO) { std::cout << "MHD_add_response_header error\n"; return MHD_NO; } if (MHD_queue_response(connection, MHD_HTTP_OK, response) == MHD_NO) { std::cout << "MHD_queue_response error\n"; return MHD_NO; } MHD_destroy_response(response); return MHD_YES; }
這個函數簽名包含了全部用來處理請求的有用信息,這裏不逐一介紹了。microhttpd庫提供了函數來方便咱們響應請求,這裏咱們重點看建立響應。microhttpd庫提供了兩種方法來建立請求:從buffer建立、從文件建立。可是後者須要傳入一個文件描述符,這在windows上不是很方便。server
咱們這裏用緩衝建立。須要注意的是最後一個參數,這是一個MHD_ResponseMemoryMode
枚舉值,表示咱們使用的buffer內容是固定不變的。這種枚舉類型還包含其餘2種表明瞬時緩衝類型的值,分別表示緩衝區是在heap上的,和非heap(例如stack)上的。 用不一樣的緩衝區時要記得用不一樣的枚舉值。 接下來設置MIME類型,把緩衝入隊,並釋放MHD_Response結構體。對於正確響應,咱們返回MHD_YES;不能響應的,咱們返回MHD_NO。
運行程序,咱們打開瀏覽器並輸入127.0.0.1:8888
,獲得以下結果:
MHD_start_daemon
函數還能夠限制特定ip的訪問。