1. 程式人生 > >跨平臺網路通訊與伺服器程式設計框架庫(acl庫)介紹

跨平臺網路通訊與伺服器程式設計框架庫(acl庫)介紹

一、描述

acl 工程是一個跨平臺(支援LINUX,WIN32,Solaris,MacOS,FreeBSD)的網路通訊庫及伺服器程式設計框架,同時提供更多的實用功能庫。通過該庫,使用者可以非常容易地編寫支援多種模式(多執行緒、多程序、非阻塞、觸發器、UDP方式)的伺服器程式,WEB 應用程式,資料庫應用程式。此外,該庫還提供了常見應用的客戶端通訊庫(如:HTTP、SMTP、ICMP、memcache、beanstalk),常見流式編解碼庫:XML/JSON/MIME/BASE64/UUCODE/QPCODE/RFC2047 etc。

1.1、庫組成

本工程主要包含 5 個庫及大量示例。5 個庫的說明如下:

  • 1) lib_acl: 該庫是最基礎的庫,其它 4 個庫均依賴於該庫; 該庫以 C 語言實現。
  • 2) lib_protocol: 該庫主要實現了 http 協議及 icmp/ping 協議; 該庫以 C 語言實現。
  • 3) lib_acl_cpp: 該庫用 C++ 語言封裝了 lib_acl/lib_protocol 兩個庫,同時增加了一些其它有價值的功能應用。
  • 4) lib_dict: 該庫主要實現了 KEY-VALUE 的字典式儲存庫,該庫另外還依賴於 BDB, CDB 以及 tokyocabinet 庫。
  • 5) lib_tls: 該庫封裝了 openssl 庫,使 lib_acl 的通訊模式可以支援 ssl。

1.2、功能模組組成

1.2.1、網路通訊庫

  • 流處理模組(ACL_VSTREAM): 該模組是整個 acl 網路通訊最基礎的流式通訊模組,不僅支援網路流,同時還支援檔案流,主要支援:
  • 1 按行讀資料,相容 win32 下的 \r\n,同時相容 UNIX 下的 \n 的結束符
  • 2 按行讀資料但要求自動去掉尾部的 \n 或 \r\n
  • 3 以字串為分隔符讀取資料
  • 4 讀規定長度的資料
  • 5 嘗試性讀一行資料或嘗試性讀規定長度資料
  • 6 探測網路 IO 狀態
  • 7 寫入一行資料
  • 8 按格式符寫入資料,類似於 fprintf
  • 9 檔案流定位操作,類似於 fseek
  • 10 一次性寫入一組資料,類似於 unix 下的 writev
  • 11 將檔案截短,類似於 ftrunk
  • 12 獲取檔案大小
  • 13 獲得當前檔案流指標位置,類似於 ftell
  • 14 獲得檔案尺寸
  • 15 獲得網路流的本地地址及遠端地址

  • 網路操作模組:該模組主要支援網路服務端監聽(支援 TCP/UDP/UNIX 域套介面)、網路客戶端連線(支援 TCP/UNIX 域套介面)、DNS 域名查詢及結果快取(支援呼叫系統 gethostbyname 函式和直接傳送 DNS 協議兩種方式)、套介面(socket)操作及取本機網絡卡等功能。

  • 非阻塞網路流:支援非阻塞方式連線、讀(按行讀,規定長度讀)、寫(寫行,寫規定長度,寫一組資料)等操作。

  • 常見網路應用協議庫(lib_protocol/lib_acl_cpp):主要支援常見網路應用協議,諸如:HTTP、SMTP、ICMP,其中 HTTP、ICMP 兩個模組實現了阻塞、非阻塞兩種通訊方式;此外,HTTP 協議在C++版的 lib_acl_cpp 中還支援服務端、客戶端兩種通訊方式,當作為服務端使用時,支援類似於 JAVA HttpServlet 的介面使用方式,當作為客戶端方式使用時,支援連線池與叢集管理方式,該模組同時支援 cookie、session、HTTP MIME 檔案上傳、分塊傳輸、字符集自動轉換、自動解壓縮、斷點續傳等豐富的功能。

  • 常見網路通訊庫:支援 memcached、beanstalk、handler socket 客戶端通訊庫,該通訊庫支援連線池方式。

1.2.2、網路 IO 事件引擎

支援 select(UNIX/LINUX/WIN32)、poll(UNIX/LINUX)、epoll(LINUX)、kqueue(BSD)、devpoll(solaris)、iocp(WIN32)、視窗訊息(WIN32) 等系統事件引擎,同時支援 Reactor 及 Proactor 兩種程式設計模型。

1.2.3、網路伺服器框架

該模組是 acl 中最為重要的模組,提供了伺服器程式設計中常用的基礎設施,該伺服器框架來源於著名的 Postfix,在其基礎上進行了諸多擴充套件,目前已經支援的主要服務模型有:

  • 1 多程序模型:一個連線一個程序,這種模型的優點是程式設計簡單、安全穩定,缺點是併發度不高;
  • 2 多程序多執行緒模型:每個子程序是由執行緒池中的一組執行緒處理所有的客戶端連線,採用 IO 事件觸發方式,只有當連線有資料可讀時才會將連線與一個執行緒進行繫結,執行緒處理完後立即歸還給執行緒池,這種模型的最大優點是可以用少量的執行緒便可以處理大量的客戶端連線,而且程式設計比較簡單(相對於非阻塞模型);
  • 3 多程序非阻塞模型:每個子程序是由一個單獨的非阻塞執行緒組成,該執行緒採用完全非阻塞 IO 方式處理外來的大量客戶端連線(類似於 nginx/squid/ircd),該模型的優點是處理效率高佔用資源少,可以處理大量客戶端連線,缺點是程式設計比較複雜;
  • 4 UDP 通訊模型:該模型主要為了支援 UDP 網路過程而增加的服務模型;
  • 5 解發器模型:該模型的例項主要用來處理一些定時任務的後臺服務過程(類似於系統的 crontab)。

伺服器框架中的子程序實用採用半駐留服務模型,支援子程序預啟動機制、最大最小程序數控制、子程序異常報警、單一程序監聽多個地址(可同時監聽TCP/UDP套接字以及 UNIX 域套接字)、子程序安全控制、日誌輸出至 syslog-ng、多程序TCP連線均勻化;採用配置檔案驅動方式,每個服務一個配置檔案,方便程序管理及服務程序線上升級。

1.2.4、常用資料結構模組

該模組提供了常見的雜湊表(及多種雜湊演算法)、動態陣列、雙向連結串列、平衡二叉樹、佇列、二分塊查詢樹、256 叉匹配樹等陣列結構;提供了統一的資料結構遍歷方法(採用 acl_foreach)。

1.2.5、 記憶體操作模組

該模組提供三種記憶體池模型:

  • 1 基本的記憶體方式:內部封裝了系統的 malloc/free API,提供了記憶體校驗等安全措施;該方式同時提供外部註冊介面,允許使用者註冊自己的記憶體分配模型;
  • 2 記憶體片(slab) 方式:根據不同的尺寸大小分配多個定長記憶體鏈,可以有效地減少記憶體碎片,大大提升記憶體分配效率;
  • 3 記憶體鏈方式:將長度不一的小記憶體分配在一條記憶體頁上,可以非常有效地使用記憶體,減少記憶體浪費。

1.2.6、常用字串操作模組

支援字串匹配查詢、前(後)向比較、字串分割、字串大小寫轉換、H2B/B2H 轉換、URL 編碼/解碼等功能。

1.2.7、檔案目錄模組

支援多級目錄建立、多級目錄掃描、檔案控制代碼快取等功能,同時在處理多級目錄採用迴圈方式,避免了遞迴方式時可能的棧溢位的隱患。

1.2.8、讀配置檔案模組

支援讀 name=value 形式的配置檔案,value 較長時可以使用反斜槓()折行,採用配置表方式提取配置檔案中的配置項。

1.2.9、執行緒及執行緒池模組

提供了跨平臺的支援 Posix 規範的執行緒介面(支援WIN32);執行緒池模組通過多種措施最大程度地減少執行緒任務分配時的鎖衝突(用在 acl 伺服器框架中多程序多執行緒服務模型中)。

1.2.10、數字鍵的 K-V 磁碟儲存模組(zdb)

採取 KEY/VALUE 分塊儲存方式,因為 KEY 限定為數字型別,只需記憶體計算便可算出 KEY 的位置,KEY 中存放了 VALUE 的位置,所以對於任何的資料查詢只需兩次磁碟定位。(本人在和訊做流量統計儲存時,使用該種方式替代了BSD、TC 等採用B樹的 K-V 儲存)

1.2.11、流式解析庫

該模組包括 xml、json、rfc2047、mime、base64、uucode、qpcode、charset 等編解碼庫,這些解碼庫均採用流式解析方式,適合於多種網路 IO 模型(阻塞/非阻塞TCP、UDP)。

1.2.12、資料庫封裝庫

設計了統一的資料庫操作介面及連線池處理方式,目前支援 sqlite/mysql。

1.2.13、檔案佇列處理庫

支援多組目錄佇列檔案的建立、掃描、刪除等操作;常用於臨時檔案佇列排程的服務程式中。

二、平臺支援及編譯

整個工程目前支援 Linux(AS4,5,6, CS4,5,6, ubuntu), Windows, MacOS, FreeBSD, Solaris。

  • Linux/UNIX: 編譯器為 gcc,直接在終端命令列方式下分別進入 lib_acl/lib_protocol/lib_acl_cpp/lib_dict/lib_tls 目錄下,執行 make 命令即可。
  • Windows: 可以用 VC2003/VC2008/VC2010/VC2012 進行編譯。(如果需要用 VC6/VC2005 編譯,可以參考 VC2003 的編譯條件)。

當在 WIN32 環境下使用動態庫時有幾點需要注意:

  • 使用 lib_acl 的動態庫時,需要在使用者的工程預定義: ACL_DLL;
  • 使用 lib_protocol 動態庫中的 HTTP 庫或 ICMP 庫時,需要在工程中預定義 HTTP_DLL 或 ICMP_DLL;
  • 使用 lib_acl_cpp 的動態庫時,需要在工程中預定義 ACL_CPP_DLL,如果您使用用 VC2003 編譯環境則還需要預定義 VC2003;
  • 使用 lib_dict 的動態庫時,需要在工程中預定義 DICT_DLL;
  • 使用 lib_tls 的動態庫時,需要在工程中預定義 TLS_DLL。  

三、專案資料

QQ 群: 242722074

acl 工程有大量的測試用例(近200個):https://github.com/zhengshuxin/acl/blob/master/SAMPLES.md

此外,還幾個實用的工具:

1、伺服器程式生成嚮導:https://github.com/zhengshuxin/acl/tree/master/app/wizard,使用該工具,可以快速地建立網路伺服器程式(甚至於 HTTP WEB 伺服器程式)

2、全域性唯一ID產生器:https://github.com/zhengshuxin/acl/tree/master/app/gid

3、網路狀態監控工具(WIN32):https://github.com/zhengshuxin/acl/tree/master/app/net_tools

4、TCP 連線分配器:https://github.com/zhengshuxin/acl/tree/master/app/master_dispatch

5、字符集轉換器:https://github.com/zhengshuxin/acl/tree/master/app/jencode

四、圖例

1、類索引圖:


2、非同步 IO 類繼承圖


3、IO 流繼承圖


4、接收上傳檔案的 CGI 程式:


5、檔案下載客戶端程式:


6、網頁下載程式: