图解丨在嵌入式设备上实现HTTP服务器
您好呀,我是小二。
本期為大家帶來一個 WiFi 應用的實際場景,其實在之前「我對 WiFi 驅動移植過程,做了一次總結復盤」這篇文章中有簡單提過,但由于內容較多,就單獨摘出來了。
來自讀者的催更????????????,別著急,小二在努力了!
1 應用場景
我喜歡講一個東西,先來探討下他的應用場景。
畢竟知道了用在哪,怎么用,才能寫好代碼嘛,哈哈????
本次項目,實際的應用場景:通過手機 APP ,連接到設備 WiFi 熱點,進行設備的參數配置;
接著結合實際框架,拆分需求如下:
采用 HTTP 協議,使用 POST 方法;
設備端需要作為一個 HTTP 服務器;
不需要支持 CGI ,通過 APP 展示界面即可;
好了,明白了需求,接下來就是實現方案了。
2 方案論證
剛開始的時候,一點頭緒都沒有。
組長指導的一種方案,就是在新唐數據手冊中看到的,采用 Lighttpd 的方案。
后來去查資料,發現一篇介紹不同 HTTP 服務器的文章,挺不錯的,如下
常見的幾種嵌入式web服務器(https://www.cnblogs.com/quliuliu2013/p/12786301.html)
2.1 Lighttpd
這塊剛開始是同事在搞,后來我這邊的需求規劃出來后,就在想能否使用這種方案。
畢竟方案是現成的,可以節省不少時間。
后來經過分析,發現 Lighttpd 需要一個單獨的進程執行,如下圖所示
Lighttpd 提供了 CGI 接口,支持 IE 訪問固定界面,然后進行參數配置。
實際實現方案,我認為比較好的方法是,Lighttpd 進程接收到參數變更時,寫入配置文件 A ,主業務進程監測文件 A 是否有改變,如果檢測到改變,則讀一次數據。
具體實現方式,參考下圖
結合實際情況分析,
1、目前只維護一個主業務進程,如果再增加額外的進程,則維護成本將大大增加。
2、實際不需要 CGI 接口,不需要支持 IE ,APP 做界面顯示即可。
經過論證,此方案較復雜,暫且當做最后的備選方案。
2.2 cpp-httplib
接著我就去 GitHub 上尋找 HTTP Server ,發現 cpp-httplib 這個比較好用的庫。
GitHub 鏈接:cpp-httplib(https://github.com/yhirose/cpp-httplib)
在查看了 ReadMe 文件后,很遺憾,我用不了????????????
提示說 GCC 4.8 及以下版本無法正常編譯,因為 <regex> 文件已損壞。。。
我去找了找解決方法,發現在 GCC 4.9 版本修復了這個問題,參考 Stack Overflow 回答如下
https://stackoverflow.com/questions/12530406/is-gcc-4-8-or-earlier-buggy-about-regular-expressions
沒辦法了,我們當前 GCC 版本是 4.8.3 的,肯定不能因為這個庫就更換編譯器呀,那只能再去找找看咯。
2.3 httpserver
然后就接著去搜索,發現了 httpserver 這個庫,只有一個 .h 頭文件,感覺很簡單。
GitHub 鏈接:httpserver(https://github.com/jeremycw/httpserver.h)
分析本質需求,發現只需要在主進程中,跑一個 HTTP Server 的線程,監聽固定端口,然后采用 HTTP 協議進行通信即可。
簡要功能,如下圖所示
從上圖可以看出
1、主進程中,單獨跑一個 HTTP Server 的線程,監聽固定端口 8888 ;
2、此線程同時進行數據處理,將參數寫入文件 A ;
3、其他業務線程,在需要參數時,直接去文件 A 獲取最新參數即可;
3 實現方式
具體實現方式,參考 ReadMe 文件,也很方便實現。
簡述一下主要流程:
綁定監聽端口號,綁定回調函數;
死循環監聽端口;
當需要關閉 HTTP 服務時,通過 flag 標志位,改變當前狀態;
關閉 HTTP 服務后,需要釋放相應資源;
所有的配置處理接口,在 HandleRequest 回調函數中;
(PS:我這電腦網絡有問題,GitHub 一直打不開,手機熱點也不行,暫時還沒別的好辦法,只能麻煩您自己去網頁上看啦。)
4 注意事項
在使用過程中,我這遇到一個問題。
您看下邊這塊代碼,是這樣的
void?hs_init_session(http_request_t*?session)?{session->flags?=?HTTP_AUTOMATIC;session->parser?=?(http_parser_t){};session->stream?=?(hs_stream_t){};if?(session->tokens.buf)?{free(session->tokens.buf);session->tokens.buf?=?NULL;}http_token_dyn_init(&session->tokens,?32); }在第 3 、4 行末尾,直接就是一個大括號,里邊什么都沒寫。
然后我的程序在這個地方就一直編譯不過去。后來在公司前輩指點下,按照下圖所示,添加了 0 之后,就能編譯通過了。
推測原因是當前編譯器使用的 C 標準,不支持這么高級的用法。
注意:需要修改的不止這一處,其他地方如有編譯報錯,也需做類似修改。
5 總結
針對本次的功能需求,最困難的地方,在于尋找一個合適的 HTTP Serve 庫來使用。
過程雖然艱難,但也鍛煉了自己找東西的能力。
好了各位看官,本次的分享到此結束,如果您還意猶未盡,大可從頭再看。
最后別忘了賞小二一個 贊 和 在看 哦????????????
祝您端午安康,工作順利!
推薦閱讀:
專輯|Linux文章匯總
專輯|程序人生
專輯|C語言
我的知識小密圈
關注公眾號,后臺回復「1024」獲取學習資料網盤鏈接。
歡迎點贊,關注,轉發,在看,您的每一次鼓勵,我都將銘記于心~
嵌入式Linux
微信掃描二維碼,關注我的公眾號
總結
以上是生活随笔為你收集整理的图解丨在嵌入式设备上实现HTTP服务器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 软件测试基础知识总结
- 下一篇: kuangbin专题-简单搜索