uIP TCP Server 運行機制分析

uIP TCP Server 運行機制分析
        

        對於任何一個協議棧而言,首先要實現的就是TCP Server,下面看看uIP的運行機制:

        ①IP地址以及端口的綁定

        uIP在初始化時進行了本機地址IP地址的默認初始化,並將其存放在一個名爲uip_hostaddr的結構體中,本機默認爲192.168.1.11同樣對子網掩碼和網關也進行了默認設置。如果用戶需要修改時,使用uip_sethostaddr()函數就可以使用新的IP地址對默認值進行覆蓋,當然也要設置相應的網關與子網掩碼。另外,使用uip_listen(HTONS(1000))進行端口的綁定,也就是說本機只偵聽來自端口1000發來的請求。(數據發送是按哪個端口發送呢?)

        ②下面看一看數據流通信的過程

         使用上位機軟件連接遠程IP以及爲192.168.1.11:1000,對其發起連接,實際上是進行三次握手操作,可以看到如下數據流:

         在程序的主循環中,輪詢讀取網卡中新的數據包

         uip_len= tapdev_read()

         如果收到的是一個IP包,那麼要對數據格式進行判斷,進入

         uip_input()同時傳入一個flag==1,代表接收到一個新的數據包,首先剝離IP包頭,指向其中的數據,接着對數據包個數進行統計UIP_STAT(++uip_stat.ip.recv);

        檢查IP協議版本號,如果正確則計算數據長度:

        if((BUF->len[0]<< 8) + BUF->len[1] <= uip_len) {

        uip_len = (BUF->len[0] << 8) + BUF->len[1];計算數據長度

        檢查數據包的目的IP是否爲本機地址

        if(!uip_ipaddr_cmp(BUF->destipaddr,uip_hostaddr)) {

                UIP_STAT(++uip_stat.ip.drop);

                goto drop;

        }

        如果是發往本機的數據包,那麼就檢查數據包校驗和

         if(uip_ipchksum()!= 0xffff) ,如果正確的話就說明這是一個完整的IP包,那上層協議是什麼呢?下面檢查協議類型,如果是TCP數據包,就跳轉到goto tcp_input,如果是UDP數據包,就跳轉到goto udp_input去執行,如果是ping包發來的icmp請求就寫入回覆標誌,交換IP,返回迴應包。本次試驗發送的是一個TCP連接請求,所以要對TCP數據包進行處理。

         判定了是一個TCP數據包,就要對數據包個數進行計數,有利於數據統計。下面再計算

TCP數據包校驗和是否正確 if(uip_tcpchksum()!= 0xffff) 。

         下面的查看現有是否存在有效連接。衆所周知,TCP server允許多個TCP client同時對其連接,使用for(uip_connr = &uip_conns[0]; uip_connr <= &uip_conns[UIP_CONNS- 1];

     ++uip_connr)查看,如果已經建立了有效連接,就到goto found;此時,通過抓包工具已經可以看出

我們的目標板已經發送了一個數據幀做了SYN的應答,下面可以看到這一過程。

         就是,如果沒有發現有效的連接,現在只用接收TCP_SYN同步數據包,如果是一個TCP_SYN同步數據包,並且是已經註冊的監聽端口,就到found_listen處執行進行連接註冊,把源端口、目的端口、源IP地址記錄下來(肯定是發往目標板端口的),然後建立BUF->flags = TCP_SYN | TCP_ACK標誌,tcp_send將回應包發出去。看到這裏就不難明白goto found;之前那幾行代碼的用意了,就是尋找已經建立好的連接。

         那麼我們接着往found下面看:

         既然是有效的連接,那麼接下來要看發來的數據包有沒有有效的數據,可以計算數據長度得知uip_len的多少,如果if(uip_len > 0) uip_flags |= UIP_NEWDATA;就說明接收到了新的數據,調用UIP_APPCALL()進行處理,之後通過UIP_APPCALL()調用處理之後的函數發出去。

        應用程序調用

       下面看一下UIP_APPCALL()是如何對數據進行解析和處理的。在這裏我做了一個簡單的測試,使用TCP&UDP調試工具想目標機發送一個指令,下位機進行解析處理以及返回。先看一個數據結構:struct uip_conn{},這個結構體代表了一個TCP的連接關係,記錄當前數據包的狀態。

        在這個結構體的最後定義應用程序定義的結構體tcp_demo_appstate,這裏面可以定義一些狀態作爲TCP數據控制的補充,也可以實現狀態機控制數據處理。TCP數據指針爲uip_appdata,數據長度爲uip_len,可以對其複製新的數據值以及新的數據長度,出去包頭可以傳輸的最大數據段爲1460個字節。
        uIP這個協議棧在uIP.c中實現了數據幀的校驗,實現了連接的建立與查詢以及用戶程序的調用,考慮縝密,簡單強大。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章