3、LwIP的三種編程接口


LwIP 提供了三種編程接口,分別為 RAW/Callback API、 NETCONN API、 SOCKETAPI。它們的易用性從左到右依次提高,而執行效率從左到右依次降低,用戶可以根據實際情況,平衡利弊,選擇合適的 API 進行網絡應用程序的開發。以下內容將分別介紹這三種 API。

1、 RAW/Callback API

  RAW/Callback API 是指內核回調型的 API, 這在許多通信協議的 C 語言實現中都有所應用。  RAW/Callback API 是 LwIP 的一大特色, 在沒有操作系統支持的裸機環境中,只能使用這種 API 進行開發,同時這種 API 也可以用在操作系統環境中。 這里先簡要說明一下“回調”的概念。 你新建了一個 TCP 或者 UDP 的連接,你想等它接收到數據以后去處理它們, 這時你需要把處理該數據的操作封裝成一個函數,然后將這個函數的指針注冊到LwIP 內核中。 LwIP 內核會在需要的時候去檢測該連接是否收到數據,如果收到了數據,內核會在第一時間調用注冊的函數,這個過程被稱為“回調”,這個注冊函數被稱為“回調函數”。 這個回調函數中裝着你想要的業務邏輯,在這個函數中,你可以自由地處理接收到的數據,也可以發送任何數據,也就是說,這個回調函數就是你的應用程序。到這里,我們可以發現, 在回調編程中, LwIP 內核把數據交給應用程序的過程就只是一次簡單的函數調用,這是非常節省時間和空間資源的。 每一個回調函數實際上只是一個普通的 C 函數,這個函數在 TCP/IP 內核中被調用。每一個回調函數都作為一個參數傳遞給當前 TCP 或UDP 連接。而且,為了能夠保存程序的特定狀態,可以向回調函數傳遞一個指定的狀態,並且這個指定的狀態是獨立於 TCP/IP 協議棧的。 

  在有操作系統的環境中, 如果使用 RAW/Callback API,用戶的應用程序就以回調函數的形式成為了內核代碼的一部分, 用戶應用程序和內核程序會處於同一個線程之中,這就省去了任務間通信和切換任務的開銷了。

  簡單來說, RAW/Callback API 的優點有兩個:

  (1)可以在沒有操作系統的環境中使用。
  (2) 在有操作系統的環境中使用它, 對比另外兩種 API, 可以提高應用程序的效率、節省內存開銷。

  RAW/Callback API 的優點是顯著的,但缺點也是顯著的:
  (1) 基於回調函數開發應用程序時的思維過程比較復雜。在后面與 RAW/CallbackAPI 相關的章節中可以看到, 利用回調函數去實現復雜的業務邏輯時, 會很麻煩,而且代碼的可讀性較差。
  (2) 在操作系統環境中, 應用程序代碼與內核代碼處於同一個線程,雖然能夠節省任務間通信和切換任務的開銷,但是相應地,應用程序的執行會制約內核程序的執行,不同的應用程序之間也會互相制約。 在應用程序執行的過程中,內核程序將不可能得到運行,這會影響網絡數據包的處理效率。如果應用程序占用的時間過長,而且碰巧這時又有大量的數據包到達, 由於內核代碼長期得不到執行,網卡接收緩存里的數據包就持續積累,到最后很可能因為滿載而丟棄一些數據包,從而造成丟包的現象。

2、NETCONN API

  在操作系統環境中,可以使用 NETCONN API 或者 Socket API 進行網絡應用程序的開發。 NETCONN API 是基於操作系統的 IPC 機制(即信號量和郵箱機制) 實現的, 它的設計將 LwIP 內核代碼和網絡應用程序分離成了獨立的線程。如此一來, LwIP 內核線程就只負責數據包的 TCP/IP 封裝和拆封,而不用進行數據的應用層處理,大大提高了系統對網絡數據包的處理效率。

  前面提到,使用 RAW/Callback API 會造成內核程序和網絡應用程序、 不同網絡應用程序之間的相互制約,如果使用 NETCONN API 或者 Socket API,這種制約將不復存在。

  在操作系統環境中, LwIP 內核會被實現為一個獨立的線程, 名為 tcpip_thread,使用NETCONN API 或者 Socket API 的應用程序處在不同的線程中,我們可以根據任務的重要性,分配不同的優先級給這些線程,從而保證重要任務的時效性, 分配優先級的原則具體見下表。

  NETCONN API 使用了操作系統的 IPC 機制, 對網絡連接進行了抽象,用戶可以像操作文件一樣操作網絡連接(打開/關閉、讀/寫數據)。 但是 NETCONN API 並不如操作文件的 API 那樣簡單易用。舉個例子,調用 f_read 函數讀文件時,讀到的數據會被放在一個用戶指定的數組中,用戶操作起來很方便,而 NETCONN API 的讀數據 API,就沒有那么人性化了。 用戶獲得的不是一個數組,而是一個特殊的數據結構 netbuf,用戶如果想使用好它,就需要對內核的 pbuf 和 netbuf 結構體有所了解。 NETCONN API 之所以采取這種不人性的設計,是為了避免數據包在內核程序和應用程序之間發生拷貝,從而降低程序運行效率。當然, 用戶如果不在意數據遞交時的效率問題, 也可以把 netbuf 中的數據取出來拷貝到一個數組中,然后去處理這個數組。

  簡單來說, NETCONN API 的優缺點是:

  (1) 相較於 RAW/Callback API, NETCONN API 簡化了編程工作,使用戶可以按照操作文件的方式來操作網絡連接。 但是,內核程序和網絡應用程序之間的數據包傳遞,需要依靠操作系統的信號量和郵箱機制完成,這需要耗費更多的時間和內存,另外還要加上任務切換的時間開銷,效率較低。
  (2) 相較於 Socket API, NETCONN API 避免了內核程序和網絡應用程序之間的數據拷貝,提高了數據遞交的效率。 但是, NETCONN API 的易用性不如 Socket API 好,它需要用戶對 LwIP 內核所使用數據結構有一定的了解。

3、SOCKET API

  Socket,即套接字,它對網絡連接進行了高級的抽象,使得用戶可以像操作文件一樣操作網絡連接。它十分易用, 許多網絡開發人員最早接觸的就是 Socket 編程, Socket 已經成為了網絡編程的標准。在不同的系統中,運行着不同的 TCP/IP 協議,但是只要它實現了Socket 的接口,那么用 Socket 編寫的網絡應用程序就能在其中運行。可見用 Socket 編寫的網絡應用程序具有很好的可移植性。

  不同的系統有自己的一套 Socket 接口。 Windows 系統中支持的是 WinSock,UNIX/Linux 系統中支持的是 BSD Socket,它們雖然風格不一致, 但大同小異。 LwIP 中的Socket API 是 BSD Socket。但是 LwIP 並沒有也沒辦法實現全部的 BSD Socket,如果開發人員想要移植 UNIX/Linux 系統中的網絡應用程序到使用 LwIP 的系統中,就要注意這一點。

  相較於 NETCONN API, Socket API 具有更好的易用性。使用 Socket API 編寫的程序可讀性好,便於維護,也便於移植到其它的系統中。 Socket API 在內核程序和應用程序之間存在數據的拷貝,這會降低數據遞交的效率。 另外, LwIP 的 Socket API 是基於NETCONN API 實現的,所以效率上相較前者要打個折扣。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM