




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
H:\精品資料\建筑精品網(wǎng)原稿ok(刪除公文)\建筑精品網(wǎng)5未上傳百度目錄一、 簡要歷史 3二、 TCP/IP協(xié)議族 32.1. 簡介 32.2. 編址 32.2.1 物理地址 32.2.2 邏輯地址 42.2.3 端口地址 52.3. 分層數(shù)據(jù)包介紹 52.3.1 以太網(wǎng)幀 52.3.2 ARP報文格式 62.3.3 IP數(shù)據(jù)報格式 62.3.4 ICMP報文格式 72.3.5 IGMP報文格式 92.3.6 UDP用戶數(shù)據(jù)報首部格式 92.3.7 TCP報文段格式 102.4. 分層協(xié)議講解 112.4.1 ARP和RARP 122.4.2 IP協(xié)議 132.4.3 ICMP協(xié)議 132.4.4 網(wǎng)際組管理協(xié)議(IGMP) 162.4.5 用戶數(shù)據(jù)報(UDP) 172.4.6 傳輸控制協(xié)議(TCP) 18三、 UIP處理流程 203.1. 簡介 203.2. 層次結(jié)構(gòu) 203.2.1 實現(xiàn)設(shè)備驅(qū)動與UIP對接需要的7個接口程序,定義在uip.h: 213.2.2 應(yīng)用層要調(diào)用的函數(shù),包括一些宏定義與函數(shù),定義在uip.h: 243.2.3 UIP中所用到的主要結(jié)構(gòu)體 273.2.4 uip的初始化與配置函數(shù) 313.2.5 Uip的主程序循環(huán) 323.2.6 主要的處理函數(shù)uip_process() 343.2.7 再來分析UIP_UDP_SEND_CONN,主要處理UDP報文的發(fā)送: 373.2.8 接下來,分析UIP_POLL_REQUEST 383.2.9 對定時器期滿的處理流程UIP_TIMER 403.2.10 對UIP_UDP_TIMER的處理流程 413.2.11 原始套接字和原始線程 41簡要歷史1973年,ARPANET核心組成員VintCerf和BobKahn發(fā)表了一篇里程碑論文,闡述了實現(xiàn)分組的端到端交付的協(xié)議。這篇關(guān)于傳輸控制協(xié)議(TCP)的論文包括:封裝、數(shù)據(jù)報,以及網(wǎng)關(guān)的功能。后來,TCP被劃分為兩個協(xié)議:傳輸控制協(xié)議(TCP)和網(wǎng)際互聯(lián)協(xié)議(IP)。IP處理數(shù)據(jù)報的路由選擇,而TCP負責(zé)高層的一些功能,如分段、重裝和差錯檢測。這個用來進行網(wǎng)際互聯(lián)的協(xié)議后來就被稱為TCP/IP。TCP/IP協(xié)議族簡介TCP/IP協(xié)議族由5層組成:物理層、數(shù)據(jù)鏈路層、網(wǎng)絡(luò)層、運輸層和應(yīng)用層。前四層與OSI模型的前四層相對應(yīng),提供物理標(biāo)準(zhǔn)、網(wǎng)絡(luò)接口、網(wǎng)際互聯(lián)、以及運輸功能。而應(yīng)用層與OSI模型中最高的三層相對應(yīng)。TCP/IP協(xié)議族中的各層包含了一些相對獨立的協(xié)議。在物理層和數(shù)據(jù)鏈路層,TCP/IP并沒有定義任何協(xié)議。在網(wǎng)絡(luò)層TCP/IP支持網(wǎng)際互聯(lián)協(xié)議(IP),而IP又由四個支撐協(xié)議組成:ARP、RARP、ICMP和IGMP。在傳統(tǒng)上,TCP/IP協(xié)議族在運輸層有兩個運輸協(xié)議:TCP和UDP,然而現(xiàn)在已經(jīng)設(shè)計出一個新的運輸層協(xié)議SCTP以滿足新的應(yīng)用的需要。IP是主機到主機的協(xié)議,即把分組從一個物理設(shè)備交付到另一個物理設(shè)備。UDP和TCP是運輸機協(xié)議,負責(zé)把報文從一個進程(運行著的程序)交付到另一個進程。編址使用TCP/IP協(xié)議的互聯(lián)網(wǎng)使用3個等級的地址:物理(鏈路)地址、邏輯(IP)地址以及端口地址。每一種地址屬于TCP/IP體系結(jié)構(gòu)中的特定層。物理地址物理地址也叫鏈路地址,是結(jié)點的地址,由它所在的局域網(wǎng)或廣域網(wǎng)定義。物理地址包含在數(shù)據(jù)鏈路層使用的幀中。以太網(wǎng)的地址是6字節(jié)(48位)長,一般見十六進制記法,如:07:01:02:01:2C:4B。以太網(wǎng)的地址共3種:單播、多播和廣播。在單播地址中的第一個字節(jié)的最低位0;在多播地址中的第一個字節(jié)的最低位是1。廣播地址是48個1。邏輯地址因特網(wǎng)的邏輯地址是32位地址,能夠用來標(biāo)志連接在因特網(wǎng)上的每個主機。在因特網(wǎng)上沒有兩個主機有相同的IP地址。同樣,邏輯地址也能夠是單播地址、多播地址和廣播地址。Internet被各種路由器和網(wǎng)關(guān)設(shè)備分隔成很多網(wǎng)段,為了標(biāo)識不同的網(wǎng)段,需要把32位的IP地址劃分成網(wǎng)絡(luò)號和主機號兩部分,網(wǎng)絡(luò)號相同的各主機位于同一網(wǎng)段,相互間能夠直接通信,網(wǎng)絡(luò)號不同的主機之間通信則需要經(jīng)過路由器轉(zhuǎn)發(fā)。把所有IP地址分為五類,如下圖1所示:圖2-SEQ圖表\*ARABIC1A類
0.0.0.0到127.255.255.255
B類
128.0.0.0到191.255.255.255
C類
192.0.0.0到223.255.255.255
D類
224.0.0.0到239.255.255.255
E類
240.0.0.0到247.255.255.255在分類編址的A類、B類、C類地址中,IP地址可劃分為net-id(網(wǎng)絡(luò)標(biāo)識)和host-id(主機標(biāo)識)。對于A類地址,1字節(jié)定義net-id而3字節(jié)定義host-id。對于B類地址,2字節(jié)定義net-id,2字節(jié)定義host-id。對于C類地址,3字節(jié)定義net-id而1字節(jié)定義host-id。D類地址和E類地址不劃分net-id和host-id。網(wǎng)絡(luò)地址是一個地址塊的第一個地址,向因特網(wǎng)的其余部分定義這個網(wǎng)絡(luò)。路由器就是根據(jù)網(wǎng)絡(luò)地址來選擇分組的路由。若給出網(wǎng)絡(luò)地址,我們就能夠找出這個地址的類別、地址塊以及這個地址塊的地址范圍。這種劃分方案有很大的局限性,它對網(wǎng)絡(luò)的劃分是flat的而不是層級結(jié)構(gòu)(hierarchical)的。Internet上的每個路由器都必須掌握所有網(wǎng)絡(luò)的信息,隨著大量C類網(wǎng)絡(luò)的出現(xiàn),路由器需要檢索的路由表越來越龐大,負擔(dān)越來越重。于是提出了新的劃分方案,稱為CIDR(ClasslessInterdomainRouting)。網(wǎng)絡(luò)號和主機號的劃分需要用一個額外的子網(wǎng)掩碼(subnetmask)來表示,而不能由IP地址本身的數(shù)值決定,也就是說,網(wǎng)絡(luò)號和主機號的劃分與這個IP地址是A類、B類還是C類無關(guān),因此稱為Classless的。這樣,多個子網(wǎng)就能夠匯總(summarize)成一個Internet上的網(wǎng)絡(luò)。IP地址與子網(wǎng)掩碼做與運算能夠得到網(wǎng)絡(luò)號,主機號從全0到全1就是子網(wǎng)的地址范圍。IP地址和子網(wǎng)掩碼還有一種更簡潔的表示方法,例如140.252.20.68/24,表示IP地址為140.252.20.68,子網(wǎng)掩碼的高24位是1,也就是255.255.255.0。目的地址為255.255.255.255,表示本網(wǎng)絡(luò)內(nèi)部廣播,路由器不轉(zhuǎn)發(fā)這樣的廣播數(shù)據(jù)包。目的地址的主機號為全1,表示廣播至某個網(wǎng)絡(luò)的所有主機,例如目的地址192.168.10.255表示廣播至192.168.10.0網(wǎng)絡(luò)(假設(shè)子網(wǎng)掩碼為255.255.255.0)。端口地址計算機是多進程設(shè)備,即能夠在同一時間運行多個進程。因特網(wǎng)通信的最終目的是使一個進程能夠和另一個進程通信。為了能夠同時發(fā)生這些事情,需要有一種方法對不同的進程打上標(biāo)號,就是說這些進程需要地址。在TCP/IP體系結(jié)構(gòu)中,給一個進程指派的標(biāo)號叫做端口地址。TCP/IP中的端口地址是16位長,一般見10進制數(shù)表示。分層數(shù)據(jù)包介紹以太網(wǎng)幀圖2-SEQ圖表\*ARABIC2目的地址(DA)DA字段有6字節(jié),是下一站的物理地址(也叫MAC地址)。源地址(SA)SA字段有6字節(jié),是前一站的物理地址。類型類型字段有三種值,分別對應(yīng)IP、ARP、RARP。數(shù)據(jù)攜帶從上層協(xié)議封裝起來的數(shù)據(jù)。它的最小長度是46字節(jié),最大長度是1500字節(jié)。ARP、RARP的數(shù)據(jù)包長度不夠46字節(jié),要在后面補填充位。最大值1500稱為以太網(wǎng)的最大傳輸單元(MTU),如果一個數(shù)據(jù)包從以太網(wǎng)路由到鏈路上,數(shù)據(jù)包的長度大于鏈路的MTU了,則需要對數(shù)據(jù)包進行分片CRC差錯檢測信息,4字節(jié)。ARP報文格式圖2-SEQ圖表\*ARABIC3如上圖3所示,ARP分組的格式如下:硬件類型16位字段,用來定義運行ARP的鏈路層網(wǎng)絡(luò)的類型。以太網(wǎng)是類型1。協(xié)議類型16位字段,指要轉(zhuǎn)換的地址類型。0x0800位IP地址。硬件長度8位字段,定義以字節(jié)為單位的物理地址長度。對以太網(wǎng)這個值為6。協(xié)議長度8位字段,定義以字節(jié)為單位的邏輯地址長度。對IPv4協(xié)議這個值是4。操作16位字段,定義分組的類型。為1表示ARP請求,為2表示ARP應(yīng)答。發(fā)送端硬件地址可變長度字段,定義發(fā)送端的物理地址。發(fā)送端協(xié)議地址定義發(fā)送端的邏輯地址。目標(biāo)硬件地址定義目標(biāo)的物理地址。對于ARP請求報文,這個字段是全0,因為發(fā)送端不知道目標(biāo)的物理地址。目標(biāo)協(xié)議地址定義目標(biāo)的邏輯(如,IP)地址。IP數(shù)據(jù)報格式圖2-4如上圖4所示,IP數(shù)據(jù)報的結(jié)構(gòu)包括:版本(VER)這個4位字段定義IP協(xié)議的版本。首部長度(HLEN)這個4位字段定義IP首部總長度,以4字節(jié)為單位計算。當(dāng)沒有選項時,首部長度是20字節(jié),這個字段的值是5(5*4=20)。當(dāng)選項字段位最大值時,這個字段的值是15(15*4=60)。服務(wù)類型(DS)TOS位是4位子字段,共有5種不同的服務(wù)類型。總長度這個16位字段定義了以字節(jié)計的數(shù)據(jù)報總長度(首部加上數(shù)據(jù))。要找出上層傳來的數(shù)據(jù)長度,能夠從總長度減去首部長度。總長度字段是16位,因此IP數(shù)據(jù)報的長度限制是65535(216-1)字節(jié)。標(biāo)識(Identification)這個16位字段與源IP地址一起唯一地定義這個數(shù)據(jù)報。IP協(xié)議使用一個計數(shù)器來標(biāo)志數(shù)據(jù)報,當(dāng)IP協(xié)議發(fā)送數(shù)據(jù)時,就把這個計數(shù)器的當(dāng)前值復(fù)制到標(biāo)識字段中,并加1。當(dāng)數(shù)據(jù)報被分片時,標(biāo)識字段的值就復(fù)制到所有的分片中。換言之,所有的分片具有相同的標(biāo)識號,即原始數(shù)據(jù)報的標(biāo)識號。在終點重裝數(shù)據(jù)報時,終點就知道所有具有相同標(biāo)識號的分片必須組裝成一個數(shù)據(jù)報。標(biāo)志(Flags)3位字段。第一位保留。第二位為不分片位,為1表示不對數(shù)據(jù)報進行分片;為0表示在需要時對數(shù)據(jù)報進行分片。第三位為分片位,為1表示這個數(shù)據(jù)報不是最后的分片,在其后還有分片;為0表示這個數(shù)據(jù)報是最后的分片。分片偏移(FragmentOffset)這個13位字段表示該分片在整個數(shù)據(jù)報中的相對位置,以8字節(jié)為度量單位。生存時間(TTL)用來控制數(shù)據(jù)報所經(jīng)過的最大路由跳數(shù),這個生存時間的單位不是秒,而是跳(hop)。協(xié)議這個8位字段定義使用IP層服務(wù)的高層協(xié)議。如:TCP、UDP、ICMP和IGMP等。檢驗和IP分組中的檢驗和只在首部而不在數(shù)據(jù)部分進行。因為,所有將數(shù)據(jù)封裝在IP數(shù)據(jù)報中的高層協(xié)議,都有覆蓋整個分組的檢驗和;其次,,每經(jīng)過一個路由器,IP數(shù)據(jù)報的首部就要改變一次,但數(shù)據(jù)部分不變。因此檢驗和只對發(fā)生變化的部分進行檢驗。源地址這個32位字段定義源點的IP地址。在IP數(shù)據(jù)報從源主機發(fā)送到目的主機的時間內(nèi),這個字段必須保持不變。目的地址這個32位字段定義了終點的IP地址。在IP數(shù)據(jù)報從源主機發(fā)送到目的主機的時間內(nèi),這個字段必須保持不變。ICMP報文格式類型8位字段,定義ICMP報文的類型。ICMP報文的類型有:終點不可達、源點抑制、超時、參數(shù)問題、改變路由、回送請求或回答、時間戳請求或回答、地址掩碼請求或回答、路由器詢問和通告。代碼8位字段,指明了發(fā)送這個特定報文類型的原因。檢驗和(icmpchksum)16位字段。在ICMP中,檢驗和的計算覆蓋了整個報文(首部和數(shù)據(jù))。ICMP回送請求或回答報文頭格式如下圖5所示:圖2-5ICMP終點不可達報文頭格式如下圖6所示:圖2-6ICMP超時報文頭格式如下圖7所示:圖2-7IGMP報文格式圖2-8類型8位字段,定義了查詢、成員關(guān)系報告、退出報告三種報文類型,類型值分別為0x11、0x16、0x17。最大響應(yīng)時間8位字段,定義了查詢必須在多長時間內(nèi)回答。它的值以十分之一秒位單位。在查詢報文中這個值不是零,但在其它兩種報文中則置為零。檢驗和16位字段,檢驗和在8字節(jié)的報文上計算。組地址在一般查詢報文中這個字段的值為0,在特殊查詢報文、成員關(guān)系報告報文以及退出報告報文中定義groupid(組多播地址)。UDP用戶數(shù)據(jù)報首部格式圖2-9UDP數(shù)據(jù)報格式如上圖9所示。用戶數(shù)據(jù)報有8個字節(jié)的固定首部。源端口號16位字段,定義源主機上運行的進程所使用的端口號。目的端口號16位字段,定義目的主機上運行的進程使用的端口號。長度16位字段,定義了用戶數(shù)據(jù)報的總長度,首部加上數(shù)據(jù)。檢驗和16位字段,UDP的檢驗和包括三部分:偽首部、UDP首部以及從應(yīng)用層來的數(shù)據(jù)。位首部是IP分組的首部的一部分,包括:源IP地址、目的IP地址、8位協(xié)議和16位UDP總長度。位首部能夠保證在IP首部受到損傷時,用戶數(shù)據(jù)報能夠交付到正確的主機。協(xié)議字段的加入,能夠確保這個分組是屬于UDP而不是屬于TCP。TCP報文段格式圖2-10如上圖10所示,TCP報文段的結(jié)構(gòu)包括:源端口地址這個16位字段定義發(fā)送報文段的應(yīng)用程序端口號。目的端口地址這個16位字段定義了接收該報文段的應(yīng)用程序端口號。序號這個32位字段定義了指派給本報文段第一個數(shù)據(jù)字節(jié)的一個號。為了保證連通性,要發(fā)送的每一個字節(jié)都要編號。序號告訴終點,這個序列中的哪一個字節(jié)是報文段中的第一個字節(jié)。在連接建立時,每一方使用隨機數(shù)產(chǎn)生器產(chǎn)生初始序號(ISN)。確認號32位字段,定義了報文段接收端期望從對方接收的下一個序號。如果報文段的接收端成功地發(fā)送了對方發(fā)來的序號x,它就把確認號定義為x+1。首部長度(tcpoffset)4位字段,指出TCP首部共有多少個4字節(jié)字。即TCP數(shù)據(jù)在IP數(shù)據(jù)中的偏移大小。同IP首部長度,能夠在5至15之間。保留位該6位字段留待今后使用??刂?標(biāo)志位該字段定義了6種不同的控制位或標(biāo)志,在同一時間可設(shè)置一位或多位標(biāo)志。表2-1控制字段各標(biāo)志說明(從高位到低位)標(biāo)志說明URG緊急指針字段值有效ACK確認字段值有效PSH推送數(shù)據(jù)RST連接必須復(fù)位SYN在連接建立時對序號進行同步FIN終止連接窗口值該字段定義接收方必須維持的窗口值(以字節(jié)為單位)。注意,該字段是16位長,因此窗口值的最大長度為65535字節(jié)。這個值由接收端來確定,發(fā)送端必須服從接收端的決定。檢驗和這個16位字段包含檢驗和,TCP使用檢驗和是強制性的。緊急指針當(dāng)緊急標(biāo)志位置位時,這個16位字段才有效,這時的報文段中包括緊急數(shù)據(jù)。緊急指針定義了一個數(shù),把這個數(shù)加到序號上就得出報文段數(shù)據(jù)部分中最后一個緊急字節(jié)。選項包括無操作(NOP)、最大報文段長度(MSS)、窗口擴大因子、時間戳等。分層協(xié)議講解總的來說,TCP/IP協(xié)議的多路選擇過程能夠表示為下圖2-11:圖2-11ARP和RARP地址解析協(xié)議ARP在任何時候,當(dāng)主機或路由器有數(shù)據(jù)報要發(fā)送給另一個主機或路由器時,它必須有接收端的邏輯(IP)地址??墒荌P數(shù)據(jù)報必須封裝成幀才能經(jīng)過物理網(wǎng)絡(luò)。這就表示,發(fā)送端必須有接收端的物理地址,因此需要有從邏輯地址到物理地址的映射。地址解析協(xié)議(ARP)用來把IP地址與其物理地址聯(lián)系起來。任何時候當(dāng)主機或路由器需要找出這個網(wǎng)絡(luò)上的另一個主機或路由器的物理地址時,它就發(fā)送ARP查詢分組。這個分組包括發(fā)送端的物理地址和IP地址,以及接收端的IP地址。因為發(fā)送端不知道接收端的物理地址,查詢就在網(wǎng)絡(luò)上廣播。例如,數(shù)據(jù)包要發(fā)送給IP地址為192.168.0.1的主機,過程如下:源主機發(fā)出ARP請求,詢問”IP地址是192.168.0.1的主機的硬件地址是多少”,并將這個請求廣播到本地網(wǎng)段(以太網(wǎng)幀首部的硬件地址填FF:FF:FF:FF:FF:FF表示廣播),目的主機接收到廣播的ARP請求,發(fā)現(xiàn)其中的IP地址與本機相符,則發(fā)送一個ARP應(yīng)答數(shù)據(jù)包給源主機,將自己的硬件地址填寫在應(yīng)答包中。ARP報文格式如前所述。ARP軟件包由5個構(gòu)件組成:高速緩存表:每臺主機都維護一個ARP高速緩存表,由于高速緩存表的空間非常有限,因此緩存表中的表項有過期時間(一般為20分鐘),如果20分鐘內(nèi)沒有再次使用某個表項,則該表項失效,下次還要發(fā)ARP請求來獲得目的主機的硬件地址。隊列:隊列用來在ARP試圖解析硬件地址時保留IP分組。輸出模塊把未解析的分組發(fā)送到相應(yīng)的隊列,輸入模塊從一個隊列中拿走一個分組,并連同解析出的物理地址一同發(fā)送給數(shù)據(jù)鏈路層來傳輸。輸出模塊:輸出模塊從IP軟件等待IP分組。輸出模塊檢查高速緩存表,尋找是否有某個項目對應(yīng)于這個分組的目的IP地址。這個IP分組的目的IP地址必須與這個項目的協(xié)議地址相匹配。輸入模塊:輸入模塊一直等待,直到有ARP分組到達。檢查高速緩存表,尋找對應(yīng)這個ARP分組的項目。輸入模塊設(shè)置這個項目的超時時間TIME-OUT。若隊列為空,則從相應(yīng)隊列中把分組一個接一個地取出,連同其硬件地址一起交給數(shù)據(jù)鏈路層來處理。高速緩存控制模塊:負責(zé)維護高速緩存表,它周期性地逐項檢查高速緩存表,判斷有哪些項目到期,哪些隊列需要撤銷。逆地址解析協(xié)議RARP當(dāng)一個主機知道自己的物理地址時,RARP可用來找出其邏輯地址。每一個主機或路由器都被指派一個或多個邏輯地址,這些地址與機器的物理地址無關(guān)。要創(chuàng)立IP數(shù)據(jù)報,主機或路由器要知道它自己的IP地址。能夠使用RARP協(xié)議從物理地址得到邏輯地址。知道物理地址后,先創(chuàng)立RARP請求,并在本地網(wǎng)絡(luò)上廣播。在本地網(wǎng)絡(luò)上的另一個機器知道所有的IP地址,它就用RARP回答來響應(yīng)。請求的機器必須運行RARP客戶程序;而響應(yīng)的機器必須運行RARP服務(wù)器程序。IP協(xié)議IP數(shù)據(jù)報的格式如前所述。IP是不可靠的無連接協(xié)議,負責(zé)源點到終點的交付。在IP層的分組叫做數(shù)據(jù)報。數(shù)據(jù)鏈路層有自己的幀格式,在這個格式中有一個字段是”數(shù)據(jù)字段最大長度”。當(dāng)數(shù)據(jù)報封裝成幀時,數(shù)據(jù)報的總長度必須小于這個數(shù)據(jù)字段最大長度(MTU)。對數(shù)據(jù)報進行分割,叫做分片。源站一般不對IP分組進行分片。運輸層會進行分片工作,把數(shù)據(jù)劃分成IP和在使用的數(shù)據(jù)鏈路層都可能接納的大小。數(shù)據(jù)報在到達終點之前能夠經(jīng)過多次分片,能夠被源主機或在其路徑上任何路由器進行分片。然而數(shù)據(jù)報的重組卻只能在目的主機上進行。在IP分組中的檢驗和只在首部而不在數(shù)據(jù)部分心進行。因為,首先所有將數(shù)據(jù)封裝在IP數(shù)據(jù)報中的高層協(xié)議,都有覆蓋整個分組的檢驗和;其次,每經(jīng)過一個路由器,IP數(shù)據(jù)報的首部就要改變一次,但數(shù)據(jù)部分不變。因此檢驗和只對發(fā)生變化的部分進行檢驗。IP軟件包包括8個構(gòu)件:首部添加模塊、處理模塊、轉(zhuǎn)發(fā)模塊、分片模塊、重裝模塊、路由表、MTU表以及重裝表,還有輸入和輸出隊列。首部添加模塊,從高層協(xié)議接收數(shù)據(jù)(連同其IP地址),添加IP首部后,把數(shù)據(jù)封裝成IP數(shù)據(jù)報。處理模塊,從一個接口或從首部添加模塊接收數(shù)據(jù)報,首先檢查數(shù)據(jù)報是否為回環(huán)地址,還是這個分組已到達最后終點。輸入隊列把從數(shù)據(jù)鏈路層或從高層協(xié)議發(fā)來的數(shù)據(jù)存放起來。輸出隊列把要發(fā)送到數(shù)據(jù)鏈路層或高層協(xié)議的數(shù)據(jù)報存放起來,處理模塊從中取出數(shù)據(jù)報,分片和重裝模塊則把這個數(shù)據(jù)報加入輸出隊列中。路由表是在轉(zhuǎn)發(fā)模塊中使用的,用來確定分組的下一跳地址。分片模塊從轉(zhuǎn)發(fā)模塊接收IP數(shù)據(jù)報。轉(zhuǎn)發(fā)模塊給出IP數(shù)據(jù)報、下一站的IP地址。以及發(fā)送這個數(shù)據(jù)報所必須經(jīng)過的接口號。分片模塊使用MTU表以便找出對于特定接口的最大傳送單元MTU。若數(shù)據(jù)報的長度大于MTU,則分片模塊對數(shù)據(jù)報進行分片,為每一個分片添加首部,并把它們發(fā)送到ARP軟件包進行地址解析和交付。重裝模塊從處理模塊接收已到達最終目的地的數(shù)據(jù)報分片。重裝模塊將未分片的數(shù)據(jù)報看成是屬于僅有一個分片的數(shù)據(jù)報。使用重裝表找出一個分片是屬于哪一個數(shù)據(jù)報,將屬于同一個數(shù)據(jù)報的各分片進行排序,并在所有分片到達時把它們重新組裝成一個數(shù)據(jù)報。ICMP協(xié)議IP協(xié)議沒有差錯報告或差錯糾正機制和管理查詢機制。網(wǎng)際控制報文協(xié)議(ICMP)就是為了補償這兩個缺點而設(shè)計的。它是配合IP協(xié)議使用的。ICMP本身是網(wǎng)絡(luò)層協(xié)議,可是它的報文不是如設(shè)想的那樣直接傳送給數(shù)據(jù)鏈路層,而是首先要封裝成IP數(shù)據(jù)報,再傳送給下一層。在IP數(shù)據(jù)報中的協(xié)議字段值是1就表示其IP數(shù)據(jù)是ICMP報文。ICMP報文類型如下表2-2所示:表2-2ICMP報文類型ICMP報文分為兩大類:差錯報告報文和查詢報文。報文格式如前所述。差錯報告報文差錯報告報文報告當(dāng)路由器或主機在處理IP數(shù)據(jù)報時可能遇到的一些問題。ICMP不能糾錯,只能報告差錯,差錯糾正留給高層協(xié)議去做。ICMP總是使用源IP地址把差錯報文發(fā)送給數(shù)據(jù)報的源點。一共有5種差錯可處理:終點不可達、源點抑制、超時、參數(shù)問題以及改變路由。終點不可達報文當(dāng)路由器不能夠給數(shù)據(jù)報找到路由或主機不能夠交付數(shù)據(jù)報時,就丟棄這個數(shù)據(jù)報,然后這個路由器或主機就向發(fā)出這個數(shù)據(jù)報的源主機發(fā)回終點不可達報文。源點抑制ICMP的源點抑制報文就是為了給IP增加一種流量控制而設(shè)計的。當(dāng)路由器或主機因擁塞而丟棄數(shù)據(jù)報時,它就向數(shù)據(jù)報的發(fā)送端發(fā)送源點抑制報文。目的有二:第一,通知源點,數(shù)據(jù)報已被丟棄。第二,它警告源點,在路徑中的某處出現(xiàn)了擁塞,因而源點需放慢發(fā)送過程。注意,必須為每一個丟棄的數(shù)據(jù)報向源點發(fā)送源點抑制報文。超時超時有兩種情況:第一,當(dāng)路由器接收到生存時間字段值為零的數(shù)據(jù)報時,就丟棄這個數(shù)據(jù)報,并向源點發(fā)送超時報文;第二,當(dāng)最后的終點在規(guī)定時間內(nèi)沒有收到所有的分片時,就丟棄已收到的分片,并向源點發(fā)送超時報文。參數(shù)問題如果路由器或主機在數(shù)據(jù)報的首部中發(fā)現(xiàn)任何二義性,或在數(shù)據(jù)報的某個字段中缺少了某個值,就丟棄這個數(shù)據(jù)報,并發(fā)送參數(shù)問題報文。改變路由路由器的路由選擇是動態(tài)的,而主機為了提高效率,一般使用靜態(tài)路由選擇。當(dāng)主機開始連網(wǎng)工作時,其路由表中的項目數(shù)很有限。它一般只知道默認路由器這一個路由器的IP地址,因此主機有可能會把某個數(shù)據(jù)報發(fā)送給一個錯誤的路由器。此時,收到這個數(shù)據(jù)報的路由器會把數(shù)據(jù)報轉(zhuǎn)發(fā)給正確的路由器,并向主機發(fā)送改變路由報文,以更新主機中的路由表。查詢報文查詢報文都是成對出現(xiàn)的。在這種類型的ICMP報文中,一個結(jié)點發(fā)送報文,然后由目的結(jié)點用特定的格式進行回答。回送請求和回答報文為診斷目的而設(shè)計的。主機或路由器能夠發(fā)送回送請求報文給另一個主機或路由器。收到回送請求報文的主機或路由器產(chǎn)生回送回答報文,并將其返回給原來的發(fā)送者。回送請求和回答報文可用來確定是否在IP這級能夠通信。還可由主機使用,以檢查另一個主機是否可達。在用戶級,調(diào)用分組因特網(wǎng)搜尋器(ping)命令可做到這點。時間戳請求和回答兩個機器可使用時間戳請求和回答來確定IP數(shù)據(jù)報在這兩個機器之間來往所需的往返時間。地址掩碼請求和回答主機經(jīng)過向局域網(wǎng)上的路由器發(fā)送地址掩碼請求報文來獲得自己的掩碼。若主機知道這個路由器的地址,則直接將請求發(fā)送給該路由器,若主機不知道,則廣播這個請求報文。路由器收到地址掩碼請求報文,就以地址掩碼回答報文進行響應(yīng),向主機提供所需的掩碼。路由詢問和通告主機若想把數(shù)據(jù)發(fā)送給另一個網(wǎng)絡(luò)上的主機,就需要知道連接到該網(wǎng)絡(luò)上的路由器的地址。另外,這個主機還需要知道這些路由器是否正常工作。就能夠通告路由詢問和通告報文。主機把路由器詢問報文進行廣播,收到詢問的路由器就使用路由通告報文廣播其路由選擇信息。路由器發(fā)送通告報文時,不但通告自己的存在,而且通告了它所知道的所有在這個網(wǎng)絡(luò)上的路由器。在ICMP中,檢驗和的計算覆蓋了整個報文(首部和數(shù)據(jù))。網(wǎng)際組管理協(xié)議(IGMP)網(wǎng)際組管理協(xié)議(IGMP)是與多播有關(guān)的一個必要的但不是充分的協(xié)議。IGMP并不是多播路由選擇協(xié)議,而是個管理組成員關(guān)系的協(xié)議。每當(dāng)主機需要加入或離開某個特定的多播群組時,該協(xié)議允許該主機去通知鄰近的路由器。該協(xié)議只用在主機與路由器之間的網(wǎng)絡(luò)上。而且,協(xié)議只把計算機(不是應(yīng)用進程)定義為群組成員。如果在一個給定計算機上有多個進程要加入到一個多播群組,計算機必須要把接收到的每個數(shù)據(jù)報復(fù)制多個副本給每個進程。只有當(dāng)最后一個進程離開群組時,計算機才利用IGMP通知本地的路由器,表明它不再是群組的成員了。IGMPv2有3種報文類型:查詢、成員關(guān)系報告和退出報告。IGMP可分為兩個階段:第一階段:當(dāng)某個主機加入新的多播組時,該主機應(yīng)向組播組的多播地址發(fā)送一個IGMP報文,聲明自己要成為該組的成員。本地的多播路由器收到IGMP報文后,將組成員關(guān)系轉(zhuǎn)發(fā)給因特網(wǎng)上的其它多播路由器。第二階段:因為組成員關(guān)系是動態(tài)的,因此本地多播路由器要周期性地探詢本地局域網(wǎng)上的主機,以便知道這些主機是否還連續(xù)是組的成員。只要對某個組有一個主機響應(yīng),那么多播路由器就認為這個組是活躍的。但一個組在經(jīng)過多次的探詢后依然沒有一個主機響應(yīng),則多播路由器就認為本網(wǎng)絡(luò)上的主機已經(jīng)都離開這個組了因此就不再將該組的成員關(guān)系轉(zhuǎn)發(fā)給其它的多播路由器。IGMP報文格式如前所述。IGMP協(xié)議的優(yōu)點:主機和多播路由器的所有通信使用IP多播,只要有可能,攜帶IGMP報文的數(shù)據(jù)報都使用硬件多播來傳送。多播路由器在探詢組成員關(guān)系時,只需要對所有多播組只發(fā)一個查詢,而不是對每一個組發(fā)送一個查詢,默認125S一次。用戶數(shù)據(jù)報(UDP)UDP數(shù)據(jù)報的格式如前所述。UDP位于應(yīng)用層和IP層之間,作為應(yīng)用程序和網(wǎng)絡(luò)操作的中介物。IP是負責(zé)在計算機級的通信(主機到主機的通信),作為網(wǎng)絡(luò)層協(xié)議,IP只能把報文交付給目的主機??墒?這是一種不完整的交付。這個報文還必須送交到正確的進程。UDP就是負責(zé)把報文交付給適當(dāng)?shù)倪M程。完成進程到進程的通信最常見的方法是經(jīng)過客戶-服務(wù)器范例。在本地主機上叫做客戶的進程主動發(fā)起請求,遠程主機上叫做服務(wù)器的進程被動地等待、接收和應(yīng)答請求。客戶端的IP地址和端口號唯一標(biāo)識了該主機上的客戶端進程,服務(wù)器的IP地址和端口號唯一標(biāo)識了該主機上的服務(wù)端進。由于客戶端是主動發(fā)起請求的一方,它必須知道服務(wù)器的IP地址和服務(wù)進程的端口號,因此,一些常見的網(wǎng)絡(luò)協(xié)議有默認的服務(wù)器端口。TCP/IP協(xié)議族中,端口號是在0~65535之間的整數(shù)。ICANN把端口號劃分為3個范圍:熟知端口號、注冊端口號和動態(tài)(或?qū)S?端口號。熟知端口范圍從0~1023;注冊端口范圍從1024~49151;動態(tài)端口范圍從49152~65535.已知UDP需要兩個標(biāo)識符,即IP地址和端口號,各用在一端以建立一條連接。一個IP地址和一個端口號合起來叫做套接字地址。這些信息是IP首部和UDP首部的一部分。UDP提供物連接服務(wù),即UDP發(fā)出的每一個用戶數(shù)據(jù)報都是獨立的數(shù)據(jù)報,每一個用戶數(shù)據(jù)報能夠走不同的路徑到達目的進行。UDP缺少流量控制和差錯控制。要從一個進程把報文發(fā)送到另一個進程,UDP協(xié)議就要把報文進行封裝和拆裝。封裝當(dāng)進程有報文要經(jīng)過UDP發(fā)送時,它就把這個報文連同一對套接字地址以及數(shù)據(jù)的長度傳遞給UDP,加上UDP首部后,UDP把用戶數(shù)據(jù)報連同套接字地址一起傳遞給IP。IP加上自己的首部,在協(xié)議字段使用值17,指出該數(shù)據(jù)是從UDP協(xié)議來的。再將IP數(shù)據(jù)報傳遞給數(shù)據(jù)鏈路層,數(shù)據(jù)鏈路層收到IP數(shù)據(jù)報后,再加上自己的首部傳遞給物理層。物理層將這些位編碼為電信號或光信號,把它發(fā)送到遠程機器。拆裝報文到達目的主機時,物理層對信號解碼,將它變?yōu)槲?傳遞給數(shù)據(jù)鏈路層。數(shù)據(jù)鏈路層使用這個首部(和尾部)檢查數(shù)據(jù)。若無差錯,則去掉首部和尾部,并把數(shù)據(jù)報傳遞給IP。IP軟件進行檢查,若無差錯,就剝?nèi)ナ撞?把用戶數(shù)據(jù)報連同發(fā)送端和接收端的IP地址一起傳遞給UDP。UDP使用檢驗和對整個用戶數(shù)據(jù)報進行檢查。若無差錯則剝?nèi)ナ撞?把應(yīng)用數(shù)據(jù)傳遞給接收進程。在需要回答收到的報文時,應(yīng)把發(fā)送端的套接字地址一起傳遞給接收進程。UDP軟件包共包括5個構(gòu)件:一個控制塊表、若干個輸入隊列、一個控制塊模塊、一個輸入模塊和一個輸出模塊。在UDP中,隊列是與端口相關(guān)聯(lián)在一起的。這里的實現(xiàn)只創(chuàng)立與每一個進程相關(guān)聯(lián)的輸入隊列,而不創(chuàng)立輸出隊列。控制塊表UDP控制塊表來記錄打開的端口。表中的每一個項目有最小的4個字段:狀態(tài)(FREE或IN-USE)、進程ID、端口號以及相應(yīng)的隊列號。輸入隊列使用了一組輸入隊列,每一個對應(yīng)于一個進程。控制塊模塊負責(zé)管理控制塊表。當(dāng)進程啟動時,它就從操作系統(tǒng)請求得到一個端口號。操作系統(tǒng)把熟知端口號指派給服務(wù)器,而把短暫端口號指派給客戶。進程把進程ID和端口號傳遞給控制塊模塊,以便在表中為這個進程創(chuàng)立一個項目。這個模塊不創(chuàng)立隊列。隊列數(shù)字段值為零。輸入模塊輸入模塊從IP接收用戶數(shù)據(jù)報。它查找控制塊表,查找具有和這個用戶數(shù)據(jù)報同樣端口號的項目。若找到這樣的項目,模塊就利用這項目中的信息把這個數(shù)據(jù)放入隊列。若未找到這樣的項目,它就產(chǎn)生ICMP”端口不可達”報文,并丟棄這個項目。輸出模塊負責(zé)創(chuàng)立和發(fā)送用戶數(shù)據(jù)報。傳輸控制協(xié)議(TCP)TCP叫做面向連接的、可靠的運輸協(xié)議。它提供進程到進程、全雙工和面向連接的服務(wù)。TCP使用滑動窗口機制實現(xiàn)流量控制,來避免接收端因數(shù)據(jù)過多而過載;使用差錯控制來提供可靠的服務(wù)。兩個設(shè)備之間使用TCP軟件傳送的數(shù)據(jù)單元叫做報文段,它有20~60字節(jié)的首部,首部后面是來自應(yīng)用程序的數(shù)據(jù)。首部結(jié)構(gòu)如前所述。TCP連接TCP的連接一般包括3個階段:連接建立、數(shù)據(jù)傳送和連接終止。連接建立需要三向握手:客戶發(fā)送第一個報文段,SYN報文段,在這個報文段中只有SYN標(biāo)志位置1.這個報文段的作用是使序號同步。SYN報文段是控制報文段,不攜帶任何數(shù)據(jù),可是消耗一個序號。當(dāng)數(shù)據(jù)傳送開始時,每發(fā)送一個字節(jié),序號應(yīng)該加1.在接收端能夠根據(jù)序號排出數(shù)據(jù)包的正確順序,也能夠發(fā)現(xiàn)丟包的情況。服務(wù)器發(fā)送第二個報文段,SYN+ACK報文段,有兩個標(biāo)志位置1(SYN和ACK)。服務(wù)器使用這個報文段同步初始序號,以便從服務(wù)器向客戶發(fā)送字節(jié)。使用ACK確認已從客戶端收到了SYN報文段,確認號為客戶端發(fā)送SYN報文段序號值加1.客戶發(fā)送第三個報文ACK,確認號為服務(wù)器發(fā)送報文段的序號值加1。該報文段的序號與SYN報文段使用的序號一樣。ACK報文段如果不攜帶數(shù)據(jù)就不消耗序號。連接建立后,數(shù)據(jù)開始雙向傳送:在數(shù)據(jù)傳輸過程中,ACK和確認序號是非常重要的,應(yīng)用程序交給TCP協(xié)議發(fā)送的數(shù)據(jù)會暫存在TCP層的發(fā)送緩沖區(qū)中,發(fā)出數(shù)據(jù)包給對方之后,只有收到對方應(yīng)答的ACK段才知道該數(shù)據(jù)包確實發(fā)到了對方,能夠從發(fā)送緩沖區(qū)中釋放掉了,如果因為網(wǎng)絡(luò)故障丟失了數(shù)據(jù)包或者丟失了對方發(fā)回的ACK段,經(jīng)過等待超時后TCP協(xié)議自動將發(fā)送緩沖區(qū)中的數(shù)據(jù)包重發(fā)。以上情況只描述了最簡單的一問一答的情景,事實上TCP協(xié)議為應(yīng)用層提供了全雙工(full-duplex)的服務(wù),雙方都能夠主動甚至同時給對方發(fā)送數(shù)據(jù)。如果通訊過程只能采用一問一答的方式,收和發(fā)兩個方向不能同時傳輸,在同一時間只允許一個方向的數(shù)據(jù)傳輸,則稱為'''半雙工(half-duplex)''',假設(shè)某種面向連接的協(xié)議是半雙工的,則只需要一套序號就夠了,不需要通訊雙方各自維護一套序號了。參加交換數(shù)據(jù)的雙方中的任何一方都能夠關(guān)閉連接,連接終止的四向握手:在正常情況下,客戶機TCP接收到客戶進程發(fā)來的關(guān)閉命令后,就發(fā)送第一個報文段——把FIN位置1。如果FIN報文段不攜帶數(shù)據(jù),它消耗一個序號。同時更改狀態(tài)為FIN_WAIT_1,關(guān)閉應(yīng)用程序進程。服務(wù)器TCP在收到這個FIN報文段后,向自己對應(yīng)的進程發(fā)送一個文件結(jié)束符EOF,同時更改狀態(tài)為CLOSE_WAIT,并發(fā)送第二個報文段——ACK,以證實從客戶端收到了FIN報文段。如果不攜帶數(shù)據(jù),客戶端接到ACK后狀態(tài)更改為FIN_WAIT_2。服務(wù)器關(guān)閉應(yīng)用程序進程,更改狀態(tài)為LAST_ACK。并發(fā)送第三個報文段——FIN,若不攜帶數(shù)據(jù),FIN消耗一個序號??蛻鬞CP接收到FIN后,更改狀態(tài)為TIME-WAIT,同時發(fā)送最后一個報文段——ACK,證實從TCP服務(wù)器收到了一個FIN報文段,該報文段的確認號等于從服務(wù)器發(fā)送的FIN報文段的序號加1。除上述的情況外,建立連接時,客戶端和服務(wù)器端能夠同時打開;關(guān)閉連接時,能夠同時關(guān)閉或者進行三向握手。TCP的狀態(tài)機轉(zhuǎn)換圖如下所示:圖2-12TCP的各種狀態(tài)如下表2所示:表2-3TCP的各種狀態(tài)狀態(tài)說明CLOSED沒有連接LISTEN收到了被動打開,等待SYNSYN-SENT已發(fā)送SYN;等待ACKSYN-RCVD已發(fā)送SYN+ACK;等待ACKESTABLISHED連接已建立;數(shù)據(jù)傳送在進行FIN-WAIT-1第一個FIN已發(fā)送;等待ACKFIN-WAIT-2對第一個FIN的ACK已收到;等待第二個FINCLOSE-WAIT收到第一個FIN,已發(fā)送ACK;等待應(yīng)用程序關(guān)閉TIME-WAIT收到第二個FIN,已發(fā)送ACK;等待2MSL超時LAST-ACK已發(fā)送第二個FIN;等待ACKCLOSING雙方都已決定同時關(guān)閉流量控制:如果發(fā)送端發(fā)送的速度較快,接收端接收到數(shù)據(jù)后處理的速度較慢,而接收緩沖區(qū)的大小是固定的,就會丟失數(shù)據(jù)。TCP協(xié)議經(jīng)過'''滑動窗口(SlidingWindow)'''機制解決這一問題。TCP在接收緩存上定義一個窗口,TCP發(fā)送數(shù)據(jù)的多少由滑動窗口協(xié)議定義。為了完成流量控制,TCP使用滑動窗口協(xié)議。兩個主機為向外通信(發(fā)送數(shù)據(jù))各使用一個窗口,這個接收窗口覆蓋了緩存的一部分。這個窗口有兩個沿:一個在左邊,另一個在右邊。這個窗口叫做滑動窗口,因為左沿和右沿都能夠滑動。窗口能夠展開、合攏或縮回,這三種活動受接收端而不是發(fā)送端的控制(取決與網(wǎng)絡(luò)上的擁塞狀態(tài)),發(fā)送端必須聽從接收端的命令。一般,窗口縮回必須避免。TCP的滑動窗口是面向字節(jié)的,窗口大小取決于接收窗口(rwnd)和擁塞窗口(cwnd)中的較小值。接收端在一段時間內(nèi)不愿意從發(fā)送端接收任何數(shù)據(jù)時,能夠發(fā)送rwnd為0的報文段來暫時關(guān)閉窗口,此時發(fā)送端窗口大小并非真正地縮回,而是暫停發(fā)送數(shù)據(jù),直到一個新的通告收到為止。差錯控制:差錯控制由檢驗和、確認和超時來處理。受損傷的和重復(fù)的報文段要重傳,重復(fù)的報文段要丟棄。數(shù)據(jù)可能不按序到達,接收端TCP把它們暫時存儲下來,但TCP保證交付給進程的報文段都是按序的。重傳發(fā)生在:當(dāng)重傳超時(RTO)計時器時間到,或已到達3個重復(fù)的ACK報文段。TCP使用擁塞機制來避免和檢測網(wǎng)絡(luò)中的擁塞。在擁塞控制中使用曼開始(指數(shù)增大)、擁塞避免(加法增大)和擁塞檢測(乘法減小)等策略。TCP在運行中使用4個計時器(重傳計時器、持久計時器、?;钣嫊r器和時間等待計時器)。UIP處理流程簡介uIP協(xié)議棧去掉了完整的TCP/IP中不常見的功能,簡化了通訊流程,但保留了網(wǎng)絡(luò)通信必須使用的協(xié)議,設(shè)計重點放在了ARP/IP/ICMP/UDP/TCP這些網(wǎng)絡(luò)層和傳輸層協(xié)議上,保證了其代碼的通用性和結(jié)構(gòu)的穩(wěn)定性。由于uIP協(xié)議棧專門為嵌入式系統(tǒng)而設(shè)計,它具有如下的優(yōu)點:代碼非常少,其協(xié)議棧代碼不到6K;占用的內(nèi)存數(shù)非常少,RAM占用僅幾百字節(jié);其硬件處理層、協(xié)議棧層和應(yīng)用層共用一個全局緩存區(qū),不存在數(shù)據(jù)的拷貝,且發(fā)送和接收都是依靠這個緩存區(qū),極大的節(jié)省空間和時間。支持多個主動連接和被動連接并發(fā);通用性強,移植起來基本不用修改就能夠經(jīng)過;對數(shù)據(jù)的處理采用輪循機制,不需要操作系統(tǒng)的支持。層次結(jié)構(gòu)uIP相當(dāng)于一個代碼庫,經(jīng)過一系列的函數(shù)實現(xiàn)與底層硬件和高層應(yīng)用程序的通訊,對于整個系統(tǒng)來說它內(nèi)部的協(xié)議組是透明的,從而增加了協(xié)議的通用性。uIP協(xié)議棧與系統(tǒng)底層和高層應(yīng)用之間的關(guān)系如圖11所示:應(yīng)用程序應(yīng)用程序UIP網(wǎng)卡驅(qū)動系統(tǒng)定時器應(yīng)用層UIP協(xié)議棧硬件驅(qū)動圖3-1實現(xiàn)設(shè)備驅(qū)動與UIP對接需要的7個接口程序,定義在uip.h:#defineuip_input()uip_process(UIP_DATA)#defineuip_periodic(conn)do{uip_conn=&uip_conns[conn];\uip_process(UIP_TIMER);}while(0)#defineuip_conn_active(conn)(uip_conns[conn].tcpstateflags!=UIP_CLOSED)#defineuip_periodic_conn(conn)do{uip_conn=conn;\uip_process(UIP_TIMER);}while(0)#defineuip_poll_conn(conn)do{uip_conn=conn;\uip_process(UIP_POLL_REQUEST);}while(0)#defineuip_udp_periodic(conn)do{uip_udp_conn=&uip_udp_conns[conn];\uip_process(UIP_UDP_TIMER);}while(0)#defineuip_udp_periodic_conn(conn)do{uip_udp_conn=conn;\uip_process(UIP_UDP_TIMER);}while(0)還有一個變量,在接口中要用到:u8_tuip_buf[UIP_BUFSIZE+2];對以上接口進行詳細介紹:#defineuip_input()處理輸入數(shù)據(jù)包。當(dāng)設(shè)備從網(wǎng)絡(luò)上接收到數(shù)據(jù)包時調(diào)用此函數(shù)。在調(diào)用此函數(shù)之前,應(yīng)將接收到的數(shù)據(jù)包內(nèi)容存入uip_buf緩沖區(qū),并將其長度賦給uip_len.以太網(wǎng)內(nèi)使用的uip需要用到ARP協(xié)議,因此在調(diào)用此函數(shù)之前先調(diào)用uip的ARP代碼。此函數(shù)返回時,如果系統(tǒng)有數(shù)據(jù)要輸出,會直接將數(shù)據(jù)存入uip_buf,并將其長度值賦給uip_len。如果沒有數(shù)據(jù)要發(fā)送,則uip_len值為0.使用舉例如下:uip_len=tapdev_read(uip_buf);if(uip_len>0){if(BUF->type==htons(UIP_ETHTYPE_IP)){ uip_arp_ipin(); uip_input(); if(uip_len>0){ uip_arp_out(); tapdev_send(uip_buf,uip_len); }}elseif(BUF->type==htons(UIP_ETHTYPE_ARP)){uip_arp_arpin(); if(uip_len>0){ tapdev_send(uip_buf,uip_len); }}}#defineuip_periodic(conn)周期性的處理一個連接,需用到該連接的連接號,conn為將要輪詢的連接號。該函數(shù)對一個uip的TCP連接進行一些必要的周期性處理(如定時器、輪詢等),它應(yīng)該在周期性uip定時器期滿消息到來時被調(diào)用。每一個連接都應(yīng)該調(diào)用該函數(shù),不論連接是否打開。該函數(shù)返回時,若緩沖區(qū)內(nèi)有需要被發(fā)送出去的數(shù)據(jù)包等待處理,就將uip_len的值置為大于零的數(shù)。以太網(wǎng)內(nèi)使用的uip需要用到ARP協(xié)議,因此在調(diào)用驅(qū)動程序之前先調(diào)用uip的ARP代碼uip_arp_out(),再調(diào)用設(shè)備驅(qū)動程序?qū)?shù)據(jù)包發(fā)送出去。使用舉例如下:for(uint32_ti=0;i<UIP_CONNS;i++){ uip_periodic(i);if(uip_len>0){uip_arp_out();tapdev_send(uip_buf,uip_len);}}#defineuip_conn_active(conn)#defineuip_periodic_conn(conn)對一個連接進行周期性處理,需用到指向該連接結(jié)構(gòu)體的指針。該函數(shù)與uip_periodic執(zhí)行的操作是相同的,不同之處在于傳入的參數(shù)是一個指向uip_conn結(jié)構(gòu)體的指針。此函數(shù)可用于對某個連接強制進行周期性處理。#defineuip_poll_conn(conn)請求對特定連接進行輪詢。該函數(shù)功能與uip_periodic()相同,可是不執(zhí)行任何定時器處理。經(jīng)過輪詢從應(yīng)用程序得到新數(shù)據(jù)。#defineuip_udp_periodic(conn)周期性處理連接號指定的連接。此函數(shù)基本上與uip_periodic()相同,區(qū)別在于這里處理的是UDP連接。其調(diào)用方式也與uip_periodic()類似:for(i=0;i<UIP_UDP_CONNS;i++){uip_udp_periodic(i);if(uip_len>0){uip_arp_out();tapdev_send();}}#defineuip_udp_periodic_conn(conn)周期性處理一個UDP連接,需用到指向該連接結(jié)構(gòu)體的指針。此函數(shù)功能與uip_periodic_conn()相同,只是用來處理的是UDP連接。u8_tuip_buf[UIP_BUFSIZE+2];uip數(shù)據(jù)包緩沖區(qū),長度固定。Uip_buf數(shù)組用于存放接收、發(fā)送的數(shù)據(jù)包。設(shè)備驅(qū)動程序應(yīng)將接收到的數(shù)據(jù)放入緩沖區(qū)。發(fā)送數(shù)據(jù)時,設(shè)備驅(qū)動程序從緩沖區(qū)中讀取鏈路層的首部和TCP/IP首部。鏈路層頭的大小在UIP_LLH_LEN中定義。注:應(yīng)用程序數(shù)據(jù)無需放入這個緩沖區(qū)中,而是需要設(shè)備驅(qū)動程序從uip_appdata指針?biāo)傅牡胤阶x取數(shù)據(jù)。u16_tuip_len;全局變量,uip_buf緩沖區(qū)中數(shù)據(jù)包的長度。當(dāng)網(wǎng)絡(luò)設(shè)備驅(qū)動調(diào)用uip輸入函數(shù)時,uip_len要被設(shè)為傳入數(shù)據(jù)包的大小。當(dāng)發(fā)送數(shù)據(jù)包時,設(shè)備驅(qū)動程序經(jīng)過這個變量來確定要發(fā)送的數(shù)據(jù)包的大小。應(yīng)用層要調(diào)用的函數(shù),包括一些宏定義與函數(shù),定義在uip.h:宏定義:#defineuip_outstanding(conn)((conn)->len)#defineuip_datalen()uip_len#defineuip_urgdatalen()uip_urglen#defineuip_close()(uip_flags=UIP_CLOSE)#defineuip_abort()(uip_flags=UIP_ABORT)#defineuip_stop()(uip_conn->tcpstateflags|=UIP_STOPPED)#defineuip_stopped(conn)((conn)->tcpstateflags&UIP_STOPPED)#defineuip_restart()do{uip_flags|=UIP_NEWDATA;\uip_conn->tcpstateflags&=~UIP_STOPPED;\}while(0)#defineuip_udpconnection()(uip_conn==NULL)#defineuip_newdata()(uip_flags&UIP_NEWDATA)#defineuip_acked()(uip_flags&UIP_ACKDATA)#defineuip_connected()(uip_flags&UIP_CONNECTED)#defineuip_closed()(uip_flags&UIP_CLOSE)#defineuip_aborted()(uip_flags&UIP_ABORT)#defineuip_timedout()(uip_flags&UIP_TIMEDOUT)#defineuip_rexmit()(uip_flags&UIP_REXMIT)#defineuip_poll()(uip_flags&UIP_POLL)#defineuip_initialmss()(uip_conn->initialmss)#defineuip_mss()(uip_conn->mss)#defineuip_udp_remove(conn)(conn)->lport=0#defineuip_udp_bind(conn,port)(conn)->lport=port#defineuip_udp_send(len)uip_send((char*)uip_appdata,len)函數(shù):voiduip_listen(u16_tport);voiduip_unlisten(u16_tport);structuip_conn*uip_connect(uip_ipaddr_t*ripaddr,u16_tport);voiduip_send(constvoid*data,intlen);structuip_udp_conn*uip_udp_new(uip_ipaddr_t*ripaddr,u16_trport);對以上函數(shù)進行詳細介紹:#defineuip_outstanding(conn)檢查一個連接是否有特殊的(例如,未答復(fù)的)數(shù)據(jù)。conn為指向該連接結(jié)構(gòu)體的指針。#defineuip_datalen()uip_appdata緩沖區(qū)中,當(dāng)前可用的傳入數(shù)據(jù)的長度。必須先調(diào)用uip_data()查明是否有當(dāng)前可用的傳入數(shù)據(jù)。#defineuip_urgdatalen()所有到達連接的緩沖區(qū)外的(緊急數(shù)據(jù))數(shù)據(jù)長度。要使用此宏,應(yīng)配置UIP_URGDATA宏為真。#defineuip_close()此函數(shù)會以一種謹慎的方式關(guān)閉當(dāng)前連接。#defineuip_abort()中止(重置)當(dāng)前連接,多用于出現(xiàn)錯誤導(dǎo)致無法使用uip_close()的場合。#defineuip_stop()告訴發(fā)送主機停止發(fā)送數(shù)據(jù)。該函數(shù)會關(guān)閉接收者的窗口,以停止從當(dāng)前連接接收數(shù)據(jù)。#defineuip_stopped(conn)找出當(dāng)前連接先前是否已經(jīng)被uip_stop()停止了。#defineuip_restart()如果連接先前被uip_stop()停止了,該函數(shù)會重啟連接。接收者的窗口會被重新打開,并從當(dāng)前連接開始接收數(shù)據(jù)。#defineuip_udpconnection()檢查當(dāng)前連接是否是一個UDP連接。#defineuip_newdata()如果uip_appdata指針?biāo)钢幱行碌膽?yīng)用數(shù)據(jù),就得到一個非零值。數(shù)據(jù)的大小可經(jīng)過uip_len得到。#defineuip_acked()若先前發(fā)送的數(shù)據(jù)得到了遠程主機的確認信息,就得到一個非零值。這表示應(yīng)用程序能夠發(fā)送新數(shù)據(jù)了。#defineuip_connected()如果當(dāng)前與遠程主機的連接建立,則得到一個非零值。這包括兩種情形:連接被主動打開(uip_connect()),或者被動打開(uip_listen())。#defineuip_closed()如果連接被遠程主機關(guān)閉,則返回一個非零值。這時應(yīng)用程序會做一些必要的清理工作。#defineuip_aborted()如果連接被遠程主機中止(重置),則返回一個非零值。#defineuip_timedout()如果當(dāng)前連接是因為多次重傳而超時中止,則返回一個非零值。#defineuip_rexmit()如果先前發(fā)送的數(shù)據(jù)在網(wǎng)絡(luò)中丟失,應(yīng)用程序需重傳時,返回一個非零值。應(yīng)用程序需調(diào)用uip_send()函數(shù)來重傳與上一次所發(fā)送的完全一致的數(shù)據(jù)。#defineuip_poll()解決連接是否由uip輪詢的問題。如果應(yīng)用程序被調(diào)用的原因是當(dāng)前連接因空閑太久而被uip輪詢,則返回一個非零值。該輪詢事件能夠被用來發(fā)送數(shù)據(jù),而無需等待遠程主機發(fā)送數(shù)據(jù)。#defineuip_initialmss()獲得當(dāng)前連接的初始最大報文段長度(MSS)。#defineuip_mss()獲得當(dāng)前連接所能發(fā)送的最大報文段長度。該長度是由接收者的窗口大小和連接的MSS計算出來的。#defineuip_udp_remove(conn)移除一個UDP連接。conn指向該連接的uip_udp_conn結(jié)構(gòu)體。#defineuip_udp_bind(conn,port)綁定一個UDP連接到本地端口。conn指向該連接的uip_udp_conn結(jié)構(gòu)體,port為本地端口號,以網(wǎng)絡(luò)字節(jié)序。#defineuip_udp_send(len)在當(dāng)前連接上發(fā)送長度為len的UDP數(shù)據(jù)包。該函數(shù)只有在答復(fù)一個UDP事件(輪詢或有新數(shù)據(jù))時才可被調(diào)用。數(shù)據(jù)必須提前放入uip_buf緩沖區(qū)中uip_appdata指針指向的地方。voiduip_listen(u16_tport);開始監(jiān)聽指定的端口。由于port應(yīng)該為網(wǎng)絡(luò)字節(jié)序,因此需要用到轉(zhuǎn)換函數(shù)HTONS()或者htons()。voiduip_unlisten(u16_tport);停止監(jiān)聽指定端口。structuip_conn*uip_connect(uip_ipaddr_t*ripaddr,u16_tport);使用TCP協(xié)議連接到遠程主機。此函數(shù)用來與特定主機上的特定端口建立新的連接,它分配一個新的連接標(biāo)識符,并將連接的狀態(tài)轉(zhuǎn)為SYN_SENT,將重傳計時器設(shè)置為0.當(dāng)該連接下次被周期性處理時,將會發(fā)送一個TCP的SYN報文段。這個過程一般在uip_connet()被調(diào)用后0.5秒后完成。該函數(shù)只有在主動打開配置項UIP_ACTIVE_OPEN被置1時可用。ripaddr為遠程主機的IP地址,port為網(wǎng)絡(luò)字節(jié)序的端口號。該函數(shù)返回一個指向新連接的uip連接標(biāo)識符的指針,當(dāng)沒有連接能被分配時返回NULL。voiduip_send(constvoid*data,intlen);在當(dāng)前連接上發(fā)送數(shù)據(jù)。該函數(shù)用來發(fā)送單個TCP數(shù)據(jù)報文段,只有為了事件處理而被uip調(diào)用的應(yīng)用程序,才能發(fā)送數(shù)據(jù)。該函數(shù)能夠發(fā)送的數(shù)據(jù)大小是由TCP所允許的最大數(shù)據(jù)量來決定的。uip會自動的分割數(shù)據(jù),以保證發(fā)送出去的數(shù)據(jù)量是合適的。能夠經(jīng)過uip_mss()來查詢uip實際將要發(fā)送的數(shù)據(jù)量。該函數(shù)不保證發(fā)送的數(shù)據(jù)能到達目的地,如果數(shù)據(jù)在網(wǎng)絡(luò)中丟失,uip_rexmit()事件將被置位。應(yīng)用程序會被調(diào)用,并經(jīng)過該函數(shù)來重新發(fā)送數(shù)據(jù)。structuip_udp_conn*uip_udp_new(uip_ipaddr_t*ripaddr,u16_trport);建立一個新的UDP連接。該函數(shù)會自動為新連接分配一個不用的端口,可是在調(diào)用該函數(shù)之后,還能夠經(jīng)過uip_udp_bind()還重新選擇一個端口。ripaddr為遠程主機(服務(wù)器)的IP地址,rport為遠程主機網(wǎng)絡(luò)字節(jié)序的端口號。該函數(shù)返回新連接的uip_udp_conn結(jié)構(gòu)體指針,或者當(dāng)沒有連接能夠分配時返回NULL。UIP中所用到的主要結(jié)構(gòu)體Structuip_conn{//TCP連接uip_ipaddr_tripaddr;/**<TheIPaddressoftheremotehost.*/u16_tlport;/**<ThelocalTCPport,innetworkbyteorder.*/u16_trport;/**<ThelocalremoteTCPport,innetworkbyteorder.*/u8_trcv_nxt[4];/**<Thesequencenumberthatweexpecttoreceivenext.*/u8_tsnd_nxt[4];/**<Thesequencenumberthatwaslastsentbyus.*/u16_tlen;/**<Lengthofthedatathatwaspreviouslysent.*/u16_tmss;/**<Currentmaximumsegmentsizefortheconnection.*/u16_tinitialmss;/**<Initialmaximumsegmentsizefortheconnection.*/u8_tsa;/**<Retransmissiontime-outcalculationstatevariable.*/u8_tsv;/**<Retransmissiontime-outcalculationstatevariable.*/u8_trto;/**<Retransmissiontime-out.*/u8_ttcpstateflags;/**<TCPstateandflags.*/u8_ttimer;/**<Theretransmissiontimer.*/u8_tnrtx;/**<Thenumberofretransmissionsforthelastsegmentsent.*//**Theapplicationstate.*/uip_tcp_appstate_tappstate;};structuip_udp_conn{//UDP連接uip_ipaddr_tripaddr;/**<TheIPaddressoftheremotepeer.*/u16_tlport;/**<Thelocalportnumberinnetworkbyteorder.*/u16_trport;/**<Theremoteportnumberinnetworkbyteorder.*/u8_tttl;/**<Defaulttime-to-live.*//**Theapplicationstate.*/uip_udp_appstate_tappstate;};structuip_stats{//統(tǒng)計信息結(jié)構(gòu)體struct{uip_stats_tdrop;/**<NumberofdroppedpacketsattheIPlayer.*/uip_stats_trecv;/**<NumberofreceivedpacketsattheIPlayer.*/uip_stats_tsent;/**<NumberofsentpacketsattheIPlayer.*/uip_stats_tvhlerr;/**<NumberofpacketsdroppedduetowrongIPversionorheaderlength.*/uip_stats_thblenerr;/**<NumberofpacketsdroppedduetowrongIPlength,highbyte.*/uip_stats_t
溫馨提示
- 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)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025至2031年中國廣味香腸行業(yè)投資前景及策略咨詢研究報告
- 2025至2031年中國女童竹節(jié)牛仔短褲行業(yè)投資前景及策略咨詢研究報告
- 平面logo設(shè)計合同范本
- 2025至2031年中國低噪音雙吸式離心風(fēng)機行業(yè)投資前景及策略咨詢研究報告
- 2025至2030年中國隔板釘數(shù)據(jù)監(jiān)測研究報告
- 科技產(chǎn)品電商平臺的消費者心理洞察
- 租房布置窯洞合同范本
- 2025至2030年中國汽車進氣壓力傳感器數(shù)據(jù)監(jiān)測研究報告
- 轉(zhuǎn)運車輛改裝合同范本
- 圍墾造田工程合同范本
- 考前沖刺攻略課件
- 2024年中煤電力有限公司所屬企業(yè)招聘29人筆試參考題庫附帶答案詳解
- 2024年12月2025中央統(tǒng)戰(zhàn)部直屬事業(yè)單位應(yīng)屆高校畢業(yè)生公開招聘21人筆試歷年典型考題(歷年真題考點)解題思路附帶答案詳解
- 積極心理學(xué)視角下高職院校學(xué)生心理健康教育路徑研究
- 2024年湖北省煙草專賣局(公司)招聘筆試真題
- 2025中鐵快運股份限公司招聘全日制普通高校畢業(yè)生35人易考易錯模擬試題(共500題)試卷后附參考答案
- 2025年浙江寧波寧興集團有限公司招聘筆試參考題庫含答案解析
- 計算機網(wǎng)絡(luò)試題及答案
- 2025年安徽馬鞍山市兩山綠色生態(tài)環(huán)境建設(shè)有限公司招聘筆試參考題庫附帶答案詳解
- 人效管理措施
- 2024年下半年中國海油秋季校園招聘易考易錯模擬試題(共500題)試卷后附參考答案
評論
0/150
提交評論