使用Libmicrohttpd搭建內(nèi)嵌(本地)服務(wù)器的方法
Libmicrohttpd簡(jiǎn)介
GNU Libmicrohttpd是一個(gè)用來(lái)在項(xiàng)目中內(nèi)嵌http服務(wù)器的C語(yǔ)言庫(kù),它具有以下幾個(gè)非常鮮明的特點(diǎn):
C語(yǔ)言庫(kù),小而快。
API非常簡(jiǎn)單,且都是可重入的。
兼容HTTP1.1。
支持4種多線程模型(select、poll、pthread、thread poll)。
跨平臺(tái)。
生成的二制文件只有32K(不包含TLS/SSL等額外功能)。
搭建一個(gè)簡(jiǎn)單的本地靜態(tài)服務(wù)器
這篇文章里,我們只編寫(xiě)一個(gè)簡(jiǎn)單的靜態(tài)服務(wù)器,對(duì)于用戶的所有請(qǐng)求我們都只返回同一個(gè)html頁(yè)面, 該頁(yè)面顯示一串字符。
1. 下載Libmicrohttpd,編譯后添加進(jìn)VS項(xiàng)目
為了使用Libmicrohttpd,我們需要將其添加進(jìn)VS項(xiàng)目中。這里我們選擇編譯源代碼生成靜態(tài)庫(kù),因?yàn)楣俜浇o的下載靜態(tài)庫(kù)版本鏈接在使用時(shí)會(huì)有問(wèn)題,可能是運(yùn)行庫(kù)版本不一致; 并且在使用靜態(tài)庫(kù)的情況下,我們只需要引用兩個(gè)文件就可以了(一個(gè)頭文件、一個(gè)庫(kù)文件),項(xiàng)目結(jié)構(gòu)不會(huì)混亂不清。
實(shí)際上Libmicrohttpd的源碼編譯非常簡(jiǎn)單,它提供了VS編譯文件,基本上我們只需要進(jìn)入<>w32
目錄,在該目錄下選擇合適的VS子目錄下的sln文件,雙擊打開(kāi)就可以了。打開(kāi)后,修改設(shè)置libmicrohttpd項(xiàng)目為靜態(tài)庫(kù)項(xiàng)目(記得修改生成文件的后綴名,因?yàn)槟J(rèn)是dll),右擊生成就可以編譯成功了。
生成的文件包括一個(gè)頭文件和一個(gè)靜態(tài)庫(kù)文件,新建一個(gè)VS控制臺(tái)項(xiàng)目,并將它們添加到VS項(xiàng)目中。
2. main函數(shù)
main函數(shù)非常簡(jiǎn)單,核心調(diào)用只有2個(gè)函數(shù):<>MHD_start_daemon
,MHD_stop_daemon
,分別開(kāi)始和停止http服務(wù)器。
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函數(shù)包含非常多的參數(shù),這也意味著它集成了很多的功能,這里我們只關(guān)注四個(gè)參數(shù),其它都為NULL:
MHD_USE_INTERNAL_POLpNG_THREAD。這個(gè)參數(shù)與其他兩個(gè)參數(shù)(MHD_USE_POLL_INTERNAL_THREAD、MHD_USE_EPOLL_INTERNAL_THREAD)一起構(gòu)成了microhttpd支持的三種模式:select、poll、epoll。用戶必須選擇這三種模式之一。具體信息見(jiàn)源碼。
port。端口號(hào)。
connectHandler。處理請(qǐng)求的函數(shù)。
MHD_OPTION_END。由于MHD_start_daemon最后一個(gè)參數(shù)是一個(gè)變參,因此MHD_OPTION_END用來(lái)表示變參終止。
MHD_stop_daemon函數(shù)比較簡(jiǎn)單,這里不介紹了。
3 請(qǐng)求處理函數(shù)
所有的請(qǐng)求處理都發(fā)生在<>connectionHandler
中:
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; }
這個(gè)函數(shù)簽名包含了所有用來(lái)處理請(qǐng)求的有用信息,這里不逐一介紹了。microhttpd庫(kù)提供了函數(shù)來(lái)方便我們響應(yīng)請(qǐng)求,這里我們重點(diǎn)看創(chuàng)建響應(yīng)。microhttpd庫(kù)提供了兩種方法來(lái)創(chuàng)建請(qǐng)求:從buffer創(chuàng)建、從文件創(chuàng)建。但是后者需要傳入一個(gè)文件描述符,這在windows上不是很方便。
我們這里用緩沖創(chuàng)建。需要注意的是最后一個(gè)參數(shù),這是一個(gè)<>MHD_ResponseMemoryMode
枚舉值,表示我們使用的buffer內(nèi)容是固定不變的。這種枚舉類(lèi)型還包含其他2種代表瞬時(shí)緩沖類(lèi)型的值,分別表示緩沖區(qū)是在heap上的,和非heap(例如stack)上的。 用不同的緩沖區(qū)時(shí)要記得用不同的枚舉值。 接下來(lái)設(shè)置MIME類(lèi)型,把緩沖入隊(duì),并釋放MHD_Response結(jié)構(gòu)體。對(duì)于正確響應(yīng),我們返回MHD_YES;不能響應(yīng)的,我們返回MHD_NO。
運(yùn)行程序,我們打開(kāi)瀏覽器并輸入<>127.0.0.1:8888
,得到如下結(jié)果:
還能做更多
MHD_start_daemon
函數(shù)還可以限制特定ip的訪問(wèn)。
請(qǐng)求處理函數(shù)還包含請(qǐng)求方法和請(qǐng)求數(shù)據(jù)。
我們還可以掛起、恢復(fù)連接。
以上這篇使用Libmicrohttpd搭建內(nèi)嵌(本地)服務(wù)器的方法就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持我們。
上一篇:C語(yǔ)言實(shí)現(xiàn)動(dòng)態(tài)順序表的實(shí)現(xiàn)代碼
欄 目:C語(yǔ)言
下一篇:C語(yǔ)言實(shí)現(xiàn)單鏈表實(shí)現(xiàn)方法
本文標(biāo)題:使用Libmicrohttpd搭建內(nèi)嵌(本地)服務(wù)器的方法
本文地址:http://mengdiqiu.com.cn/a1/Cyuyan/1263.html
您可能感興趣的文章
- 04-02func函數(shù)+在C語(yǔ)言 func函數(shù)在c語(yǔ)言中
- 01-10使用OpenGL實(shí)現(xiàn)3D立體顯示的程序代碼
- 01-10使用C++實(shí)現(xiàn)全排列算法的方法詳解
- 01-10深入Main函數(shù)中的參數(shù)argc,argv的使用詳解
- 01-10C++大數(shù)模板(推薦)
- 01-10淺談C/C++中的static與extern關(guān)鍵字的使用詳解
- 01-10基于C語(yǔ)言fflush()函數(shù)的使用詳解
- 01-10linux c 查找使用庫(kù)的cflags與libs的方法詳解
- 01-10深入sizeof的使用詳解
- 01-10基于c中使用ftruncate()前需要fflush(),使用后需要rewind()的深入探討


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹(shù)的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問(wèn)題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 04-02c語(yǔ)言函數(shù)調(diào)用后清空內(nèi)存 c語(yǔ)言調(diào)用
- 04-02func函數(shù)+在C語(yǔ)言 func函數(shù)在c語(yǔ)言中
- 04-02c語(yǔ)言的正則匹配函數(shù) c語(yǔ)言正則表達(dá)
- 04-02c語(yǔ)言用函數(shù)寫(xiě)分段 用c語(yǔ)言表示分段
- 04-02c語(yǔ)言中對(duì)數(shù)函數(shù)的表達(dá)式 c語(yǔ)言中對(duì)
- 04-02c語(yǔ)言編寫(xiě)函數(shù)冒泡排序 c語(yǔ)言冒泡排
- 04-02c語(yǔ)言沒(méi)有round函數(shù) round c語(yǔ)言
- 04-02c語(yǔ)言分段函數(shù)怎么求 用c語(yǔ)言求分段
- 04-02C語(yǔ)言中怎么打出三角函數(shù) c語(yǔ)言中怎
- 04-02c語(yǔ)言調(diào)用函數(shù)求fibo C語(yǔ)言調(diào)用函數(shù)求
隨機(jī)閱讀
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 01-10SublimeText編譯C開(kāi)發(fā)環(huán)境設(shè)置
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
- 01-10delphi制作wav文件的方法
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
- 04-02jquery與jsp,用jquery
- 01-11Mac OSX 打開(kāi)原生自帶讀寫(xiě)NTFS功能(圖文
- 01-10C#中split用法實(shí)例總結(jié)
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改