歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

一個簡單的 C++ 嵌入 Web 服務器

引言

你有一兩個網頁吧?不一定是多麼神奇的東西,但一個通過幾個HTML標簽作出的簡潔的演示就可以。你有一個需要遠程控制的復雜的C++ Windows 桌面應用程序吧?所以,不需要學習一個全新的技術,讓我們一起為您的應用添加WEB頁面吧。

Webem是一個可以嵌入你的C++應用程序的WEB服務器。它可以輕松地實現一個從任何地方都能訪問的浏覽器GUI。

Webem基於一個簡化版的boost::asio WEB服務器,它可以讓HTML代碼執行C++方法。盡管你不需要查看服務器代碼來使用Webem,但你需要為你的工程下載和使用BOOST庫。我建議如果你從未使用過BOOST,那Webem可能不適合你。

源碼下載 - 751.1 KB

------------------------------------------分割線------------------------------------------

免費下載地址在 http://linux.linuxidc.com/

用戶名與密碼都是www.linuxidc.com

具體下載目錄在 /2014年資料/10月/26日/一個簡單的 C++ 嵌入 Web 服務器

下載方法見 http://www.linuxidc.com/Linux/2013-07/87684.htm

------------------------------------------分割線------------------------------------------

C++ 設計新思維》 下載見 http://www.linuxidc.com/Linux/2014-07/104850.htm

C++ Primer Plus 第6版 中文版 清晰有書簽PDF+源代碼 http://www.linuxidc.com/Linux/2014-05/101227.htm

讀C++ Primer 之構造函數陷阱 http://www.linuxidc.com/Linux/2011-08/40176.htm

讀C++ Primer 之智能指針 http://www.linuxidc.com/Linux/2011-08/40177.htm

讀C++ Primer 之句柄類 http://www.linuxidc.com/Linux/2011-08/40175.htm

將C語言梳理一下,分布在以下10個章節中:

  1. Linux-C成長之路(一):Linux下C編程概要 http://www.linuxidc.com/Linux/2014-05/101242.htm
  2. Linux-C成長之路(二):基本數據類型 http://www.linuxidc.com/Linux/2014-05/101242p2.htm
  3. Linux-C成長之路(三):基本IO函數操作 http://www.linuxidc.com/Linux/2014-05/101242p3.htm
  4. Linux-C成長之路(四):運算符 http://www.linuxidc.com/Linux/2014-05/101242p4.htm
  5. Linux-C成長之路(五):控制流 http://www.linuxidc.com/Linux/2014-05/101242p5.htm
  6. Linux-C成長之路(六):函數要義 http://www.linuxidc.com/Linux/2014-05/101242p6.htm
  7. Linux-C成長之路(七):數組與指針 http://www.linuxidc.com/Linux/2014-05/101242p7.htm
  8. Linux-C成長之路(八):存儲類,動態內存 http://www.linuxidc.com/Linux/2014-05/101242p8.htm
  9. Linux-C成長之路(九):復合數據類型 http://www.linuxidc.com/Linux/2014-05/101242p9.htm
  10. Linux-C成長之路(十):其他高級議題

背景

現有的嵌入式C++ web服務器使用起來是一個挑戰,並且有不對Windows友好的趨勢. 它們也不是你想要用來為你的實驗性應用程序加入可以用手機進行監控的能力的那種東西.

我嘗試過 (http://www.webtoolkit.eu/wt) ,但在安裝和學習中挫敗了.

最近我開始使用John Bartas的Webio. 我喜愛其理念,它也運作的很好.

然而,我仍然發現它在使用時過於復雜,並且服務端代碼也難於理解. 我想要的是一個容易使用,基於一個知名web服務器,只做了輕微修改的好東東.

Webio的許多復雜性是有使用一個HTML編譯器來隱藏控制著嵌入於應用程序代碼裡面的文件系統的外觀的HTML頁面所造成的. 我更喜歡將HTML頁面放在外部一個通常的視圖中,那樣我就可以不用重新編譯程序,卻可以調整GUI.

我在嘗試調整Webio以符合自己喜好的過程中了解了很多, 最終決定准備去構建一個能切實滿足我自己的需求的東西. 

代碼使用

你可以像建立網站一樣來建立的你應用程序GUI-從index.html開始使用HTML新建頁面。

現在你需要使HTML調用你的C++方法。你需要做以下三件事:

  • 創建被包含在WEB頁面裡的能生成HTML的include(包含)方法。 

  • 創建當用戶點擊WEB頁面裡的按鈕時被webem調用的action(動作)方法。它們可以是簡單的按鈕,或html表單。

  • 創建"web控件",即上面兩個的組合,一個include方法生成表單,當用戶點擊按鈕時這個表單會調用action方法-示例程序"Calendar"展示了如何創建一個顯示和更新數據表的控件。

"Hello,world!"

第一步:新建web頁面。你可以隨你喜好將頁面設計的很精心,但是對於我們的第一個“hello,world”應用,頁面當然是越簡單越好:

The Webem Embedded Web server says:  <!--#webem hello -->

在尖括號中的文本告訴webem在應用中何處將文本包含進來,“hello”則是指定的應用方法,必需被調用來提供包含的文本。

第二步:新建類,該類返回“hello”:

/// An application class which says hello
class cHello
{
public:
  char * DisplayHTML()
  {
    return "Hello World";
  }
};

第三步:初始化wenem,配置端口和地址來監聽浏覽器請求並且去找到index.html作為web頁面的首頁。

// Initialize web server.
http::server::cWebem theServer(
    "0.0.0.0",        // address
              "1570",          // port
          ".\\");          // document root

第四步:用webem注冊應用方法:

cHello hello;
 
// register application method
// Whenever server sees <!--#webem hello -->
// call cHello::DisplayHTML() and include the HTML returned
 
theServer.RegisterIncludeCode( "hello",
  boost::bind(
  &cHello::DisplayHTML,  // member function
  &hello ) );    // instance of class

第五步:最後,你已經准備好了啟動服務。

// run the server
theServer.Run();

一個正式的Hello

讓我們來創建一個更儒雅的程序,可通過姓名(如CodeProject,Canadian)來定位網絡。

第一步:新建站點:

What is your name, please?
<form action=name.webem>
<input name=yourname /><input value="Enter" type=submit />
</form>
 
The Webem Embedded Web server says: <!--#webem hello -->

該表單提供一個文本域,可以使用戶輸入姓名。另外還有一個提交按鈕將姓名提交給服務器。表單屬性“action=name.webem”確保webem服務器會調用應用通過“name”注冊的方法來處理輸入。

第二步:創建應用類:

/// An application class which says hello to the identified user
 
class cHelloForm
{
string UserName;
http::server::cWebem& myWebem;
 
public:
  cHelloForm( http::server::cWebem& webem ) :
    myWebem( webem )
  {
    myWebem.RegisterIncludeCode( "hello",
    boost::bind(
    &cHelloForm::DisplayHTML,  // member function
    this ) );      // instance of class
    myWebem.RegisterActionCode( "name",
    boost::bind(
    &cHelloForm::Action,  // member function
    this ) );      // instance of class
  }
  char * DisplayHTML()
  {
    static char buf[1000];
    if( UserName.length() )
    sprintf_s( buf, 999,
      "Hello, %s", UserName.c_str() );
    else
      buf[0] = &apos;\0&apos;;
    return buf;
  }
  char * Action()
  {
    UserName = myWebem.FindValue("yourname");
    return "/index.html";
  }
};

這個類存儲了對webem服務器的引用. 它允許在其構建時維護對其自身方法的注冊, 並調用cWebem類的FindValue()來提取輸入表單域中的值.

這個類需要注冊兩個方法,一個在表單提交時保存輸入的用戶名,一個用來在頁面被組合起來發送給浏覽器時展示被存儲的用戶名稱.

動作方法必須返回要在提交按鈕點擊響應中展示的web頁面.

注意所有的動作方法都是有Webem在包含方法之前調用的,所以web頁面總是會展示更新了的數據.

第三步:構建webem,構建應用類並啟動服務器:

// Initialize web server
http::server::cWebem theServer(
  "0.0.0.0",        // address
  "1570",          // port
  ".\\");          // document root
 
// Initialize application code
cHelloForm hello( theServer );
 
// run the server
theServer.Run();

你可能需要在其他線程中啟動服務器,這樣你應用能夠繼續在實驗室裝置中記錄日志數據。為了做到這一點,更改對server::run的調用:

boost::thread* pThread = new boost::thread(
boost::bind(
&http::server::server::run,    // member function
&theServer ) );      // instance of class

Webem 控件

Webem控件是以標准方式監視��示和操作應用數據的細節的類,所以應用程序開發者不需要關注生成HTML文本的所有細節。

示例程序使用一個webem來列出一個SQLITE數據表的所有內容,且提供了添加和刪除記錄的能力。在本文的開始是它的截圖。

更多詳情見請繼續閱讀下一頁的精彩內容: http://www.linuxidc.com/Linux/2014-10/108473p2.htm

Copyright © Linux教程網 All Rights Reserved