• 沒有找到結果。

NS2 資料傳輸模組的製作

在文檔中 中 華 大 學 (頁 54-70)

圖 4-1 為 ecapp 的主要結構,以下我們會詳細的說明主要的成員函數,而這 樣成員函數的實現則會在 ecapp 中介紹。

首先在第三章中提到,ecapp 是繼承 Application 的一個子類別,我們會對其中比 較重要的幾項來做說明。

(1) send(int nbytes):此成員函數只是單純用來傳送 n 個 bytes 的封包流量,如果 將 send()成員函數的參數設定為-1,那麼便會一直傳送封包,直到系統模擬 時間結束為止,此成員函數的缺點為無法指定要傳送的行動節點對象。

(2) sendto(int nbytes, AppData* data, const char* flags, nsaddr_t dst):此成員函數為 ecapp 最主要的成員函數,int nbytes 為欲傳送的封包大小,AppData* data 是傳送真實資料的 NS2 結構,因為應用層只有負責運作需要傳送什麼樣的 資料,真正的資料包裝會交給代理層去執行,因此在這個地方只是使應用層 與代理層之間的溝通正確,才需要定義為此資料結構的型態,而 nsaddr_t dst 為的行動節點編號,也就是想要傳送資料給那一個行動節點。

(3) command(int argc, const char*const* argv):可以視為 NS2 中所以程式執行的開 端,應用層中的 command 主要是用來接收 TCL 中所需入的參數個數及第幾 個參數所要執行的動作,在下面會有完整的功能介紹。

(4) start():功能類似 send(int nbytes),不過 start 的功能是一直傳送相同大小的封 包流量,直到下達 stop 指令才會停止。

(5) stop():用來停止 start 的成員函數。

(6) Agent *agent_:連接應用層與代理層的一個重要參數,我們在上述章節中有 描述此變數的結構圖,如果沒有正確的將應用層與代理層使用此成員資料連 接起來,應用層上的功能與變數就無法正確的傳遞到代理層上,使代理層運 作。

(7) nsaddr_t dst:為 NS2 中定義行動節點的位置,通常都是使用行動節點的編號 來作為代表,舉例來說,要傳送資料給行點節點 1,那麼我們在 sendto 的 nsaddr_t dst 參數中填入 1 便能傳送資料給行動節點 1。

接下來我們會對 ecapp 各成員函數深入的去解釋,包含了 command、send 與 sendto。首先是 command 的部份,分為輸入的外部參數的個數為 2、3、6 三個 部份來介紹,圖 4-2 為外部參數個數 2 的詳細解說。

圖 4-2 類別 ecapp 的成員函式 command()(1/3)

在圖 4-2 中我們可以看到有 start 和 stop 這兩個成員函數可執行,當研究人 員想要在系統時間 1 秒時開始一直傳送封包流量時,可以透過 TCL 下達一個指 令「$ns at 1.0“$ecapp start”」,此 TCL 指令,可以看到 command 會去判斷有兩 個輸入參數$ecapp 與 start,並根據 start 去執行成員函數。相同的,如果想要在 系統時間 3 秒時結束傳輸,同樣可以透過$ns at 3.0“$ecapp stop”」的指令去中止 傳輸。

接下來是圖 4-3 是外部參數個數 3 的詳細解說。

圖 4-3 類別 ecapp 的成員函式 command()(2/3)

在圖 4-3 可以看到分為 attach-agent 與 send 兩個成員資料,首先我們先來介 紹 attach-agent,此成員資料是將應用層與代理層連結的一個重要關鍵,TCL 的 語法如下:「$ecapp attach-agent $tcp」,當 TCL 下了此指令後,NS2 會透過 command 中的 attach-agent 去做判斷,當有定義的此代理層時,便可順利的連結應用層與 代理層,反之,便會出現 error 的訊號,要求要連結到正確的代理層。而 send 的 TCL 語法為「$ns at 1.0“$ecapp send 512”」,當系統時間為 1 秒時,command 接 收到 send 此指令,並會將欲傳送的流量封包大小透過 send()告知代理層。

最後圖 4-4 所介紹的是外部參數個數 6 的情形。

圖 4-4 類別 ecapp 的成員函式 command()(3/3)

sendto()在 TCL 的語法為「$ns at 1.0 “$ecapp sendto 512 realdata 1 ”」,可視為在 1 秒時 ecapp 欲傳送一個 512KB 大小的封包內含 realdata 的資料給行動節點 1 , 在 command 中,因為是在應用層的範圍內,故只會針對欲傳送的資料進行符合 NS2 所定義的資料結構去做填入的動作,其它的參數都交由代理層去處理,關於 sendto()更詳細的運作,我們在第四章實驗的部份有清楚的描述。

最後可以從圖 4-5 中看到應用層和代理層之間是如何互動,我們舉 sendto() 與 send()來做解說。

圖 4-5 類別 ecapp 的成員函式 sendto()與 send()

在此兩個程式中,可以看見 agent_->sendto 和 agent_->send,這是代表應用 層透過上述的 Agent *agent_和代理層連結後,使用 agent_來指向所連結的代理 層,而代理層也會有相對應的功能函數來接收處理應用層的下達的功能。下面我 們會介紹代理層的程式部份。

第二節  資料傳輸模組代理層的製作 

在代理層的部份,會分為發送端 TCP 與接收端 TCPSink 兩個代理層來做介 紹,這是因為在前面章節所提過,NS2 中的 TCP 並非是雙工的代理層,因此需 要另一個相對應的接收代理層才能使行動節點具有傳送與接收的功能。在代理層 的實作介紹中,因為代理層的程式比之應用層來說是相當的繁瑣,故此我們只會 對代理層的結構與主要傳輸的部份做介紹。

(1) TCP:

圖 4-6 為介紹 TCP 的類別部份,其中我們會對幾個較重要的成員資料提出 說明。

圖 4-6 類別 tcpagent 的成員資料

ts 代表封包在來源產生時的系統時間;seqno_為封包的編號,每一個封包的 編號都是唯一的;ackno_為 ack 的編號;hlen_代表封包的表頭長度,不包含封包 的資料區塊;offset_為封包表頭所在的正確位置,由於在實驗時說明會更明瞭,

因此我們在實驗時會仔細的解說。再來會針對 TCP 的程式運作說明,會著重在 應用層中使用 sendto 功能函數將所想要傳送的封包大小、資料與目標行動節點 透過 agent_->sendto()傳遞給 TCP 之後的運作說明。圖 4-7 為 TCP 中的 sendto() 部份。

圖 4-7 類別 tcpagent 的成員函式 sendto()

dsts_與 dats 為我們所自訂的一個全域變數,以便封包傳輸時一些資料的取 用,dst_主要是將所要傳送的目標行動節點記錄下來;dats 則是將應用層中所傳 遞的資料使用 NS2 的 PacketData 中已經定義好的 copy 函示將整個結構放入其 中,最後會至 send_much()執行 TCP 的一些判斷。

圖 4-8 類別 tcpagent 的成員函式 send_much()

圖 4-8 為 tcp 中的 send_much(),我們只挑選較重要的部份列出,在 send_much() 中主要是判斷封包的編號與傳輸量是否有超過預設的最大傳輸量,之後便會交由 output()此成員函數執行封包的製作與表頭的填入,便能將資料封包送出。

圖 4-9 類別 tcpagent 的成員函式 output()

在圖 4-9 中,主要的工作是在建立 NS2 中的傳輸封包結構,Packet* p = allocpkt()便是分配一個新的封包,要特別說明的是在 NS2 中為了要節省資源的 耗費,通常會將使用過的封包放入一個空的 LINK LIST 中,當需要封包時,會 先從此 LINK LIST 尋找是否有可以的封包,若無,再新建一個封包結構,以節 省系統資料的耗費。當建立好封包後,會填入封包所需要的表頭,而封包的目的 地,便是由應用層上面所想要傳送到的目標行動節點決定,當應用層決定要廣播 時,就使用-1 表示;反之則填入行動節點的編號。最後將欲傳送的資料透過 p->setdata(dats)放入封包的資料區塊,最後使用 send(p,0)透過底層的節點連結層 傳送出去,在此我們並不會討論到節點連節層,故並不會再深入的去介紹結點連 結層中的 send(p,0)。接著會對 TCPSink 介紹如何接收由 TCP 所傳送出去的資料 封包。

(2) TCPSink:

TCPSink 的主要類別可以分為兩個部份,Acker 與 TCPSink 本身,其中 Acker 是 處理三次交握的部份,而 TCPSink 的類別中,最主要的部份是 recv(),在圖 4-10 與 4-11 之後會對 recv()如何接收由 TCP 所傳送的資料作介紹。

圖 4-10 類別 tcpsink 中的 acker 類別

圖 4-11 類別 tcpsink

在看過 Acker 與 TCPSink 的類別之後,下面會對 TCPSink 中的成員函數 recv() 做描述,敘述如何接收由 TCP 透過節點連結層傳送的資料封包。

圖 4-12 類別 tcpsink 的成員函式 recv()

當資料封包透過 send(p,0)傳送出去之後,經由節點連節層的中的路由,會傳 送目的地節點的節點連結層,再由節點連節層往上傳送給 TCPSink 中的 recv(),

如圖 4-12 所示,當 recv()收到封包之後會由封包的時間去判斷此封包是否為有效 封包,如果不是,便會直接將此封包 free 掉;反之,會利用此封包的資訊將 ack 的資訊作更新,再來便是將我們想傳送的真實資料從封包中取出,並儲存,最後 透過 ack 結束行動節點間的通訊,並把封包給 free 掉,以免佔用系統資源。

以上是模組實作的部份,我們將其分為應用層與代理層來說明。在下一章的 部份我們會使用一個 TCL 的腳本來解說我們的實驗部份。

第三節        模擬實驗 

在此小節中,我們已經預先將 NS2 所有的行動節點所需的設定包含應用層、

代理層與節點連節層都設定完成。接下來我們會利用一個 TCL 的開始語法說明 整個實驗的過程,在前面的章節我們有提過,此實驗能分為廣播與點對點兩種不 同的方式去傳送資料,在 TCL 指令時我們便能決定是否需要廣播或是點對的傳 輸方式,而廣播的範圍是以行動節點的一次跳躍(one-hop)的通訊範圍內的所有行 動節點為傳送對象;點對點則是一般所熟知的兩個行動節點之間的互相通訊。

從 TCL 指令開始對應用層下達傳送指真實資料的指令,應用層會根據所要 傳送的封包大小、資料內容與是否為廣播或點對點的方式去做決定,然後先將要 傳送的真實資料依照 NS2 中已經建立的資料格式,將資料置入,之後便交由代 理層去執行,這也是為什麼我們前面說新建一個應用層並不會對我們所想知道的 一些行動節點上的資訊,如行動節點的耗電。

因為新建應用層僅是對欲傳送的資料進行放置的動作,其它的行為都是經由 代理層上來的協定來執行。在代理層中,主要的工作是針對所使用的代理協定去 製作我們在一般網路中所謂的封包,這些封包所包含的資訊與詳細的結構會在下 面說明,在完成封包的製作後,會將由應用層中所準備傳送的真實資料一併的放

入封包中,最後透過最底層的節點連節層將此封包送出,完成我們所想要的以完 整的 NS2 三層架構去達成傳送真實的料的目的。表 4-1 為實驗中所使用的一些 主要參數設定,包含 NS2 中的參數。

表 4-1 參數設定

說明 參數

行動隨意網路範圍 1200 m X 800 m

路由協定 Ad hoc On-demand Distance

Vector(AODV)

行動節點移動速動 1-5 m/s

行動節點移動樣型 Random Waypoint channel type WirelessChannel radio-propagation model TwoRayGround network interface type WirelessPhy

MAC type 802_11

interface queue type DropTail/PriQueue max packet in ifq 50

在文檔中 中 華 大 學 (頁 54-70)

相關文件