uIP各部分协议代码的分析
轉(zhuǎn)載地址:http://www.go-gddq.com/html/YuanMa-ChengXu/2013-03/1112798.htm
uIP是模塊化設(shè)計的,頭文件主要有uip.h、uipopt.h、uip_arp.h、uip_arch.h,核心文件主要包括uip_arp.c、uip.c、uip_arch.c等。另外在源碼中給出了幾個應用示例,實現(xiàn)了一個簡單的http服務器,并且?guī)в胁糠謈gi功能。下面主要結(jié)合TCP/IP協(xié)議說明各核心文件實現(xiàn)的功能,對代碼進行分析。
   
   (1)ARP協(xié)議的實現(xiàn)及uIP提供的相關(guān)函數(shù)。
   
   ARP協(xié)議本質(zhì)是完成網(wǎng)絡(luò)地址到物理地址的映射。物理地址本例中指以太網(wǎng)類型地址(MAC地址),網(wǎng)絡(luò)地址特指IP地址。
   
   ARP的以太網(wǎng)封裝格式和報文格式如下圖所示。
?
uIP使用一結(jié)構(gòu)體arp_HDR來表示ARP數(shù)據(jù)幀。注意arp_hdr數(shù)據(jù)結(jié)構(gòu)中還包括了以太網(wǎng)的頭部,硬件類型和協(xié)議類型等,真正的ARP數(shù)據(jù)幀是從u8_thwlen開始的。
ethhdr以太網(wǎng)頭部。定義的結(jié)構(gòu)體原型如下:
  ·dest,SRC:以太網(wǎng)目的地址和源地址,都是6字節(jié),為FFFFFFFFFFFF時是廣播地址,以太網(wǎng)上的所有節(jié)點都可以收到。
   
   ·type:以太網(wǎng)頭部的類型一般有兩種,如果type=0x0806,表明以太網(wǎng)封裝的數(shù)據(jù)部分為ARP數(shù)據(jù)包,如果type=0x0800,表明以太網(wǎng)封裝的數(shù)據(jù)部分為IP數(shù)據(jù)包。
   
   ·hwtype:硬件類型字段。指明了發(fā)送方想知道的硬件地址的類型,以太網(wǎng)的值為1。
   
   ·protocol:協(xié)議類型字段。表明要映射的協(xié)議地址類型,IP為0X0800。
   
   ·hwlen:硬件地址長度。指明了硬件地址和高層協(xié)議地址的長度。對于以太網(wǎng)上IP地址請求來講,值為6。
   
   ·protolen:協(xié)議地址長度。指明了硬件地址和高層協(xié)議地址的長度,對于以太網(wǎng)上的IP地址來講,值為4。
   
   ·opcode:操作字段,用來表示這個報文的類型,ARP請求為l,ARP響應為2,RARP請求為3,RARP響應為4。
   
   ·shwaddr:發(fā)送端的以太網(wǎng)地址(MAC地址),6字節(jié)。
   
   ·SIPaddr[2]:發(fā)送端的協(xié)議地址(IP地址),4字節(jié)。
   
   ·dhwaddr:接收端的以太網(wǎng)地址(MAC地址),6字節(jié)。
   
   ·DIPaddr[2]:接收端的協(xié)議地址(IP地址),4字節(jié)。
   
   uIP協(xié)議棧中與ARP協(xié)議有關(guān)的文件有uip_arp.c。文件中主要包含與arp實現(xiàn)相關(guān)的數(shù)據(jù)結(jié)構(gòu)和相關(guān)函數(shù)等。
   
   uIP協(xié)議棧將IP地址和MAC地址的對應關(guān)系保存在一個表arp_table[]中。
   
   statICstructarp_entryxdataarp_table[UIP_ARPTAB_SIZE];表中的每一個元素筆者稱之為表項,每一個表項保存的是一個IP地址和MAC地址的對應關(guān)系,另外還有一個標志時間的8位變量。顯然表中每一個元素都是arp_entry型,arp_entry的定義如下:
下表給出了一個arp_table[]的表格示例
uip_arp.c又件中主要函數(shù)說明如下。
  ①voiduip_arp_init(void)。函數(shù)的作用是初始化arp_table,使其中的IP地址全部為0。
   
   ②voiduip_arp_timer(void)。這個函數(shù)應該每隔一段時間被調(diào)用一次,函數(shù)的作用是每調(diào)用一次,arp_table中的所有元素的老化時間增加1,然后與最大老化時間UIP-ARP_MAXAGE比較,如果大于這個數(shù)值,說明這個arptabl表項太老,于是表項被清0,以用來存放更新的數(shù)據(jù)。
   
   ③staticvoiduip_arp_update(u16_t*ipaddr,structuip_eth_addr*ethaddr)。函數(shù)是只被uip_arp.c文件中的其他函數(shù)調(diào)用,作用是更新arp_table中的表項。
   
   首先尋找未使用的表項,若找到則將新的arp對應關(guān)系加入其中;若未找到,則尋找arp_table中最老的表項,并用新的數(shù)據(jù)代替。
   
   ④voiduip_arp_iPIN(void)。函數(shù)功能是對收到的IP包進行ARP部分的處理。如果收到的IP包中的lP地址在arp_table中存在,則其中相應表項中的MAC地址將會被收到IP包的MAC地址代替。如果arp_table中不存在這個IP地址,則創(chuàng)建一個新的表項。實際上這個函數(shù)對收到IP包中的IP地址進行判斷是否是本地網(wǎng)絡(luò)中后,直接又調(diào)用uip_arp_update()函數(shù)更新arp_table表項。
   
   ⑤voiduip_arp_arpin(void)。函數(shù)的功能是對收到的ARP數(shù)據(jù)包進行處理。當收到一個ARP數(shù)據(jù)包時,應該調(diào)用這個函數(shù)處理。如果收到的ARP數(shù)據(jù)包是一個ARP請求的應答,則在這個函數(shù)將更新ARP表。如果收到的ARP包是其他主機發(fā)送的請求本機MAC地址的數(shù)據(jù)包,則這個函數(shù)生成一個ARP應答包,且生成的數(shù)據(jù)包存放在uip_buf[]緩沖中。
   
   當函數(shù)返回時,全局變量uip_len的值表明網(wǎng)絡(luò)驅(qū)動是否應該發(fā)送一個數(shù)據(jù)包。如果uip_ler]
   
   不為0,則值就是uip_buf[]中存儲的要發(fā)送的數(shù)據(jù)包的長度,數(shù)據(jù)包就存放在uip_buf[]中。
   
   ⑥voiduip_arp_out(void)。uip_arp_out()函數(shù)的作用是對要發(fā)送的IP數(shù)據(jù)包進行預先處理,根據(jù)處理的情況決定是否發(fā)送一個ARP請求包以得到IP包中對應IP地址主機的MAC地址。如果要發(fā)送的數(shù)據(jù)包的IP地址是在本地網(wǎng)絡(luò)中(具有相同的子網(wǎng)掩碼),則搜索arp_table尋找是否存在相應的表項,如果存在,則為要發(fā)送的IP數(shù)據(jù)包添加上以太網(wǎng)幀頭,然后函數(shù)返回。
   
   如果ARP表項中不存在相應的表項,則生成一個ARP請求包,以得到要發(fā)送IP包目的IP地址的MAC地址。新生成的ARP包存放在uip_buf[]中代替原有的數(shù)據(jù)。IP包的重發(fā)依靠上層協(xié)議(如TCP協(xié)議)來完成。當函數(shù)返回時,全局變量uip_len的值表明網(wǎng)絡(luò)驅(qū)動是否應該發(fā)送一個數(shù)據(jù)包。如果uip_len不為O,則值就是uipbuf口中存儲的要發(fā)送的數(shù)據(jù)包的長度,數(shù)據(jù)包就存放在Iup_buf[]中。
   
   (2)IP和TCP協(xié)議簡單說明及uIP中相關(guān)接口函數(shù)的實現(xiàn)。
   
   IP協(xié)議是TCP/IP協(xié)議族中最為核心的協(xié)議。所有的TCP、UDP數(shù)據(jù)等都是以口數(shù)據(jù)包格式傳輸。IP負責將數(shù)據(jù)傳輸?shù)秸_的目的地,同時也負責路由。lP數(shù)據(jù)的傳輸具有以下特點。
   
   傳輸數(shù)據(jù)不能保證到達目的地。數(shù)據(jù)傳輸?shù)目煽啃杂缮蠈訁f(xié)議來提供(如TCP協(xié)議)。
   
   IP協(xié)議傳輸?shù)臄?shù)據(jù)是無連接的。
   
   TCP協(xié)議用于在不可靠的網(wǎng)絡(luò)上提供可靠、端到端的數(shù)據(jù)流通信協(xié)議。當傳輸受到干擾或網(wǎng)絡(luò)故障等原因使傳輸?shù)臄?shù)據(jù)不可靠時,就需要其他協(xié)議來保證數(shù)據(jù)傳輸?shù)耐暾耘c可靠性。TCP協(xié)議正是完成這種功能。TCP采用“帶重傳的肯定確認”和“滑動窗口”來實現(xiàn)數(shù)據(jù)傳輸?shù)目煽啃院土髁靠刂啤>唧w詳細過程請讀者參考相關(guān)資料。
   
   TCP協(xié)議是面向連接的數(shù)據(jù)傳輸協(xié)議。雙方通信之前,先建立連接,然后發(fā)送數(shù)據(jù),發(fā)  送完數(shù)據(jù)之后,關(guān)閉連接。通信的雙方建立連接之后,數(shù)據(jù)沿著這個連接雙向傳送數(shù)據(jù),連接的雙方通過序列號和確認號來對數(shù)據(jù)保持跟蹤。
   
   序列號說明當前數(shù)據(jù)塊在數(shù)據(jù)流中的位置。如果第一個數(shù)據(jù)塊的序列號是0,并且有10字節(jié)長,那么下一個數(shù)據(jù)塊的序列號應該是10。
   
   確認號表示接受數(shù)據(jù)的總數(shù)。如果初始的序列號是0,并且收到10字節(jié)需要確認,則應答中的確認號就是10。因為TCP的數(shù)據(jù)傳輸是雙向的,每一方對它自己的傳輸都保留一個序列號和確認號,并且每一方都對從對方節(jié)點接收來的序列號和確認號進行跟蹤TCP的操作可以使用一個具有11種狀態(tài)的有限狀態(tài)機來表示。
   
   各狀態(tài)的描述如下表所示。
| 狀態(tài) | 描述 | 
| CLOSED | 關(guān)閉狀態(tài) | 
| LISTEN | 監(jiān)聽狀態(tài),等待連接進入 | 
| SYN?RCVD | 收到一個連接請求,尚未確認 | 
| SYN?SENT | 已經(jīng)發(fā)出連接請求,等待確認 | 
| ESTABLISHED | 連接已經(jīng)建立,正常數(shù)據(jù)傳輸狀態(tài) | 
| FIN?WAIT1 | (主動關(guān)閉)已經(jīng)發(fā)送關(guān)閉請求,等待確認 | 
| FIN?WAIT2 | (主動關(guān)閉)收到對方關(guān)閉確認,等待對方關(guān)閉請求 | 
| TIMED?WAIT | 完成雙向連接,等待所有分組結(jié)束 | 
| CLOSING | 雙方同時嘗試關(guān)閉,等待對方確認 | 
| CLOSE?WAIT | (被動關(guān)閉)收到對方關(guān)閉請求,已經(jīng)確認 | 
| LAST?ACK | (被動關(guān)閉)等待最后一個關(guān)閉確認,并等待所有分組結(jié)束 | 
  相關(guān)信號說明如下:
   
   SYN初始同步消息。? ? ACK確認。
   
   FIN? 最后關(guān)閉消息。? RST? 強迫關(guān)閉信號。
   
   下面主要對IP、TCP協(xié)議的數(shù)據(jù)包格式進行說明。IP和TCP數(shù)據(jù)幀的以太網(wǎng)封裝格式如下圖所示。
IP和TCP數(shù)據(jù)幀頭部格式如下圖所示。
uIP并沒有單獨將IP幀拿出來進行單獨處理,定義數(shù)據(jù)結(jié)構(gòu)時直接將IP和TCP部分的頭部放在一個結(jié)構(gòu)體uip_tcpip_HDR中:
  .Vhl:版本號和首部長度。目前的協(xié)議版本號是4,首部長度是以32為單位的IP數(shù)據(jù)幀頭長度,在沒有選項時,首部長度字段中的值是5。
   
   ·tos:服務類型。uIP中未使用,數(shù)值為0。
   
   ·len[2]:16位總長度。指的是整個IP數(shù)據(jù)幀的長度(包括IP幀頭)。
   
   ·ipid[2]:ipid是一個無符號數(shù),屬于同一個報文的分段具有相同的標識符。IP協(xié)議每發(fā)送一個IP報文,則要把該標識符的值加1,作為下一個報文的標識符。
   
   ·Ipoffset:前3位的標志只有低兩位有效。
   
   第1位:最終分段標志。若為0,表明該分段是原報文的最后一個分段。
   
   第2位:禁止分段標志。當該位為1時,該報文不能分段。假如此時IP數(shù)據(jù)包的長度大于網(wǎng)絡(luò)的MTU值,則根據(jù)IP協(xié)議丟棄該報文。
   
   ipoffset后13位表示分段偏移,以8B為單位表示當前數(shù)據(jù)報相對于初始數(shù)據(jù)報的開頭位置。
   
   ·Ttl:數(shù)據(jù)包生存時間。表明數(shù)據(jù)在進入網(wǎng)絡(luò)后能夠在網(wǎng)絡(luò)中存留的時間,以秒為單位,最大為255。當為0時該數(shù)據(jù)包被丟棄,數(shù)據(jù)報每經(jīng)過一個路由器時,該值減1。這樣,當循環(huán)傳送的數(shù)據(jù)包最后總是會被丟棄。
   
   ·proto:協(xié)議類型。該字段的內(nèi)容指出IP數(shù)據(jù)報中數(shù)據(jù)部分屬于哪一種協(xié)議(高層協(xié)議)。例如0x06為TCP協(xié)議,0x01為ICMP協(xié)議,0x17為UDP協(xié)議等。
   
   ·ipchksum:頭部校驗和。用于保證IP數(shù)據(jù)幀頭部數(shù)據(jù)的正確性。此校驗只是針對IP數(shù)據(jù)幀頭。如果校驗失敗,數(shù)據(jù)包將被丟棄。計算方法為,把IP數(shù)據(jù)幀頭作為16位二進制數(shù)(校驗和本身部分字段設(shè)為0),對首部每個16位數(shù)進行二進制反碼的求和,即得到校驗碼。接收方收到數(shù)據(jù)包后,同樣對首部每個16位數(shù)進行二進制反碼的求和(這次包括校驗碼),如果無誤,結(jié)果的16位二進制數(shù)全為1,否則證明有誤。
   
   ·SRCipaddr[2]:源IP地址。
   
   ·destipaddr[2]:目的IP地址。
以下為TCP數(shù)據(jù)幀頭部各部分說明。
   
   ·SRCport:源端口號。
   
   ·destport:目的端口號。
   
   ·seqno[4]:順序號,用來標識從TCP源端向TCP目的端發(fā)送的數(shù)據(jù)字節(jié)流。
   
   ·ackno[4]:確認號,確認號用來指示下一個數(shù)據(jù)塊序列號。
   
   ·tcpoffset:包括4位TCP報頭長度和6位保留位。4位頭長度字段用來說明TCP報文段頭部的長度,單位為由32位組成的字的數(shù)目。由于TCP選項字段是可選項,所以TCP報文端的頭部長度可變。通常這個字段為空,缺省值為5。uIP中初始數(shù)值為5,通過與5比較大小來判斷是否有選項數(shù)據(jù)。
   
   ·flags:標志。包括6位控制位標志字段。為1表明本字段有效,為0表示無效。
   
   ·URG:用來表示報文中的數(shù)據(jù)已經(jīng)被發(fā)送端的高層軟件標志為緊急數(shù)據(jù)。
   
   ·ACK:用來表示確認號的值有效。如果ACK為1,則表示報文段中的確認號有效;否則,報文段中的確認號無效,接收端可以忽略。
   
   ·PSH:為1表明接收方應該盡快將這個報文段交給應用層而不用等待緩沖區(qū)滿。
   
   ·RST:用于復位因主機崩潰或其他原因而出現(xiàn)錯誤的連接,它還可以用于拒絕非法的報文段或拒絕連接請求。為1時表示要重新建立TCP連接。
   
   ·SYN:為1時表示連接要與序列號同步。
   
   ·FIN:用于釋放連接,為1時表示發(fā)送端數(shù)據(jù)已發(fā)送完畢。
   
   ·wnd[2]:窗口大小。用于數(shù)據(jù)流量控制。字段中的值表示接收端主機可接收多少個數(shù)據(jù)塊。
   
   ·tcpchksum:16位校驗和。用于校驗TCP報文段頭部、數(shù)據(jù)和偽頭部之校驗和。校驗和的校驗方法與IP頭部校驗方法相同。偽頭部如下圖所示.
  ·urgp[2]:16位緊急指針。只有當URG標志為1時緊急指針才有效。緊急指針是一個正偏移量,和順序號字段中的值相加表示緊急數(shù)據(jù)最后一個字節(jié)的序號。
   
   ·optdata[4]:選項數(shù)據(jù)。最常見的可選字段是最長報文大小,又稱為MSS。每個連接方通常都在通信的第一個報文段(為建立連接而設(shè)置SYN標志為1的那個段)中指明這個選項,它指明本端所能接受的最大長度的報文段。
   
   uIP協(xié)議棧中使用uip.conn結(jié)構(gòu)體來保存每一個TCP連接的雙方IP地址、端口號、順序號、確認號等。在uIP中定義了一個數(shù)組(見uip.c文件中的structuip_connxdatauip_conns[UIP_CONNS])。數(shù)組中的每一個元素保存了每一個連接的狀態(tài)。每一個元素的類型為structuip_conn型,uip_conn結(jié)構(gòu)體定義如下:
  uIP中IP、TCP協(xié)議的相關(guān)函數(shù)大部分都是在uip.c中實現(xiàn)。另外uip.c還包括UDP、ICMP協(xié)議的相關(guān)函數(shù),本節(jié)不對其說明,下面主要對lP和TCP協(xié)議的相關(guān)函數(shù)進行簡單分析。
   
   uip.C文件中函數(shù)并不多,對相關(guān)函數(shù)簡單說明如下。
   
   ①voiduip_init(void)函數(shù)功能:uIP協(xié)議初始化。所有監(jiān)聽的端口置0,所有連接的狀態(tài)置為CLOSED。
   
   ②structuip_conn*uip_connect(u16_t*ripaddr,u16_trport)函數(shù)功能:使用TCP協(xié)議與遠程主機相連。形參分別為IP地址和端口號。
   
   函數(shù)入口:ripaddr為要連接的遠程主機的IP地址首地址,rport為要連接的遠程主機的TCP端口。
   
   函數(shù)返回值:如果連接成功,函數(shù)的返回值為一個指向建立連接的連接狀態(tài)的指針,否則返回值為NULL。
  程序中,首先尋找本地未使用的端口,然后在uip_conns[UIP_CONNS]數(shù)組中搜索每一個元素,尋找當前未使用的連接,將當前建立的連接狀態(tài)填入;若沒有找到,則尋找數(shù)組中重發(fā)數(shù)據(jù)時間最多的一個連接狀態(tài)元素,將將當前建立的連接狀態(tài)填入,并返回新建立連接的指針。
   
   ⑧voiduip_unlisten(u16_tport)函數(shù)功能是停止監(jiān)聽指定的TCP連接端口。
   
   ④voiduip_listen(u16_tport)函數(shù)功能是監(jiān)聽指定的TCP連接端口。
   
   ⑤staticvoiduip_add_rcv_nxt(u16_tn)函數(shù)功能是將當前連接的下一個要接收的順序號加n。只是在uip.c文件內(nèi)有效。
   
   ⑥voiduip_process(u8_tflag)這個函數(shù)完成TCP處理,是uIP中最重要和復雜的函數(shù)。為了節(jié)省RAM,函數(shù)中使用了goto語句。實際上,uIP為了減少堆棧使用,設(shè)置了大量的全局變量,雖然程序可讀性差,各模塊之間聯(lián)系復雜,但是對RAM的使用大大減少,這在8位和16位系統(tǒng)中是我們所期盼的。
   
   本函數(shù)只有一個形參flag,在uIP中flag有幾種取值:UIP_TIMER(值為2)和UIP_DATA(值為1),uip_process函數(shù)根據(jù)flag判斷進行何種操作。
   
   如果flag標志為UIP_TIMER,則對初始順序序列號iSS(實際上用數(shù)組表示的一個32位數(shù))加1,然后判斷當前連接的TCP狀態(tài),根據(jù)不同的狀態(tài)來實現(xiàn)不同的操作。注意:uip中的應用程序函數(shù)也是在uip_process()函數(shù)中實現(xiàn)的。uIP自帶的一個http服務器,其文件中,如何在uip_process()函數(shù)中實現(xiàn)的,說明如下:
而UIP_APPCALL()又在httpd.h定義如下:
在httpd.c文件中應用程序函數(shù)為:
因此程序在編譯時將UIP_APPCALL替換為httpd_appcall,uip_process()函數(shù)中的UIP_APPCALL()被替換為httpd_appcall()。之所以要這么做,是因為當使用另外一個應用程序時,直接將UIP—APPCALL定義為應用程序的函數(shù)名稱即可。注意,uIP的應用程序只能是一個函數(shù),并且該函數(shù)不能有形參和返回值。
接下來函數(shù)的作用是檢查IP頭部的vhl字段的值,該IP包是否是分段的,IP頭部的目的IP地址與本機IP地址是否相等,IP頭部校驗和是否正確等。然后判斷上層協(xié)議字段,上層協(xié)議字段可以是TCP協(xié)議、UDP協(xié)議(需要根據(jù)需要選擇了條件編譯)和ICMP協(xié)議等。
   
   程序依次判斷是哪一種協(xié)議,是某一種,就跳轉(zhuǎn)到相應的協(xié)議處理程序段取處理。下面只對TCP處理程序部分作說明。
   
   程序跳轉(zhuǎn)到TCP輸入處理程序部分后,首先檢查TCP校驗和是否正確,然后尋找當前連接中的活動連接(連接的地址與數(shù)據(jù)包中的地址相同),若找到,則跳轉(zhuǎn)到找到連接程序處理部分。若沒有找到,這個數(shù)據(jù)包或者是一個重復的數(shù)據(jù)包,或者是一個SYN數(shù)據(jù)包,根據(jù)結(jié)果跳轉(zhuǎn)到相應的程序處執(zhí)行。
   
   found_listen程序處理部分。如果數(shù)據(jù)包符合正在監(jiān)聽的一個連接,則跳轉(zhuǎn)到這部分。首先程序?qū)ふ襲ip_conn[]數(shù)組中狀態(tài)為CLOSED的連接或者TIME_WAIT的連接,并用新的狀態(tài)等填入這個連接狀態(tài)。再接著,程序執(zhí)行到tcp_send_synack部分,將uip_buf緩沖中的要發(fā)送的數(shù)據(jù)包的狀態(tài)變?yōu)镾YNACK,然后跳轉(zhuǎn)到tcp_send程序處發(fā)送數(shù)據(jù)。
   
   found如果發(fā)現(xiàn)一個活動的連接,則跳轉(zhuǎn)到這部分。檢查TCP的數(shù)據(jù)包RST狀態(tài)位,順序號是否正確,如不正確,跳轉(zhuǎn)到tcp_send_ack部分請求發(fā)送正確的序列號。然后,檢查當前數(shù)據(jù)包的連接響應是否要有新的數(shù)據(jù)發(fā)送,如果有,做要發(fā)送數(shù)據(jù)的準備。
   
   程序接下來是一個switch循環(huán)判斷語句,這個語句相當長,功能是判斷當前連接的狀態(tài),根據(jù)各種不同的狀態(tài)進行相應的處理等。
   
   uip_process()函數(shù)的最后是tcp_send_ack,tcp_send_nodata等部分。
   
   u16_thtons(u16_tval)這個函數(shù)的作用是實現(xiàn)不同字節(jié)格式的轉(zhuǎn)換。根據(jù)定義的處理器的大小端格式實現(xiàn)處理器字的格式與網(wǎng)絡(luò)數(shù)據(jù)的字格式轉(zhuǎn)換。
   
   (3)其他輔助程序。
   
   uIP還包括一個uip_arch.c文件。其中的函數(shù)主要實現(xiàn)數(shù)據(jù)處理、校驗和的計算等。
   
   ①voiduip_add32(u8_t*op32,u16_top16)函數(shù)的功能是實現(xiàn)32位數(shù)的進位加法。op32是定義的op32[4]數(shù)組的首指針。由于op32[4]
   
   中每個元素的類型為8位,因此uIP中用4個元素表示一個32位數(shù)。程序?qū)崿F(xiàn)的功能是實現(xiàn)op32[4]數(shù)組表示的32位數(shù)與op16表示的16位數(shù)相加,結(jié)果存放在uip_aCC32[4]這個全局數(shù)組表示的32位數(shù)中。
   
   ②u16_tuip_chksum(u16_t*sdata,u16_tlen)函數(shù)的功能是實現(xiàn)數(shù)據(jù)的校驗,被uip_ipchksum()函數(shù)調(diào)用。
   
   ③u16_tuipjpchksum(void)函數(shù)功能是實現(xiàn)IP頭部校驗和的實現(xiàn)。
   
   ④u16_tuip_tcpchksum(void)函數(shù)功能是計算得到TCP頭部的校驗和。
   
   (4)uIP應用實例:一個簡單的WEBSERVER。
   
   uIP0.9版本中應用程序部分帶了一個簡單的WEB服務器和只讀文件系統(tǒng),實現(xiàn)了簡單的CGI功能。在此對其進行了改造,使其代碼更簡單、便于理解。關(guān)于http協(xié)議,請讀者參閱相關(guān)資料,在此不做說明。程序代碼如下:
總結(jié)
以上是生活随笔為你收集整理的uIP各部分协议代码的分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: pod 文件管理服务器,k8s中pod的
- 下一篇: 高等数学(第七版)同济大学 习题8-6
