uIP介绍
下面內(nèi)容都是參考英文文檔
uip是一個開源的微型協(xié)議棧,主要用于8位,16位MCU,占用內(nèi)存少,并且代碼少,容易移植。
它既可以用于多任務的操作系統(tǒng)中,如ucos。也能單獨存在,傳說中的裸奔。
uip的主循環(huán)
uip主循環(huán)中重復做著兩件事情。
- 查看是否收到數(shù)據(jù)包
- 查看周期性超時是否發(fā)生
uip的API接口 因為與uip協(xié)議棧的原因,它不使用傳統(tǒng)的BSD套接字API,它有兩種API用于應用編程,一種類似BSD套接字API,還有一種是基于事件的API,這種需要內(nèi)存比前者更少。 基于事件的API的意思是有一個應用程序運行在uip之上,當處理發(fā)生的特定事件時,由uip調(diào)用處理相關事件。這些事件包括接收到或發(fā)送包,建立連接時,當數(shù)據(jù)需要重發(fā)時等等。 另外uip不同于其他TCP/IP協(xié)議棧的地方是需要手動處理重發(fā)數(shù)據(jù),也就是要自己在應用程序里編寫代碼處理要重發(fā)的數(shù)據(jù),其他協(xié)議棧都是自動處理。這樣做的理由也是為了節(jié)約內(nèi)存。 應用程序事件 處理應用程序事件的函數(shù)是UIP_APPCALL(),當發(fā)生任何事件時都會調(diào)用此函數(shù)。每個事件都有特定的測試函數(shù)來區(qū)分是哪種事件,這個函數(shù)是一個宏實現(xiàn),需要注意的是,事件可以同時發(fā)生。 連接指示器 當uip調(diào)用一個應用程序,全局變量uip_conn被設置成一個指向uip_conn結構體的指針,這個變量被稱作當前連接。唉這個結構體中有些變量是有用的,比如用來區(qū)分要連接的是何種服務或者是連接對方的IP地址。一個典型的應用就是通過結構體中的變量uip_conn->lport看連接端口來確定是何種服務,比如如果是80端口,就是HTTP服務器應用程序。 數(shù)據(jù)接收 如果測試函數(shù)uip_newdata()非零,那么說明接收到新數(shù)據(jù)。接收到數(shù)據(jù)的長度可以通過uip_datalen()函數(shù)獲得。數(shù)據(jù)不會被uip緩沖,但是當函數(shù)返回時數(shù)據(jù)會被覆蓋。所以應用程序必須及時處理該數(shù)據(jù)或者將數(shù)據(jù)放入另一個緩沖區(qū)中。 發(fā)送數(shù)據(jù) 發(fā)送數(shù)據(jù)時,uip通過接收者的TCP窗口大小和有效的緩沖區(qū)空間來調(diào)整發(fā)送數(shù)據(jù)的長度。緩沖空間的大小由內(nèi)存配置決定,因此有可能不是所有發(fā)送的數(shù)據(jù)都會到達接收者一方。所以可以調(diào)用uip_mss()看實際到底有多少數(shù)據(jù)發(fā)送出去了。 發(fā)送數(shù)據(jù)的函數(shù)是uip_send(),這個函數(shù)需要兩個參數(shù),一個是指向發(fā)送數(shù)據(jù)的指針和發(fā)送數(shù)據(jù)的長度。如果應用程序需要RAM空間來發(fā)送數(shù)據(jù)的話,那么包緩沖區(qū)(就是由uip_appdata指向的緩沖區(qū))可以用于此目的。 在一個連接的同一時間只能有一塊數(shù)據(jù)被發(fā)送,在一次應用程序里調(diào)用多次uip_send()是不可能的,它只會把最后調(diào)用的數(shù)據(jù)包發(fā)出去。 數(shù)據(jù)重發(fā) 重發(fā)是由周期TCP定時器驅(qū)動的,每次超時定時器調(diào)用時,每個連接的重發(fā)定時器就會減少,如果重發(fā)定時器減少到0,那么重發(fā)就要重發(fā)數(shù)據(jù)。因為uip在發(fā)送數(shù)據(jù)包后不會保存數(shù)據(jù),所以需要手動處理重發(fā)數(shù)據(jù)。當uip確定有一段需要重發(fā)時,應用程序調(diào)用uip_rexmit()設置標志,表明有重發(fā)要求。 應用程序會檢查重發(fā)標志然后產(chǎn)生重發(fā)數(shù)據(jù),從應用程序角度來看,重發(fā)的數(shù)據(jù)和原來的數(shù)據(jù)沒有什么不同,所以這兩段代碼是一樣的。 關閉連接 應用程序通過調(diào)用uip_close()來關閉連接。這種關閉是正常的關閉連接。如果為了表示是嚴重錯誤而導致的關閉,那么應用程序應該調(diào)用uip_abort()來終止連接。 如果連接被關閉的話,那么uip_closed()會返回真,接著應用程序就可以繼續(xù)做必要的清理工作了。 報告錯誤 在一個連接中有兩種嚴重的錯誤會發(fā)生,一種是連接被異常終止或者數(shù)據(jù)多次重發(fā)無效而終止。uip會分別通過調(diào)用測試函數(shù)uip_aborted()和uip_timeout()來報告這些錯誤信息。 輪詢 當連接空閑時,uip就會在每次超時時間到達時進行輪詢。輪詢的函數(shù)是uip_poll()。 輪詢的目的有兩個,第一個目的是讓應用程序知道有空閑的連接,并讓空閑太久的連接關閉。第二個目的是讓應用程序發(fā)送新產(chǎn)生的數(shù)據(jù)。發(fā)送數(shù)據(jù)只能由uip來調(diào)用。因此輪詢是在空閑連接時發(fā)送數(shù)據(jù)的唯一方式。 監(jiān)聽端口 監(jiān)聽端口的函數(shù)是uip_listen()。當連接需要和端口綁定時,uip就會創(chuàng)建一個連接并調(diào)用此函數(shù)。如果應用程序調(diào)用此函數(shù)的話,uip_connected()就會返回真。 開始連接 打開一個新的連接的函數(shù)是uip_connect(),這個函數(shù)會返回一個指針指向uip_conn()結構體。如果沒有多余的空閑槽,那么函數(shù)返回NULL。 函數(shù)uip_ipaddr()用于將IP地址放入兩個16位的數(shù)組,用來表示IP地址。
總結
- 上一篇: c语言创建一个bat文件内容,基础教程:
- 下一篇: DAC 实验