LWIP協(xié)議棧的分析和設(shè)計_第1頁
LWIP協(xié)議棧的分析和設(shè)計_第2頁
LWIP協(xié)議棧的分析和設(shè)計_第3頁
LWIP協(xié)議棧的分析和設(shè)計_第4頁
LWIP協(xié)議棧的分析和設(shè)計_第5頁
已閱讀5頁,還剩9頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

《計算機網(wǎng)絡(luò)與控制》LWIP協(xié)議棧的分析摘要近些年來,隨著互聯(lián)網(wǎng)和通訊技術(shù)的迅猛發(fā)展,除了計算機之外,大量的嵌入式設(shè)備也需求接入網(wǎng)絡(luò)。目前,互聯(lián)網(wǎng)中使用的通訊協(xié)議基本是TCP/IP協(xié)議族,可運行于不同的網(wǎng)絡(luò)上,本文研究的就是嵌入式TCP/IP協(xié)議棧LWIP。文章首先分析了LWIP的整體結(jié)構(gòu)和協(xié)議棧的實現(xiàn),再介紹協(xié)議棧的內(nèi)存管理,最后講解協(xié)議棧應(yīng)用程序接口。關(guān)鍵詞:嵌入式系統(tǒng);協(xié)議;LWIP;以太網(wǎng)AbstractWiththerapiddevelopmentofinternetandcommunicationtechnology,Notonlycomputersbutalsoembededequipmentsareneedtoconnectnetworks.Atpresent,thebasiccommunicationprotocolusingininternetisTCP/IP,itcanrunindifferentnetwork.ThispaperanalysestheLight-WeightTCP/IP.Theprocessmodelofaprotocolimplementationandprocessingofeverylayeraredescribedfirst,andthengivesthedetailedmanagementofBufferandmemory.Atlast,areferencelwIPAPIisgiven.Keywords:EmbeddedSystem,Protocol,LightweightTCP/IP,Ethernet引言近期互聯(lián)網(wǎng)絡(luò)硬件、軟件的迅猛發(fā)展,使得網(wǎng)絡(luò)用戶呈指數(shù)增長,在使用計算機進行網(wǎng)絡(luò)互聯(lián)的同時,各種家電設(shè)備、儀器儀表以及工業(yè)生產(chǎn)中的數(shù)據(jù)采集與控制設(shè)備在逐步地走向網(wǎng)絡(luò)化,以便共享網(wǎng)絡(luò)中龐大的信息資源。在電子設(shè)備日趨網(wǎng)絡(luò)化的背景下,引人TCP/IP協(xié)議棧,以支持嵌人式設(shè)備接人網(wǎng)絡(luò),成為嵌人式領(lǐng)域重要的研究方向。本文分析一個輕量級的嵌入式系統(tǒng)的TCP/IP協(xié)議棧-LWIP,LWIP是一個比較完整和可靠的TCP/IP協(xié)議棧,具有開源,易用,系統(tǒng)資源要求不高等優(yōu)點。一、LWIP概覽LWIP是瑞典計算機科學(xué)院(SwedishInstituteofComputerScience)開發(fā)的一套用于嵌入式系統(tǒng)的開放源代碼TCP/IP協(xié)議棧。LWIP的含義是LightWeight(輕型)IP協(xié)議。LWIPTCP/IP實現(xiàn)的重點是在保持TCP協(xié)議主要功能的基礎(chǔ)上減少處理和內(nèi)存需求,因為LWIP使用無順數(shù)據(jù)復(fù)制并經(jīng)裁剪的API,一般它只需要幾十KB的RAM和40KB左右的ROM就可以運行。同時LWIP可以移植到操作系統(tǒng)上,也可以在無操作系統(tǒng)的情況下獨立運行。這使LWIP協(xié)議棧適合在低端嵌入式系統(tǒng)中使用。LWIP的特性如下:支持多網(wǎng)絡(luò)接口下的IP轉(zhuǎn)發(fā);支持ICMP協(xié)議;支持主機和路由器進行多播的Internet組管理協(xié)議(IGMP);包括實驗性擴展的UDP(用戶數(shù)據(jù)報協(xié)議);包括阻塞控制,RTT估算和快速恢復(fù)和快速轉(zhuǎn)發(fā)的TCP;提供專門的內(nèi)部回調(diào)接口(rawAPI)用;支持DNS;支持SNMP;支持PPP;支持ARP;IPfragment的支持;支持DHCP協(xié)議,動態(tài)分配IP地址;可選擇的Berkeley接口API(多線程情況下);LWIP的源代碼從作者AdamDunkels的官方網(wǎng)站上下載(網(wǎng)址為:www.sics.se/~adam/lwip/),版本號為1.3.1。以下為解壓后的目錄結(jié)構(gòu)。LWIP的目錄結(jié)構(gòu)主要分為五個部分:Api\:應(yīng)用程序接口文件,包括RAW,BSD以及正式提供的3種API。Arch\:與硬件和OS有關(guān)的文件,包括網(wǎng)絡(luò)驅(qū)動,移植需要修改的文件。Core\:ICMP,IP,TCP,UDP協(xié)議的實現(xiàn)文件,以及一些輔助函數(shù),LWIP實現(xiàn)的核心代碼。Include\:LWIP的包括文件。Netif\:ARP協(xié)議和LWIP網(wǎng)絡(luò)設(shè)備驅(qū)動程序的模板,用戶為自己的網(wǎng)絡(luò)接口設(shè)計的驅(qū)動程序應(yīng)該與ethernetif.c中給出的驅(qū)動框架相同。二、LwIP的整體構(gòu)架和進程模型:傳統(tǒng)的TCP/IP協(xié)議棧的實現(xiàn)方法嚴格分層,一般每一層都是一個獨立的進程。這樣方法雖然

有利于協(xié)議棧的調(diào)試,但是,其最大的弊端為數(shù)據(jù)包跨層傳遞時會引起頻繁的上下文的切換,尤其是在多任務(wù)系統(tǒng)中,這樣導(dǎo)致時間的浪費而直接影響到系統(tǒng)的實時性。LWIP將所有TCP/IP協(xié)議都放在在一個進程當中,這樣TCP/IP協(xié)議棧就和操作系統(tǒng)內(nèi)核分開了。而應(yīng)用層程序既可以是單獨的進程也可以駐留在TCP/IP進程中。如果應(yīng)用程序是單獨的進程,可以通過操作系統(tǒng)的郵箱、消息隊列等通訊機制和TCP/IP進程進行通訊。如果應(yīng)用層程序駐留在TCP/IP程中,那應(yīng)用層程序就利用內(nèi)部回調(diào)函數(shù)接口(RawAPI)和TCP/IP協(xié)議棧通訊。LWIP進程模式的主要優(yōu)點是可以很方“tcpip_thread”任務(wù)中,而位于圖中最上方的'Applicationlayer”(應(yīng)用層)和下方的“Networkinterfacelayer”(網(wǎng)絡(luò)接口驅(qū)動層)由用戶自己來實現(xiàn)。應(yīng)用層程序既可以是獨立的任務(wù)(如圖中正上方的“tftp_thread”和“tcpecho_thread”),通過mbox(消息隊列)和LWIP進程通訊;也可以在“tcpip_thread”(如圖左上角)中利用原始接口(RawAPI)和TCP/IP協(xié)議棧通訊。LWIP的數(shù)據(jù)流程主要分為接收和發(fā)送兩種情況。?接收數(shù)據(jù)時:數(shù)據(jù)包從一個網(wǎng)絡(luò)接口被接收,如果網(wǎng)絡(luò)接口驅(qū)動通過low_level_input函數(shù)讀到這個數(shù)據(jù)包,簡單的區(qū)分是ARP包還是IP包。如果是ARP包,將調(diào)用ARP的功能處理這個包。通常將更新一個ARP地址映射表,然后將數(shù)據(jù)包發(fā)送給IP_input函數(shù)處理。如是查一個IP包,將把數(shù)據(jù)包發(fā)送給ip_input函數(shù)處理。IP_input函數(shù)將數(shù)據(jù)包進行簡單的處理(如計算校驗和)后,分析該包是發(fā)送到本機的正常數(shù)據(jù)包,IP_input則根據(jù)包的類型,分別發(fā)送給udp_input、tcp_input、icmp_input函數(shù)處理。如果是發(fā)送給UDP或TCP協(xié)議的數(shù)據(jù)包,UDP、TCP協(xié)議的處理函數(shù)將做相應(yīng)的處理,最后發(fā)送給應(yīng)用程序。?發(fā)送數(shù)據(jù)流程:當應(yīng)用程序需要發(fā)送一個數(shù)據(jù)包的時候,它將調(diào)用UDP和TCP協(xié)議處理函數(shù)udp_sender或tcp_write函數(shù)發(fā)送該數(shù)據(jù)包。UDP和TCP協(xié)議的處理函數(shù)接收數(shù)據(jù)后,將數(shù)據(jù)打包、分段,然后發(fā)送給IP層ip_output_if函數(shù)(需要時,將調(diào)用ip_route函數(shù)進行路由選擇),該函數(shù)把數(shù)據(jù)打包、封裝,然后調(diào)用網(wǎng)絡(luò)接口驅(qū)動的low_level_output函數(shù)傳給網(wǎng)絡(luò)接口。三、LWIP協(xié)議棧的實現(xiàn)3.1網(wǎng)絡(luò)接口LwIP使用一個與BSD中相似的網(wǎng)絡(luò)接口結(jié)構(gòu)來表示底層網(wǎng)絡(luò)驅(qū)動,結(jié)構(gòu)體的原型定義如下所示。structnetif{structnetif*next;charname[2];intnum;structip_addrip_addr;structip_addrnetmask;structip_addrgw;void(*input)(structpbuf*p,structnetif*inp);int(*output)(structnetif*netif,structpbuf*p,structip_addr*ipaddr);void*state;}next指針用于將網(wǎng)絡(luò)接口鏈入到全局鏈表中。Name域用于表示網(wǎng)絡(luò)接口的類型,只用于這個接口在運行時由人工操作進行配置。Name由設(shè)備驅(qū)動設(shè)置并且應(yīng)該反映硬件的種類。num用來區(qū)分相同類別的不同網(wǎng)絡(luò)接口。三個IP地址ip_addr,netmask與gw分別用來表示IP地址,子網(wǎng)掩碼,網(wǎng)關(guān)。State表示設(shè)備驅(qū)動所包含的網(wǎng)絡(luò)接口狀態(tài),由設(shè)備驅(qū)動設(shè)置。當設(shè)備驅(qū)動接受到一個信息包的時候需要調(diào)用input指向的函數(shù)。而網(wǎng)絡(luò)接口通過output指針與設(shè)備驅(qū)動連接。這個指針指向處于設(shè)備驅(qū)動中的發(fā)送信息包的函數(shù),這個函數(shù)將在一個信息包發(fā)送出去后,被IP層調(diào)用。指針output將在設(shè)備驅(qū)動初始化的時候賦值。3.2IP處理LwIP僅實現(xiàn)了IP層大部分的基本功能,能夠發(fā)送、接收以及轉(zhuǎn)發(fā)信息包,但是不能接收和發(fā)送IP分片包,也不能處理攜帶IP參數(shù)選項的信息包。不過對大多數(shù)的應(yīng)用來說,這不會引起任何問題。?接收信息包收到的IP信息包,由網(wǎng)絡(luò)設(shè)備驅(qū)動調(diào)用ip_input()函數(shù)開始處理。在這里完成對IP版本字段及包頭長度的初始完整性檢查,同時還要計算和驗證包頭校驗和。協(xié)議棧假定代理會重新組合IP分片包為一個完整的包。接下來,函數(shù)檢查目的地址是否與網(wǎng)絡(luò)接口的IP地址相符以確定信息包是否到達預(yù)定主機。網(wǎng)絡(luò)接口在鏈表中被排序并且采用了線性檢索。如果一個到達的信息包被發(fā)現(xiàn)已經(jīng)到達了目的主機,則由協(xié)議字段來決定信息包應(yīng)該傳送到哪一個上層協(xié)議。?發(fā)送信息包外發(fā)的信息包由ip_output()函數(shù)處理,該函數(shù)使用ip_route()函數(shù)查找適當?shù)木W(wǎng)絡(luò)接口來傳送信息包。當外發(fā)的網(wǎng)絡(luò)接口確定后,信息包傳給以外發(fā)網(wǎng)絡(luò)接口為參數(shù)的ip_output_if()函數(shù)。-5-在這里,所有的IP包頭字段被填充,并且計算IP包頭校驗和°IP信息包的源及目標地址作為參數(shù)被傳遞給ip_output_if()函數(shù)。?轉(zhuǎn)發(fā)信息包如果沒有網(wǎng)絡(luò)接口的地址與到達的信息包的目標地址相同,信息包應(yīng)該被轉(zhuǎn)發(fā)。這項工作由ip_forward()函數(shù)完成。在這里,TTL字段值被減少(TimeToLive的簡寫,生存時間的意思,譯者注),當減為0的時候,將會給IP信息包的最初發(fā)送者發(fā)送ICMP錯誤信息,并拋棄該信息包。最后,信息包被轉(zhuǎn)發(fā)到適當?shù)木W(wǎng)絡(luò)接口。查找適當?shù)木W(wǎng)絡(luò)接口的算法與發(fā)送信息包使用的算法相同。?ICMP處理網(wǎng)際控制報文協(xié)議ICMP(IntemetControlMessageProtoc01)總是與IP協(xié)議配置在一起,它運行在IP協(xié)議之上,發(fā)送一些控制信息,幫助Intemet處理差錯。ICMP處理是相當簡單的。由ip_input()收到的ICMP包被移交到icmp—input(),它解析ICMP報頭并且進行適當?shù)奶幚?。ICMP處理過程如圖3-1所示7i,心zspoE:layer圖3-1ICMP處理3.3UDP處理用戶數(shù)據(jù)報協(xié)議UDP(UserDatagramProtoc01)較為簡單,輸出處理也較簡單,基本的UDP處理過程被分割為三個功能函數(shù)來實現(xiàn):如圖3-2所示。udp_input()函數(shù)與UDP輸入有關(guān)udp_send()及udp_output()則用于UDP輸出圖3-2UDP處理3.4TCP處理傳輸層控制協(xié)議TCP為應(yīng)用層提供可靠的二進制數(shù)據(jù)流服務(wù)。TCP協(xié)議比這里描述的其它協(xié)議

都要復(fù)雜,基本TCP處理如圖3-3所示,被劃分成六個函數(shù):函數(shù)tcp_input()、tcp_process()、tep_receive()與TCP輸入處理有關(guān);tep_write()、top_enqueue()、tcp_output()對輸出進行處理。當應(yīng)用程序想要發(fā)送TCP數(shù)據(jù)時,函數(shù)tcp_write()將被調(diào)用,函數(shù)tcp_write()將控制權(quán)交給tcp_enqueue(),該函數(shù)將數(shù)據(jù)分成合適大小的TCP段(如果必要),并放進發(fā)送隊列。接下來函數(shù)top_output()將檢查數(shù)據(jù)是否可以發(fā)送。也就是說,如果接收器的窗口有足夠的空間并且擁塞窗口足夠大,則使用ip_route()和ip_output_if()兩個函數(shù)發(fā)送數(shù)據(jù)。當ip_input()對IP報頭進行檢驗且把TCP段移交給tcp_input()函數(shù)后,輸入處理開始。在該函數(shù)中將進行初始檢驗(也就是checksumming和TCP剖析)并決定該段屬于哪個TCP連接。該段于是由tcp_process()處理,它實現(xiàn)TCP狀態(tài)機和其他任何必須的狀態(tài)轉(zhuǎn)換。如果一個連接處于從網(wǎng)絡(luò)接收數(shù)據(jù)的狀態(tài),函數(shù)tcp_receive()將被調(diào)用。如果那樣,tcp_receive()將把段上傳給應(yīng)用程序。如果段構(gòu)成未應(yīng)答數(shù)據(jù)(先前放入緩沖區(qū)的)的ACK,數(shù)據(jù)將從緩沖被移走并且收回該存儲區(qū)。同樣,如果接收到請求數(shù)據(jù)的ACK,接收者可能希望接收更多的數(shù)據(jù),這時tcp_output()將被調(diào)用。圖3圖3-3TCP處理四、LWIP協(xié)議棧的內(nèi)存管理4.1LWIP協(xié)議棧中pbuf介紹TCP/IP是一種基于OSI參考模型的分層網(wǎng)絡(luò)體系結(jié)構(gòu),它由應(yīng)用層、運輸層、網(wǎng)絡(luò)層、數(shù)據(jù)鏈路層、物理層組成。各層之間消息的傳遞通過數(shù)據(jù)報的形式進行。由于各層之間報頭長度不一樣,當數(shù)據(jù)在不同協(xié)議層之間傳遞時,對數(shù)據(jù)進行封裝和去封裝、增加和刪除操作將十分頻繁。因此,必須有一種能適應(yīng)數(shù)據(jù)動態(tài)增刪、但在邏輯上又呈現(xiàn)連續(xù)性的數(shù)據(jù)結(jié)構(gòu),以滿足在各協(xié)議層之間傳遞數(shù)據(jù)而不需要進行內(nèi)存拷貝。嵌人式TCP/IP協(xié)議棧要求簡單高效,并減少對內(nèi)存的需求。這些都需要相應(yīng)的內(nèi)存管理機制實現(xiàn)。LwIP利用pbuf結(jié)構(gòu)實現(xiàn)數(shù)據(jù)傳遞,它與BSD中的Mbuf很相似。pbuf的主要用途是保存在應(yīng)用程序和網(wǎng)絡(luò)接口間互相傳遞的用戶數(shù)據(jù)。pbuf的內(nèi)部結(jié)構(gòu)為:structpbuf{pbuf*next;*payload;tot_len;len;pbuf*next;*payload;tot_len;len;*指向下一個pbuf*/*指向pbuf數(shù)據(jù)中的起始位置*1*該pbuf和后續(xù)pbuf中數(shù)據(jù).長度的總和*/*該pbuf中數(shù)據(jù)的長度*/////voidul6_tu16t

u16-t flags; /*pbuf的類型*/ul6_t ref; /*該pbuf被引用的次數(shù)*/}4.2LWIP內(nèi)存管理的實現(xiàn)在運行TCP/IP協(xié)議棧的嵌人式系統(tǒng)中,可以把整個系統(tǒng)的存儲區(qū)域分為協(xié)議棧管理的存儲器和應(yīng)用程序管理的存儲器兩部分。4.2.1協(xié)議棧管理的存儲器協(xié)議棧管理的存儲器是指TCP/IP內(nèi)核能夠操作的內(nèi)存區(qū)域,主要用于裝載待接收和發(fā)送的網(wǎng)絡(luò)數(shù)據(jù)分組。當接收到分組或者有分組要發(fā)送時,TCP/IP協(xié)議棧為這些分組分配緩存;接收到的分組交付給應(yīng)用程序或者分組已經(jīng)發(fā)送完畢后,對分配的緩存回收重用。協(xié)議棧分配的緩存必須能容納各種大小的報文,例如從僅僅幾個字節(jié)的ICMP回答報文到幾百個字節(jié)的TCP分段報文。LWIP中的pbuf有四種類型;PBUF_POOL、PBUF_RAM、PBUF_ROM、PBUF_REF。這四種類型的pbuf都是從TCP/IP協(xié)議棧管理的存儲器中分配的,其中PBUF_ROM和PBUF_REF與應(yīng)用程序管理的存儲區(qū)域密切相關(guān)。PBUF_POOL是具有固定容量的pbuf,主要供網(wǎng)絡(luò)設(shè)備驅(qū)動使用,為收到的數(shù)據(jù)分組分配緩存。在協(xié)議棧管理的內(nèi)存中初始化了一個pbuf池(PBUF_POOL),具有相同尺寸的pbuf都是從這個pbuf池中分配得到。一般使用多個PBUF_POOL鏈接成一個鏈表,用于存儲數(shù)據(jù)分組。如圖1所示。next *next 物payloadpayloadpayloadto—kmtotjenlotj-ennext *next 物payloadpayloadpayloadto—kmtotjenlotj-enJenlenn略fl咿噂rtf研iwtuforlinkheader——roomforIPheaderrromiorTCPIteaderLwIP用一個宏定義一個PBUF_POOL的大小。一個分組需要分配幾個PBUF_POOL,而在數(shù)據(jù)較少時分配一個PBUF_POOL即可。由于分配一個PBUF_POOL類型的pbuf很快,適合在中斷處理中使用,所以PBUFPOOL主要供網(wǎng)絡(luò)設(shè)備驅(qū)動使用,為收到的數(shù)據(jù)分組分配緩存。nejdused-1pW日或或prevuscd^Onextpre%1used-1圖4-2內(nèi)存堆應(yīng)用程序發(fā)送動態(tài)產(chǎn)生的數(shù)據(jù)時,可以用PBUF_RAM類型的pbuf。PBUF_RAM在事先劃分好的內(nèi)存堆中分配。對該內(nèi)存堆的操作類似于C語言中的malloc/free。內(nèi)存堆分配的結(jié)構(gòu)如圖4-2所示。圖2中每個被分配的存儲塊附帶了一個小結(jié)構(gòu),該結(jié)構(gòu)的兩個指針指向相鄰的內(nèi)存塊。usednejdused-1pW日或或prevuscd^Onextpre%1used-1圖4-2內(nèi)存堆PBUF_POOL和PBUF_RAM都可以根據(jù)需要從存儲器中動態(tài)分配,這種分配機制又稱為動態(tài)存儲器分配機制。該分配機制不僅能為應(yīng)用程序的數(shù)據(jù)分配存儲空間,而且能為協(xié)議首部分配存儲空間。在層與層之間傳遞數(shù)據(jù)時,真正需要修改的只是數(shù)據(jù)的格式,使之符合各層的規(guī)范,而數(shù)據(jù)本身不需要變動。實際上數(shù)據(jù)格式反應(yīng)的是各層的首部,當數(shù)據(jù)在各層之間傳送時,需要動態(tài)地添加和移去相應(yīng)的首部,用動態(tài)分配機制可以很好地實現(xiàn)。4.2.1應(yīng)用程序管理的存儲器應(yīng)用程序管理的存儲器是指應(yīng)用程序管理、操作的存儲區(qū)域,二般從該區(qū)域為應(yīng)用程序發(fā)送數(shù)據(jù)分配緩存。雖然該存儲區(qū)域不由TCP/IP協(xié)議棧管理,但在不嚴格分層的協(xié)議棧中,該存儲區(qū)域必須與TCP/IP管理的存儲器協(xié)同工作。為節(jié)省內(nèi)存,LWIP不采取分級訪問模式,而是通過指針訪問數(shù)據(jù)。這樣就不需要為數(shù)據(jù)的傳遞分配存儲空間。應(yīng)用程序發(fā)送的數(shù)據(jù)在交付LWIP后,LWIP就認為這些數(shù)據(jù)是不能被改動的,因此應(yīng)用程序的數(shù)據(jù)被認為是永遠存在并且不能被改變的。這一點與ROM很相似。類型名PBUF_ROM也由此而來。如圖4-3所示,PBUF_ROM的數(shù)據(jù)指針payload指向Externalmemory(外部存儲區(qū))。Externalmemory指不由TCP/IP協(xié)議棧管理的存儲區(qū),它可以是應(yīng)用程序管理的存儲器為用戶數(shù)據(jù)分配的緩存,也可以是ROM區(qū)域,如靜態(tài)網(wǎng)頁中的字符串常量等。由于由應(yīng)用程序交付的數(shù)據(jù)不能被改動,因此就需要動態(tài)地分配一個PBUF_RAM來裝載協(xié)議的首圖4-3PBUFRAM與PBUFROM的連接圖4-3中的PBUF_ROM還可以是PBUF_REF。PBUF_REF和PBUF_ROM的特性非常相似,都可以實現(xiàn)數(shù)據(jù)的零拷貝。但是當發(fā)送的數(shù)據(jù)需要排隊時就表現(xiàn)出PBUF_REF的特性了。例如在發(fā)送分組時,待發(fā)送的分組需要在ARP隊列中排隊,假如這些分組中有PBUF_ROM類型的pbuf,則說明該類型pbuf中的數(shù)據(jù)位于應(yīng)用程序的存儲區(qū)域,是通過指針被PBUF_ROM引用的。這樣直到分組被處理之前,被引用的應(yīng)用程序的這塊存儲區(qū)域都不能另作它用。在此情況下要用到PBUF_REF類型的pbuf。在排隊時,LWIP會為PBUF_REF類型的pbuf分配緩存(PBUF_POOL或PBUF_RAM),并將引用的應(yīng)用程序的數(shù)據(jù)拷貝到分配的緩存中。這樣應(yīng)用程序中被引用數(shù)據(jù)的存儲區(qū)域就能被釋放。pbuf結(jié)構(gòu)實現(xiàn)了層與層之間的數(shù)據(jù)傳遞,但其非常消耗內(nèi)存,并且需要TCP/IP協(xié)議棧為之分配存儲空間,例如協(xié)議控制udp_pcb,tcp-pcb等。通常,嵌人式TCP/IP協(xié)議棧都不是嚴格分層的,盡量減少對內(nèi)存的需求是實現(xiàn)嵌人式TCP/IP的重點,內(nèi)核的內(nèi)存管理機制直接關(guān)系到嵌人式TCP/IP協(xié)議棧的性能。五、LWIP的應(yīng)用編程接口(API)LwIP為我們提供了三種應(yīng)用程序接口(API函數(shù))來實現(xiàn)TCP/IP協(xié)議棧,它們分別是:low-level"core"/"callback"or"raw"API.是一種低水平的、基于回調(diào)函數(shù)的API(后面直接稱RAWAPI),整個通信流程依靠協(xié)議棧里的回調(diào)函數(shù)來驅(qū)動。因為回調(diào)函數(shù)的調(diào)用不能超越任務(wù)邊界,這樣應(yīng)用程序和TCP/IP協(xié)議棧必須運行在同一個任務(wù)中,而用戶不再增加其它的任務(wù),應(yīng)用程序直接在TCP/IP任務(wù)空間運行。因此,就要避免調(diào)用諸如掛起、等待的函數(shù),以防止整個TCP/IP任務(wù)被掛起。RAWAPI接口函數(shù)不僅在程序代碼的執(zhí)行時間上更快,而且在運行中它也占用更少的內(nèi)存資源。唯一的缺點是應(yīng)用程序的編寫比較困難,并且代碼較難理解。盡管如此,在CODE和RAM都較小的嵌入式系統(tǒng)中,這也是我們優(yōu)先考慮采用的方法。higher-level"sequential"API/LWIPAPI是一種高水平的、連續(xù)的API,LWIPAPI為我們提供了一種通用的方法,它與BSD標準的socketAPI非常相似,程序的執(zhí)行過程同樣是基于"open-read-write-close”模型的,但操作相對低級。API不需要在應(yīng)用程序和協(xié)議棧之間復(fù)制數(shù)據(jù),因為應(yīng)用程序可以巧妙的直接處理內(nèi)部緩沖區(qū)。(充分利用LwIP的內(nèi)部結(jié)構(gòu)以實現(xiàn)其設(shè)計目標)因為BSDSocketAPI易于理解,并且很多應(yīng)用程序為它而寫,所以LwIP保留一個BSDSocket兼容層是很有用的。盡管LwIP與BSDSocketAPI非常相似,但是它們之間仍然存在著值得注意的區(qū)別,使用BSDSocketAPI的應(yīng)用程序不必知道普通文件和網(wǎng)絡(luò)連接的差別,而使用LwIPAPI的應(yīng)用程序就必須知道正在使用的是一個網(wǎng)絡(luò)連接。它不適合于應(yīng)用在比較小的嵌入式系統(tǒng)中,因為它的實現(xiàn)要求應(yīng)用程序必須支持多線程。從本質(zhì)上講,TCP/IP協(xié)議棧的通信過程是事件驅(qū)動的,因此,TCP/IP的代碼和用戶應(yīng)用程序的代碼,應(yīng)該在不同的線程里面。當然,在不同的應(yīng)用程序中,這兩種API我們可以同時采用。實際上,sequentialAPI就是一種利用RAWAPI來實現(xiàn)的一種屬于協(xié)議本體的應(yīng)用程序。BSDSocketAPIBSDSocketAPI在連續(xù)的內(nèi)存區(qū)域處理數(shù)據(jù)非常便于編寫應(yīng)用程序。因為應(yīng)用程序內(nèi)的數(shù)據(jù)處理通常是在這樣的連續(xù)內(nèi)存區(qū)域內(nèi)進行的。但是,對于LwIP,采用這種機制不具備任何優(yōu)勢。特別是BSDSocket需要將要發(fā)送的數(shù)據(jù)從應(yīng)用程序復(fù)制到TCP/IP協(xié)議棧的內(nèi)部緩沖區(qū)。復(fù)制數(shù)據(jù)的原因是應(yīng)用程序與TCP/IP協(xié)議棧通常駐留在不同的受保護空間。大多數(shù)情況是應(yīng)用程序是一個用戶進程,而TCP/IP協(xié)議棧則駐留在操作系統(tǒng)內(nèi)核。通過避免額外的復(fù)制操作,API的性能可以大幅度提升。同樣,為了復(fù)制數(shù)據(jù),系統(tǒng)還需要為此分配額外的內(nèi)存,這樣每一個信息包都需要使用雙倍的內(nèi)存。雖然LWIP提供了一些接口函數(shù),但操作相對低級,使用起來不方便,不利用于后續(xù)開發(fā)。由于BSDSOCKETAPI很容易理解且己經(jīng)有很多人為它寫過應(yīng)用程序,且應(yīng)用程序使用BSDSOCKETAPI時候不需要知道普通文件和網(wǎng)絡(luò)連接之間的差別,所以為了便要理解和應(yīng)用,LWI提供了基于LWIP接口函數(shù)的BSDSOCKETAPI,但沒有任何容錯機制,沒有select()與poll()函數(shù)。以下就一些重要的SOCKETAPI函數(shù)做一介紹。socket()函數(shù)用于創(chuàng)建網(wǎng)絡(luò)通信的套接字,并返回該套接字的整數(shù)描述符。函數(shù)原型為 intsocket(intdomain,inttype,intprotocol),其中參數(shù)domain代表協(xié)議族或地址族,對于TCP/IP為PF_INET或AF_INET;type代表服務(wù)類型,對于TCP為SOCK_STREAM(流式),對于UDP為SOCK—DGRAM(數(shù)據(jù)報);protocol代表使用的協(xié)議號,對于TCP為IPPROTO_TCP,對于UDP為IPPROTO_UDP,傳遞0表示根據(jù)協(xié)議族和給定的服務(wù)類型選擇默認的協(xié)議號。若socket成功返回,返回大于或等于0的有效套接字描述符,返回一1表示發(fā)生了差錯。bind()函數(shù)將BSDsocket綁定到本地(本機)地址上。在調(diào)用bind()時,本地IP地址和端口號將被指定。⑶connect()允許調(diào)用者為先前創(chuàng)建的套接字指明遠程端點的地址。如果套接字使用TCP,該函數(shù)就使用三次握手建立連接;如果套接字使用UDP,則僅指明遠程端點,但不向它傳送任何數(shù)據(jù)報。⑷listen()使套接字處于被動狀態(tài)(即準備接受傳入的連接請求)。在服務(wù)器處理某個請求時,協(xié)議軟件應(yīng)將后續(xù)收到的請求排隊,listen也設(shè)置排隊的連接請求的數(shù)目。listen只用于TCP套接字。⑸accept()函數(shù)被用來等待TCPsocket口上的輸入連接。在此之前,這個TCPsocket口通過調(diào)用listen()已經(jīng)被設(shè)置成監(jiān)聽狀態(tài),對accept()調(diào)用一直被阻塞,直到與遠程主機建立連接。(6)send()數(shù)在UDP和TCP兩種連接中被用來發(fā)送數(shù)據(jù)。在調(diào)用send()前,數(shù)據(jù)接收器必須被設(shè)置成正在使用connect(),應(yīng)用程序在調(diào)用send()后可以直接修改發(fā)送的數(shù)據(jù)。⑺sendto()調(diào)用函數(shù)與send()調(diào)用函數(shù)類似,但是在參數(shù)調(diào)用中他們允許應(yīng)用程序指定數(shù)據(jù)接

溫馨提示

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

評論

0/150

提交評論