lwip設計與實現(xiàn)_第1頁
lwip設計與實現(xiàn)_第2頁
lwip設計與實現(xiàn)_第3頁
lwip設計與實現(xiàn)_第4頁
lwip設計與實現(xiàn)_第5頁
已閱讀5頁,還剩31頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

1、Design and Implenientation(f* the LWlP ' TCP/IP StackLwip協(xié)議棧的設計與實現(xiàn)(中文版)翩 SICSSwedish In stitute of Computer Scie neeFebruary 20, 2001作者:Adam Dunkels adamsics.se翻譯:果農(nóng)(QQ: 10205001)核桃(QQ: 329147)佳旭(QQ:3232253)整理:佳旭(QQ:3232253)本文為QQ群ARM TCPIP LCD (群號:10988210)版權所有未經(jīng)作者許可不得用于商業(yè)用途摘要LWIP是TCP/IP協(xié)議棧的一種實現(xiàn)

2、。LWIP的主要目的是減少存儲器利用量和代碼尺寸,使LWIP 適合應用于小的、資源有限的處理器如嵌入式系統(tǒng)。 為了減少處理器和存儲器要求, lwIP 可以通過不需任何數(shù)據(jù)拷貝的 API進行裁減。本文敘述了 IwlP的設計與實現(xiàn)。敘述了協(xié)議實現(xiàn)及子系統(tǒng)中所使用的算法和數(shù)據(jù)結構如存儲 和緩沖管理系統(tǒng)。還包括 LWIP API 的參考手冊和使用 LWIP 的一些代碼例子。目錄1 In troduct ion 12 Protocol layering 13 Overview 24 Process model 25 The operat ing system emulatio n layer 36 Bu

3、ffer and memory management . . 36.1 Packet buffers pbufs 36.2 Memory management 57 Network in terfaces 58 IP process ing 78.1 Receivi ng packets 78.2 Sending packets77777777777777777777777777777777778.3 Forwarding packets777777777777777777777777777777788.4 ICMP processing 777777777777777777777777777

4、77777.89 UDP processing 777777777777777777777777777777. 810 TCP processing 777777777777777777777777777777910.1 Overview77777777777777777777777777777777777910.2 Data structures777777777777777777777777777777771010.3 Seque nee nu mber calculations 1210.4 Queu ing and tran smitt ing data 1210.4.1 Silly

5、window avoidanee 1310.5 Receivi ng segments 13 .10.5.1 Demultiplexi ng 13 .10.5.2 Receivi ng data 14 .10.6 Accept ing new connections 1410.7 Fast retransmit 14 .10.8 Timers 14 .10.9 Roun d-trip time estimation 15 .10.10C on gesti on control 15 .11 In terfa cing the stack1512 Applicati on Program In

6、terface 16.12.1 Basic concepts 16 .12.2 Impleme ntatio n of the API 17.13 Statistical code an alysis1713.1 Lines of code- 1813.2 Object code size 19 .14 Performa nee an alysis 20 15 API refere nee 21 15.1 Data types 2115.1.1 Netbufs 21 .15.2 Bu?er functions 21 .15.2.1 n etbuf new() 21 .15.2.2 n etbu

7、f delete() 21 .15.2.3 n etbuf alloc() 2215.2.4 n etbuf free() 22 .15.2.5 n etbuf ref() 2215.2.6 n etbuf len() 23.15.2.7 n etbuf data() 2315.2.8 n etbuf next() 2315.2.9 n etbuf rst() 24 .15.2.10 n etbuf copy() 24 .15.2.11 n etbuf chain() 24 .15.2.12 n etbuf fromaddr() 2415.2.13 n etbuf fromport() 251

8、6 Network connection functions2516.0.14 netconn new()25.16.0.15 netconn delete(-) 25 .16.0.16 netconn type()25.16.0.17 netconn peer(-) 2516.0.18 netconn addr()2616.0.19 netconn bind()2616.0.20 netconn connect-( 2616.0.21 netconn listen() 2616.0.22 netconn accept(-) 26 .16.0.23 netconn recv()2716.0.2

9、4 netconn write() 2816.0.25 netconn send(-) 2916.0.26 netconn close()3017 BSD socket library 3017.1 The representation of a socke-t 3017.2 Allocating a socket 30 .17.2.1 The socket() call 3017.3 Connection setup31 .17.3.1 The bind() call 31 .17.3.2 The conn ect() call 3117.3.3 The liste n() call 321

10、7.3.4 The accept() call 32.17.4 Sending and receivi ng data 33.17.4.1 The sen d() call 3317.4.2 The sen dto() and sen dmsg() calls 3417.4.3 The write() call 3417.4.4 The recv() and read() calls 3517.4.5 The recvfrom() and recvmsg() calls 3618 Code examples 3618.1 Us ing the API 3618.2 Directly in te

11、rfa cing the stack 39.Bibliography 411 序論 在過去的幾年里,人們對計算機互連和計算機無線互連支持設備的興趣不斷的增長,計算 機逐漸與日常使用的設備無縫結合,并且價格不斷下降。同時,無線網(wǎng)絡技術如 Bluetooth HNI+98和IEEE 802.11b WLAN BIG+97不斷顯現(xiàn)。這也在一些領域譬如醫(yī)療保健、安全保衛(wèi)、交通運輸、加工業(yè)等引起了許多新引人入勝的情節(jié)。小的設備如傳感器能被聯(lián)入現(xiàn)有的網(wǎng) 絡如全球因特網(wǎng),并可以在任何地方對其進行監(jiān)控。在過去的幾年里,互聯(lián)網(wǎng)技術證明自己具有足夠的靈活性來合并不斷改變的網(wǎng)絡的環(huán)境。與當初為低速網(wǎng)絡譬如ARPAN

12、E網(wǎng)而產(chǎn)生的互聯(lián)網(wǎng)相比,今天的大范圍連接的互聯(lián)網(wǎng)技術在帶寬和誤碼率方面都與原來有著巨大的差異。由于互聯(lián)網(wǎng)的大量應用,把將來的無線互連網(wǎng)絡應用 于現(xiàn)有的互連網(wǎng)絡將會給我們帶來巨大的收益。并且,大面積互連的互聯(lián)網(wǎng)也是一強勁趨勢。自從人們經(jīng)常對像傳感器這樣的小設備有小的物理外形和便宜的價格的要求,實現(xiàn)一較少 的處理和存儲要求的互連協(xié)議就成為必須解決的問題。本文描述了一種稱為LWIF的小到足以滿足最小系統(tǒng)要求的TCP/IP協(xié)議棧的設計與實現(xiàn)。本文結構如下編排:第2,3和4部分對lwIP棧作一個概述,第5部分敘述操作系統(tǒng)模擬層, 第6部分敘述緩存和存儲管理。第7部分介紹lwIP抽象的網(wǎng)絡接口,第8,9,

13、和10部分敘述IP, UDP和TC脅議的實現(xiàn)。第11和12部分敘述怎樣與lwIP進行接口并介紹lwIP API。第13和14部 分分析了實現(xiàn)過程。最后, 15部分提供了 lwIP API 用戶參考手冊, 17和18部分展示了多種代碼 例子。2 協(xié)議分層( Protocol layering )TCP/IP協(xié)議被設計為分層結構,各協(xié)議層分別解決通信問題的一部份。這一分層對于協(xié)議 的設計、實現(xiàn)可起一個指導作用,各個協(xié)議可分開實現(xiàn)。然而協(xié)議嚴格的按分層結構來實現(xiàn), 各層之間的通訊可能會導致總體性能的降低 Cla82a。 為克服這些問題 , 協(xié)議的某些內(nèi)部方面可傳達給其它協(xié)議共享,但必須注意,保證只有

14、那些重要信息才在各層共享。盡管底層協(xié)議或多或少可以進行交叉存取,大部分 TCP/IP協(xié)議,還是在應用層協(xié)議與底層 協(xié)議之間進行嚴格的區(qū)分。在大部分操作系統(tǒng)中,底層協(xié)議被作為與應用層程序具有通訊接口 的操作系統(tǒng)內(nèi)核的一部分。應用程序被看作是 TCP/IP協(xié)議的抽象,網(wǎng)絡通訊與進程間通訊或者 文件I/O只有很小的差別。這意味著,因為應用程序不知道被底層協(xié)議所使用的緩沖機制,它不 能利用緩沖機制對經(jīng)常使用的數(shù)據(jù)進行緩沖。同樣,當應用程序發(fā)送數(shù)據(jù)時,在數(shù)據(jù)被網(wǎng)絡代 碼處理前,必須把這些數(shù)據(jù)從應用程序存儲區(qū)被拷貝到內(nèi)部緩沖區(qū)。最小系統(tǒng)中使用的操作系統(tǒng)像lwIP的目標系統(tǒng)在內(nèi)核和應用進程之間常常并不存在嚴

15、格的保護 屏障。這就允許應用程序和底層協(xié)議之間使用一種更寬松的方案,通過共享內(nèi)存。特別地,應 用層可以意識到底層協(xié)議所使用的緩存處理機制。因此,應用可以更有效地重用緩沖區(qū)。而且, 既然應用進程和網(wǎng)絡代碼可以使用相同的內(nèi)存,應用可以直接讀寫內(nèi)部緩存,因此節(jié)省了執(zhí)行 拷貝的開銷。3 總述( Overview )正如其他TCP/IP協(xié)議的實現(xiàn),分層協(xié)議的設計為LWIP勺設計與實現(xiàn)提供一向導。每一個協(xié) 議都作為一個模塊來實現(xiàn),提供一些與其他協(xié)議的接口函數(shù)。盡管各層分開實現(xiàn),但正如上面 所討論的,為了同時提高處理速度和內(nèi)存利用兩方面的性能,一些層在設計時違背這一原則。 例如:當檢驗一接收到的TCP( s

16、egment)的校驗和(checksum)和分解TCP時,源和目的IP 地址必須被告知TCP模塊。LWIP實現(xiàn)時不是通過函數(shù)調(diào)用把IP地址傳遞給TCP 而是TCP莫塊通過 獲取IP報頭的結構進而自己提取這一信息。LWIP有幾個模塊組成,除了實現(xiàn)TCP/IP協(xié)議的各個模塊(IP、ICMP UDP和TCP),同時設 計了許多支持模塊。 這些支持模塊組成了操作系統(tǒng)模擬層(第5章) 、緩沖和存儲管理子系統(tǒng) (第6章)、網(wǎng)絡接口函數(shù)(第7章)和一些處理因特網(wǎng)校驗和的函數(shù)。LWIP還包括關于API的摘要(第12章)。4 進程模型( Process model )協(xié)議實現(xiàn)的過程模型以把系統(tǒng)劃分成為不同的過程

17、的方法進行描述。用于實現(xiàn)通訊協(xié)議的 過程模型使每個協(xié)議作為孤立的過程運行。這種模型使用嚴格的協(xié)議分層,協(xié)議之間的通訊結 點必須被嚴格定義。雖然這種方法有其諸多優(yōu)勢如協(xié)議能在運行時被增加,代碼一般容易理解 和調(diào)試,但也有不利因素。 嚴格的分層,正如先前所述,并不總是實現(xiàn)協(xié)議的最好方法。 同 時,更重要的,每跨越一層,必須做一次上下文切換。這將意味著,接受一個TC毀要進行三次上下文切換:從網(wǎng)絡接口的驅動,到IP處理,再到TCP±理,最終到應用處理。根據(jù)網(wǎng)絡接口的 設備驅動程序,對于IP過程,對于TCfti程和最后。 在大多數(shù)操作系統(tǒng)中一個上下文切換所花 的代價都是相當昂貴的。另一個較普通

18、的方法是把通信協(xié)議封裝在操作系統(tǒng)的內(nèi)核。 在這種內(nèi)核實現(xiàn)通訊協(xié)議的情況 下,應用程序通過系統(tǒng)調(diào)用完成通訊。 通訊協(xié)議之間不嚴格區(qū)分,但可以使用交叉協(xié)議分層技 術。lwIP所使用的過程模型是:把所以協(xié)議封裝到一個單一的過程中,從而與操作系統(tǒng)內(nèi)核分 開。應用程序可能也駐留在lwIP處理過程中,或者在單獨的過程中。 TCP/IP棧和應用程序之間 的通信可以通過函數(shù)調(diào)用實現(xiàn),也可以通過更為抽象的 API。以上兩種LWIP的實現(xiàn)方法各有其優(yōu)缺點。把LWIF作為一個過程的主要優(yōu)點是便于在不同的 操作系統(tǒng)上移植。由于LWIP的設計目標是面向小的操作系統(tǒng),這些操作系統(tǒng)一般不支持進程外 交換(swapping

19、out processes )或者虛擬存儲,這樣由于LWIP處理過程交換或者翻頁到磁盤 而引起的不得不等待磁盤響應造成的延遲將不再是一個問題。盡管在獲得服務響應前必須等待 調(diào)度仍然是一個問題,但是,在LWIF設計時,這并沒有妨礙它在一操作系統(tǒng)內(nèi)核中實現(xiàn)。5 操作系統(tǒng)模擬層為了使lwIP便于移植,與操作系統(tǒng)有關的功能函數(shù)調(diào)用和數(shù)據(jù)結構沒有在代碼中直接使用。而 是當需要這樣的函數(shù)時,操作系統(tǒng)模擬層將加以使用。操作系統(tǒng)模擬層向諸如定時器、處理同 步、消息傳送機制等的操作系統(tǒng)服務提供一套統(tǒng)一的接口。原則上,移植lwIP到其他操作系統(tǒng)時,僅僅需要實現(xiàn)適合該操作系統(tǒng)的操作系統(tǒng)模擬層。操作系統(tǒng)模擬層提供了由

20、TCP使用的定時器功能。操作系統(tǒng)模擬層提供的定時器是一次性的 定時器,當超時發(fā)生時,調(diào)用一個已注冊函數(shù)至少要 200m啲間隔。進程同步機制僅提供了信號量。即使在操作系統(tǒng)底層中信號量不可用,也可以通過其他信 號原語像條件變量或互鎖來模擬。信息傳遞的實現(xiàn)使用一種簡單機制,用一種稱為 “郵箱 ”的抽象方法。郵箱做兩種操作:郵 寄和提取。郵寄操作不會阻塞進程;郵寄到郵箱的消息由操作系統(tǒng)模擬層排入隊列直到另一個 進程來提取它們。即使操作系統(tǒng)底層對郵箱機制不支持,也容易用信號量實現(xiàn)。6緩沖和存儲管理通訊系統(tǒng)中的存儲和緩沖管理必須能夠適應大小變化的緩沖區(qū),從幾百字節(jié)的包含完全大 小TCP段的緩沖區(qū)到僅僅包含

21、幾個字節(jié)的短的ICMF回報。而且,為了避免拷貝它應當盡可能讓緩沖區(qū)的數(shù)據(jù)內(nèi)容駐留在內(nèi)存中,網(wǎng)絡子系統(tǒng)不管理像應用存儲或R0這樣的內(nèi)存。6.1包緩沖器pbufsPbuf在IwlP的內(nèi)部表示一包,也是為了最小限度的使用棧這一特殊需要而設計。Pbufs類似于用于BSD實現(xiàn)的mbufs。 pbuf結構既支持分配動態(tài)內(nèi)存來保存包內(nèi)容,也支持把包數(shù)據(jù)存儲 在靜態(tài)存儲區(qū)。Pbufs能在一張列表中一起被連在一起,稱為一個pbuf鏈,這樣一個包可以跨越若干個pbufs。Pbufs具有三種類型, PBUF RAM , PBUF ROM,和 PBUF POOL。 圖 1 中 pbuf描繪了 PBUF RAM類型,和

22、儲存的被pbuf子系統(tǒng)管理的數(shù)據(jù)包。圖2中的pbuf是被鏈在一起的pbuf的一個例子,在其中鏈的第一個 pbuf具有 PBUF RAM 類型(where the first pbufin the chain is of the PBUF RAM type ),而第二個具有PBUF ROM類型,這意味著它具有不被 pbuf系統(tǒng)管理的存儲數(shù)據(jù)。 第三種類型的pbuf , PBUF POOL如圖3所示,包括從共有的固定大小的 pbufs分配的固定大小的 pbufs (consists of fixed size pbufs allocated from a pool of fixedsize pbu

23、fs.)。 一個 pbuf鏈可能包 括多重類型的pbufs。三種類型有不同的使用。PBUF_POOL主要被網(wǎng)絡設備驅動程序使用,因為對操作系統(tǒng)來說分配單一的pbuf速度較快并且適合用于中斷管理(suitable foruse in an interrupt handler )。當應用程序發(fā)送位于被應用程序管理的存儲區(qū)的數(shù)據(jù)時,PBUF_ROM被使用。在pbuf被移交到TCP/IP棧后,數(shù)據(jù)不能修改,因此這一pbuf類型,這類型主要用于數(shù)據(jù)位于ROM時(因此名稱為PBUF_ROM )。 PBUF_ROM pbu中的數(shù)據(jù)可能會用到的頭存儲在PBUF_RAM pbu中,它鏈接在PBUF_ROM pb

24、uf前面,如圖2所示。nextpayloaalentot leutiagaireT丘 stw jfer i:* Hg:仙只審卿幷rlphsgr盤口廿WjfcF TCP CCiMfeFFijirre 1L A PHIphuf with data in iueiiiory inanajred by the pb if subystpm.Figure N A PBUF_RAM pbuf cliEniiied wiili “ PBUF_ROM pbuf that diitu In extrjuil iiiemorAr.當應用程序發(fā)送動態(tài)地產(chǎn)生的數(shù)據(jù)時,PBUF_RAM型的Pbufs也被使用。在這種情況

25、下, pbuf系統(tǒng)不光為應用數(shù)據(jù)分配存儲空間,也為將要發(fā)送的數(shù)據(jù)的報頭準備空間。如圖1所示。pbuf系統(tǒng)不能預先知道為將要發(fā)送的數(shù)據(jù)準備什么樣的報頭,并且假定最壞的情況。報頭大小 在編譯時可動態(tài)配置。實質(zhì)上,進入pbufs的是PBUF_PO類型,離開pbufs的是PBUF_ROMPBUF_RAM型。pbuf的內(nèi)部的結構如圖13。pbuf結構包括兩個指針,兩長度域,一個flags域,和一參考 計數(shù)。pbuf鏈中next域是一個指向下一個pbuf的指針。Payload指針指向pbuf中的數(shù)據(jù)的起始位置。len域包含pbuf的數(shù)據(jù)內(nèi)容的長度。Tot_len域包含當前的pbuf的長度和在pbuf鏈中接

26、下來 的pbufs的所有l(wèi)en領域的總數(shù)。換句話說,tot_len域是len域和pbuf鏈中的隨后的pbuf中的 tot_len域的值的總和。flags域表明pbuf的類型,而ref領域包含一參考計數(shù)。Next和payload 域是內(nèi)部指針和依賴于處理器體系結構的數(shù)據(jù)大小。兩個長度域為16位無符號整形,flags和ref域均為4bit寬。pbuf結構整個的大小取決于所使用的處理器體系結構中一個指針的大小及可能 的最小alignment的大小。 在帶有32位指針和4個字節(jié)alignment的體系結構,整個的大小為 字節(jié),16位指針和1個字節(jié)alignment的體系結構上,大小是 9個字節(jié)。16F

27、L*KtFigure 3. A chained PBUF_POOL pbuf from the pbuf pooLpsylsi&d len£1-3.77-=:1*XLct lea£ lai-5pbuf模塊為操縱pbufs提供了函數(shù)。函數(shù)pbuf_alloc() 完成分配一個pbuf的任務,它能夠 分配上面所說的三種pbuf中的任何一種。pbuf_ref()增加參考計數(shù)。pbuf_free()完成釋放分 配的工作,它首先減少pbuf的參考計數(shù)。如果參考計數(shù)到達零表示pbuf已經(jīng)被釋放。函數(shù)pbuf_realloc() 收縮pbuf使它剛好能夠包含數(shù)據(jù)大小。pbuf_h

28、eader()調(diào)整payload指針和長度域,以便對pbuf中的數(shù)據(jù)的報頭進行預先估計。buf_chain()和pbuf_dechain()用于用鏈接pbufs。6.2內(nèi)存管理支持pbuf調(diào)度的存儲管理非常簡單。它處理內(nèi)存中連續(xù)區(qū)域的分配和釋放,可以緊縮一 個預先分配的內(nèi)存塊。內(nèi)存管理器使用系統(tǒng)中總內(nèi)存的專用部分,這確保網(wǎng)絡系統(tǒng)不會使用所 有可利用內(nèi)存,而且如果網(wǎng)絡系統(tǒng)用了所有它自己的內(nèi)存其他程序的操作也不會影響它。在內(nèi)部,內(nèi)存管理通過將一種小的結構放置在每一被分配的內(nèi)存塊的頂端上來追蹤分配的 內(nèi)存。這個結構(圖4)中設置兩個指針指向內(nèi)存中下一個和前一個分配塊,還有一個used標志用來指示這個

29、分配塊是否已經(jīng)被分配。通過搜索一個未使用的內(nèi)存塊來分配內(nèi)存,這個內(nèi)存塊對于請求分配來說足夠大。使用最 先適用原則,因此第一塊被使用的內(nèi)存足夠大。當一個分配塊釋放時,used標志被設為0。為了防止碎片,檢測下一個和上一個分配塊的 used標志,如果它們還沒被使用,幾個塊合并成一個 大未使用塊。7網(wǎng)絡接口硬件設備驅動程序中,IwlP用一個類似于BSD勺網(wǎng)絡接口結構來描述物理硬件。網(wǎng)絡接口結構如圖5所示。通過next指針,網(wǎng)絡接口被連成一個全局鏈表(global linked list )。每個網(wǎng)絡接口有一個名字,存儲在圖5中的nam字段。這個兩個字符的名字識別用于網(wǎng)絡接口中的設備驅動類型,而且當接

30、口在運行時由人為操作來配置。這個名字由設備驅動設置,應 當映射由網(wǎng)絡接口表示的硬件類型。例如,藍牙驅動網(wǎng)絡接口可能使用名字btd ,而IEEE802.11bWLA硬件可能使用名字wl。由于這些名字不必是唯一的,num字段用來區(qū)分同類設備中的不同的網(wǎng)絡接口。Figure 丄 The memory allocation structure.Btnict netif Rtriirt neri f +npyt;char nEune ;mt nmii;struct ip_addr ip_addr;struct ip_addr netmask;struct ip_addr 糾;void (* input)

31、(struct pbuf *p, struct netif *iup): int (* output)(stnict net if *netif,struct pbuf *p, 5truer ip_addr *ipaddr);void +state;;Figure 5. The net If atructure.當發(fā)送和接收包時,三個IP地址ip_addr , netmask和gw由IP層使用,它們的用途在下一節(jié) 敘述。給網(wǎng)絡接口配置多于一個IP地址是不允許的,一個網(wǎng)絡接口應當為每一個IP地址創(chuàng)建。當包接收到時,設備驅動應當調(diào)用in put指針指向的函數(shù)。網(wǎng)絡接口通過output指針連接到設備

32、驅動。這個指針指向設備驅動中的一個函數(shù),它在物 理網(wǎng)絡上傳送一個包,當一個包被發(fā)送時它由IP層調(diào)用。這個字段由設備驅動初始化函數(shù)填充。 output函數(shù)的第三個參數(shù)ipaddr是主機的IP地址,它可以接收實際鏈路層的幀。它不應和IP包 的目的地址相同。特別地,當發(fā)送一個IP包到不在本地網(wǎng)絡的主機時,鏈路層幀被發(fā)送到網(wǎng)絡上一個路由。這種情況,給output函數(shù)的IP地址將是路由的IP地址。最后, state 指針指向設備驅動中網(wǎng)絡接口的特定狀態(tài),由設備驅動設置。8 IP 處理IwlP僅僅實現(xiàn)IP最基本的功能,它可以發(fā)送,接收和轉發(fā)包,但不能發(fā)送或接收分割的IP包,也不能處理帶IP選項的包。對于大

33、多數(shù)應用來說這不會引起任何問題。8.1接收包對于接收的IP若干包,處理從ip_input()函數(shù)被設備驅動程序調(diào)用開始。在這里,初始化工作將檢查IP版本,同時確定報頭長度,還會計算和檢查報頭 checksum域。期望的情況是,自 從Proxy服務器重組所有碎片(fragmented )包以來,堆棧就再沒有收到碎片(fragments),這 樣任何IP碎片的包都會被默默的丟棄。帶有ip選項的包同樣會被指定為由代理處理,并因此被 丟掉。接下來,函數(shù)通過網(wǎng)絡接口的 IP 地址檢驗目的地址以確定包是否去往主機。網(wǎng)絡接口已在 鏈表中排序,可以線性查找。網(wǎng)絡接口的序號指定為是小的號,因為比線性查找更巧妙的

34、查找 方法還沒實現(xiàn)。如果接收的包是主機指定的包,將使用 protocoI 域來決定該包應該傳給哪個更高層協(xié)議。8.2發(fā)送包一個要發(fā)送的包由函數(shù) ip_output( )處理,它使用函數(shù) ip_route( )尋找適當?shù)木W(wǎng)絡接口來 上傳包。 當時發(fā)送包的網(wǎng)絡接口被確定后, 包被傳遞到 ip_output_if() 函數(shù), 該函數(shù)把發(fā)送網(wǎng) 絡接口作為一個函數(shù)自變量。在這里,所有IP報頭域被填補并且IP報頭checksum被計算。IP包的源和目的地址作為變量傳遞給 ip_output_if() 函數(shù)。源地址可能被略去( Ieft out ),然 而,在這種情況下要發(fā)送的網(wǎng)絡接口的IP地址將被用作包的

35、來源IP地址。ip_route()函數(shù)通過線性查找網(wǎng)絡接口列表找到適合的網(wǎng)絡接口。在查找 IP包的目的IP地 址期間,用網(wǎng)絡接口的網(wǎng)絡掩碼進行掩碼。如果目的地址等于經(jīng)掩碼的接口IP地址,則選擇這個接口。如果找不到匹配的,則使用缺省網(wǎng)絡接口。缺省網(wǎng)絡接口由人工操作在啟動時或運行 時配置。如果缺省接口的網(wǎng)絡地址和目的IP地址不匹配,則選擇網(wǎng)絡接口結構中的gw字段作為 鏈路層幀的目的IP地址。(注意這各情況下IP包的目的地址和鏈路層幀的IP地址是不同的。) 路由的原始形式忽略了這個事實:一個網(wǎng)絡可能有許多路由器依附它。而工作時,對于一般情 況下,一個本地網(wǎng)絡只有一個路由器。因為運輸層協(xié)議UD和TCP

36、在計算運輸層校驗和時需要有目的IP地址,所以在包傳給IP層前外發(fā)網(wǎng)絡接口在某些情況下必須已確定。這可讓運輸層函數(shù)直接調(diào)用 ip_route() 函數(shù)完成,因 為在包到達IP層時外發(fā)網(wǎng)絡接口已經(jīng)知道,沒必要再查找網(wǎng)絡接口列表。而是那些協(xié)議直接調(diào) 用ip_output_if() 函數(shù)。由于這個函數(shù)把網(wǎng)絡接口作為參數(shù),可避免外發(fā)接口的查找。注:運行期間lwIP的手工配置要有一個能配置棧的應用程序,lwIP中不包含這樣的程序。8.3轉交包如果沒有網(wǎng)絡接口的IP地址和傳進包的目的地址相同,這個包應當轉發(fā)。這由函數(shù) ip_forward()完成。在這里,TTL字段減小,如果變?yōu)榱?,貝U ICMP錯誤信息被

37、發(fā)送到IP包原始發(fā) 送器并丟棄這個包。由于IP頭被改變,有必要調(diào)整IP頭校驗和。然而不必重算完整的校驗和, 因為可用簡單的算術來調(diào)整原始的IP校驗和MK90,Rij94。 最后,包被轉發(fā)到適當?shù)木W(wǎng)絡接口。 用來尋找合適網(wǎng)絡接口的算法和發(fā)送IP包時使用的一樣。8.4 ICMP 處理ICMP處理是相當簡單的。由ipnput()收到的ICM電被移交到icmp_input(), 它解析ICMP報頭并且進行適當?shù)奶幚?。一些ICMPt息被傳遞到更高協(xié)議層并被傳輸層的一些特殊函數(shù)處理(Some ICMP messages are passed to upper layer protocols and tho

38、se are taken care of by special functions in the transport layer)。ICMF目的地不能到達的信息能被運輸層協(xié)議發(fā)送,尤其是UDP和函數(shù)icmp_dest_unreach()。Figure 6. ICMP processing使用ICMP ECH信息來探測網(wǎng)絡被廣泛應用,因此對ICMPECHO行了性能優(yōu)化。實際處理在函數(shù)icmp_input()中發(fā)生,包括對接收的包的目的和源地址進行交換,改變ICMP類型為echoreply并且調(diào)整ICMP checksum。然后包回送到IP層等待傳送。9 UDP處理UDP是一個簡單的協(xié)議,用來完成

39、不同處理過程間的包分離。每一個UD話路(session)的狀態(tài)都被保留在一個PCB結構中,如圖7所示。UDP PCBs保存在一個鏈表中,當UDP datagram 到達,則搜索該鏈表并進行匹配。UDP PCE結構中包含一個指向全局 UDP PC鏈表中的下一個 PCB的指針。UD話路(session) 由IP地址和端口號來定義,并且被存放在 local_ip, dest_ip,local_port,dest_port域中。Flags域指出這一話路(session )將使用什么樣的UDP校驗和策略。這可能既沒關掉UDPchecksumming完全,或者使用UDP輕便在哪個檢驗數(shù)字蓋住只數(shù)據(jù)報的部分

40、。This can beeither to switch UDP checksumming off completely, or to use UDP Lite LDP99 in which the checksum covers only parts of the datagram. If UDP Lite is used, the chksum len field specifies how much of the datagram that should be checksummed.當接收到由PC標明的session中的datagram時,最后二個參數(shù)recv和recv_arg將被使用

41、。當 接收到datagram時,recv所指向的函數(shù)被調(diào)用。struct udp p<b <fltruct udp.pcb next;struex ip_jddr local_ip, dos_ip;ul6_t local.port, doet_port;u8_r flaga;chkoum .Lcn;void ( recv)(void +arg, struct udp_pcbstruct pbuf *p);void +rcv_ar;Fixurr 7. /he tdp.pcb truilur*由于UD較為簡單,輸入和輸出處理也較簡單,如圖8所示。Applicaiion ta)rFigu

42、re 8. UDP proix/stiu巖當收到一個UDP datagram時,IP層調(diào)用udp_input()函數(shù)。這里,如果session應該使用 checksumming UDP checksum)各被檢查同時datagram被分離。當發(fā)現(xiàn)相應的UDP PCB recv函數(shù) 被調(diào)用。10 TCP處理TCP為傳輸層協(xié)議它為應用層提供可靠的二進制數(shù)據(jù)流服務。TCP協(xié)議比這里描述的其它協(xié)議都要復雜,并且TCP代碼占lwIP總代碼的50%10.1總述基本TCP 處理(圖9)被劃分成六個函數(shù);函數(shù) tcp_input() 、tcp_process()、tcp_receive() 與TCP 輸入處理

43、有關,tcp_write()、tcp_enqueue()、tcp_output()對輸出進行處理。Figure 9. TCP proccsin當應用程序想要發(fā)送TCP數(shù)據(jù),函數(shù)tcp_write()將被調(diào)用。函數(shù)tcp_write() 將控制權交給 tcp_enqueue(),該函數(shù)將數(shù)據(jù)分成合適大小的TCP(如果必要),并放進發(fā)送隊列。接下來函數(shù)tcp_output()將檢查數(shù)據(jù)是否可以發(fā)送。也就是說,如果接收器的窗口有足夠的空間并且擁塞窗口足夠大,則使用ip_route()和ip_output_if()兩個函數(shù)發(fā)送數(shù)據(jù)。當ipnput()對IP報頭進行檢驗且把TCP移交給tcp_input

44、()函數(shù)后,輸入處理開始。在該函數(shù)中將進行初始檢驗(也就是,checksumming和TCP剖析析)并決定該段屬于哪個TCP!接。 該段于是由tcp_process()處理,它實現(xiàn)TCP狀態(tài)機和其他任何必須的狀態(tài)轉換。如果一個連接處于從網(wǎng)絡接收數(shù)據(jù)的狀態(tài),函數(shù) tcp_receive() 將被調(diào)用。 如果那樣 , tcp_receive() 將 把段上傳給應用程序。 如果段構成未應答數(shù)據(jù)(先前放入緩沖區(qū)的)的 ACK, 數(shù)據(jù)將從緩沖被 移走并且收回該存儲區(qū)。同樣,如果接收到請求數(shù)據(jù)的ACK接收者可能希望接收更多的數(shù)據(jù),這時tcp_output()將被調(diào)用。10.2 數(shù)據(jù)結構由于小型嵌入式系統(tǒng)內(nèi)

45、存的限制,LWIP所使用的數(shù)據(jù)結構被故意縮小。這是在數(shù)據(jù)結構復雜度與使用數(shù)據(jù)結構的代碼的復雜度之間的一個折衷。這樣就因為要保證數(shù)據(jù)結構的小巧而使代 碼復雜性增加。TCP PC相當大,如圖10。因為TCP連接在處于監(jiān)聽(listen )和時間等待(TIME-WAIT 狀態(tài)時比處于其他狀態(tài)的連接需要保留較少狀態(tài)信息,對于這些連接使用了一種更小的PCB數(shù)據(jù)結構。這種數(shù)據(jù)結構鑲嵌在完整的PCB結構中,在PCB結構中的排列持續(xù)如圖10,因此有 些笨拙。TCP PCBs被保留在一份鏈表中,并且next指針把PCB表連接在一起。 狀態(tài)變量包含當 前連接的TCP狀態(tài)。其次,辨認連接的IP地址和端口號被保存。m

46、ss變量保存連接所允許的 最大段大小。當接受數(shù)據(jù)時,rcv_nxt和rcv_wnd域被使用。rcv_nxt域包含期望從遙端的下個順序編號(contains the n ext seque nee nu mber expected from the remote end),因而當發(fā)送 ACKs 至 U 遠程主機時被使用。接收器的窗口被保留在rcv_wnd中,并且在將要發(fā)出的TCP段中被告知。tmr 被作為定時器使用,在經(jīng)過一特定時間后連接應該被取消 , 譬如連接在 TIME-WAIT 狀態(tài)。 連接 所允許的最大段大小被存放在 mss域中。Flags域包含連接的附加狀態(tài)信息,譬如連接是否為 快速恢

47、復或被延遲的ACI是否被發(fā)送。struct tcp_pcb struct tcp.pcb *neit;enum tcp_state state;/* TCP state */void C+ accept(void *azgT struct tcp_pcb *newpcb); void *acceptarg;struct ip.addr Local_ip;ulSt lccalport;ul6tdast_port;uS2_trcv_nxt h rcv_und;/*ul6_ttmr;u32_.ttnss;/*u8_tul6_.trttest;/*u32_rtrtseq;/*s32_Lc/*U32_.

48、trto;/*u32_-tlastack;/+u8_t. dupacks;/*u32_t cvndt u32_t ssthresh; u32_t snd.ack, and_nxt,/*3nd_wnd, snd_wll» snd_wl2Jmaximum segment size */struct ip_addr dest_ip;rtt eatimation */ squnc no for rtt estimation */ rut輕w and vaiIcmce */retransiiiissioti time-out */ last ACK received +/ number of

49、duplicate ACKe */ /* congestion control variables */ sender variables */ snd_lbb;void C+ recv)(void *arg, struct tcp_pcb +pcb, struct pbnf +p)j void *recv_arg;struct tcp_seg *unsentt *unacked. /* queues */*ooseq;Figure 10. I ho tcp_pcb structur域rttest, rtseq, sa,和sv被使用為round-trip時間估計。用于估計的段順序號存儲在rts

50、eq ,該段被發(fā)送的時間存放在rttest 。平均round-trip時間和round-trip時間變化分別 存放在sa和sv 。這些變量被用來計算存放在rto域中的轉播暫停(retransmissiontime-out )。二個域lastack 和dupacks被用來實現(xiàn)快速轉播和快速重發(fā)。lastack包含由最后接受到的ACK應答的順序編號,dupacks對接收到多少關于存儲在lastack的順序編號的ACK進行計數(shù)。當 前連接的阻塞窗口被存放在cwnc域,并且緩慢的起動門限被保留在ssthresh 。六個域 snd_ack、snd_nxt、snd_wnd snd_wl1、snd_wl2和

51、snd_lbb 在發(fā)送數(shù)據(jù)時使用。由接收器應答的最高的順序編號被存放在sn d_ack,并且下個被發(fā)送的順序編號保存在sn d_nxt。接收器的廣告窗口(advertisedwindow)保存在snd_wnd,兩域snd_wl1 和snd_wl2在更新snd_wn時使用。Snd_lbb域包含發(fā)送隊列最后字節(jié)的順序編號。當傳遞接受的數(shù)據(jù)到應用層時將使用函數(shù)指針recv和recv_arg。三個隊列unsent, unacked和oose q當發(fā)送和接受數(shù)據(jù)時被使用。已經(jīng)從應用接收但未被發(fā)送的數(shù)據(jù)由隊列 un se nt進行排 隊,已發(fā)送但還沒有被遠程主機應答(acknowledged)的數(shù)據(jù)由un

52、acked 存儲。接收的序列外 面的數(shù)據(jù)由ooseq進行緩沖。struct tcp.seg struct tcp.seg *naxt;ui6_t len;struct pbuf *p;struct tcp_lidr *tcphdr; void *data;ul6_t rtiaw;h11, The tcp.se j stnicture表11中的Tcp_seg 結構是TCP段的內(nèi)部表示方法。這個結構由一個next指針開始,該指針用于連接排隊段。len域包含段的長度。這意味著一個數(shù)據(jù)段的len域將包含段中數(shù)據(jù)的長度,具 有SY!或FIN標志的空段的len被設置為1 。 pbuf結構類型指針p是包含實

53、際段、tcphdr、指向 TC陜的數(shù)據(jù)指針和數(shù)據(jù)段的緩沖。分別的,對于將要外發(fā)的段,rtime域被用于該段的轉播暫停。因為接收的段不會需要被轉播,對于接收段來說這個域并不需要并且也不為該域分配內(nèi) 存。10.3 順序編好計算(Sequenee number calculations)用于枚舉 TCP二進制數(shù)據(jù)流的TCP順序編號為無符號32位數(shù)據(jù),因此其范圍是 。32因為在TCP連接中要發(fā)送字節(jié)的數(shù)量可能會比32 位組合的數(shù)量更多,順序編號以2為模數(shù)進行 計算。這意味著,普通的比較操作符無法被TCP順序編號使用。修改過的比較操作符,叫做 <seq和>seq,由下面關系定義:S <

54、A£q t S t < 0S >BCq f 臺井一 t > CL這里s和t是TCP順序編號。比較操作符w仝也等效地被定義。比較操作符作為C宏指令被定義在標頭文件。10.4隊列和發(fā)送數(shù)據(jù)將要發(fā)送的數(shù)據(jù)被劃分成適當?shù)拇笮〉拇髩K并tcp_e nqueue()指定順序編號。這里,數(shù)據(jù)被打包進pbufs結構并附加進tcp_seg結構。在pbuf內(nèi),TCP頭被建立,并且除應答數(shù)字,ack no 和廣播窗口,wnd以外的所有域被填充。這些域在段排隊時可以被改變,并由tcp_output()進 行設置,該函數(shù)完成段的實際傳輸。在段被建立之后,他們被送往PCB里的unsent列表進行

55、排隊。函數(shù)tcp_enqueue()設法用最大段大小的數(shù)據(jù)填裝各段直到在 unsent隊列的末端發(fā)現(xiàn)段under-full,該段使用pbuf chaining functionality功能被添附以新數(shù)據(jù)。在tcp_enqueue() 格式化和排隊了段之后,tcp_output()函數(shù)被調(diào)用。它檢查在當前的窗口中 是否還有空間來存儲更多的數(shù)據(jù)。當前窗口的數(shù)值是通過窗口數(shù)據(jù)擁擠的最大量和接收窗口的 廣播。 (It checks if there is any room in the current window for any more data. The curre nt window is

56、computed by tak ing the maximum of the con gesti on window and the advertised receiver's window )。其次,它填裝由 tcp_enqueue() 未填裝的 TCP頭的域,并 且使用ip_route()和ip_output_if()傳送段。在段被放入傳輸后unacked表后,停留直到該段的AC被接收到。當段放入unacked 表的同時,如在10.8部分所描述同時也為重發(fā)計時。當段需重發(fā)時原來的TCP IP頭被保留,只需對TCP頭做少量變化。TCP頭的ackno和wnc域被設置 為當前值,因為在段的原始傳輸和重發(fā)期間我們可能接收了數(shù)據(jù)。這只改變報頭里的二個16位字和整體TCP checksum不必要重新計算,因為簡單的算術Rij94 可以用來更新checksun。當段最初被傳送時,IP層已經(jīng)增加了 IP頭,并且沒有理由改變它。因而重發(fā)不要求IP頭的checksum.的任何重發(fā)計算。Silly Window Syndrome Cla82b (SWS)綜合癥狀 Cla82b

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論