1. 程式人生 > >Oment++ 初學者教程 第4節-將其轉變為真實網路

Oment++ 初學者教程 第4節-將其轉變為真實網路

## 4.1兩個以上的節點 現在,我們將邁出一大步:建立幾個`tic`模組並將它們連線到網路中。現在,我們將使它們的工作變得簡單:一個節點生成一條訊息,其他節點繼續沿隨機方向扔訊息,直到它到達預定的目標節點為止。NED檔案將需要進行一些更改。首先,該`Txc`模組將需要具有多個輸入和輸出門: ```cpp simple Txc10 { parameters: @display("i=block/routing"); gates: input in[]; //宣告input,ouput兩種型別的gate陣列 output out[]; } ``` `陣列[ ]`多個門變成gate向量。向量的大小(門數)將在我們使用Txc構建網路的地方確定。 ```cpp network Tictoc10 { submodules: tic[6]: Txc10; connections: tic[0].out++ --> { delay = 100ms; } --> tic[1].in++; tic[0].in++ <-- { delay = 100ms; } <-- tic[1].out++; tic[1].out++ --> { delay = 100ms; } --> tic[2].in++; tic[1].in++ <-- { delay = 100ms; } <-- tic[2].out++; tic[1].out++ --> { delay = 100ms; } --> tic[4].in++; tic[1].in++ <-- { delay = 100ms; } <-- tic[4].out++; tic[3].out++ --> { delay = 100ms; } --> tic[4].in++; tic[3].in++ <-- { delay = 100ms; } <-- tic[4].out++; tic[4].out++ --> { delay = 100ms; } --> tic[5].in++; tic[4].in++ <-- { delay = 100ms; } <-- tic[5].out++; } ``` 在這裡,我們建立了6個模組作為模組向量,並將它們連線起來。 生成的拓撲如下所示: ![](https://cdn.nlark.com/yuque/0/2021/png/12898141/1617198957405-fd68a32a-0855-4254-94cf-c99a2ec7067a.png#align=left&display=inline&height=316&margin=%5Bobject%20Object%5D&originHeight=316&originWidth=372&size=0&status=done&style=none&width=372) 在此版本中,`tic[0]`將生成要傳送的訊息。這是在函式`initialize()`的幫助下完成的,該`getIndex()`函式返回向量中模組的索引。 程式碼的`forwardMessage()`實質是`handleMessage()`每當訊息到達節點時我們從中呼叫的函式。它繪製一個隨機的gate number,並在該gate上傳送message。 ```cpp void Txc10::forwardMessage(cMessage *msg) { // 我們選擇隨機的一個gate傳送資訊 // 我們在0~out[]陣列長度之間選擇一個隨機數 int n = gateSize("out"); int k = intuniform(0, n-1); EV << "Forwarding message " << msg << " on port out[" << k << "]\n"; send(msg, "out", k); } ``` 當訊息到達時`tic[3]`,`handleMessage()`它將刪除該訊息。 請參閱[txc10.cc中](https://docs.omnetpp.org/showfile/?url=tutorials/tictoc/code/txc10.cc)的完整程式碼 練習 您會注意到,這種簡單的“路由”效率不是很高:通常,資料包會在兩個節點之間不斷跳動一段時間,然後再發送到另一個方向。如果節點不將資料包傳送回傳送方,則可以在某種程度上進行改進。實現這一點。提示:`cMessage::getArrivalGate()`, `cGate::getIndex()`。請注意,如果訊息不是通過門到達的,而是self-messages,則`getArrivalGate()`返回`NULL`。 來源:[tictoc10.ned](https://docs.omnetpp.org/showfile/?url=tutorials/tictoc/code/tictoc10.ned),[txc10.cc](https://docs.omnetpp.org/showfile/?url=tutorials/tictoc/code/txc10.cc),[omnetpp.ini](https://docs.omnetpp.org/showfile/?url=tutorials/tictoc/code/omnetpp.ini) ## 4.2通道和內部型別定義 我們新的網路定義變得非常複雜冗餘,尤其是連線部分。讓我們嘗試簡化它。我們注意到的第一件事是,連線始終使用相同的`delay`引數。與簡單模組類似,可以為連線建立型別(它們稱為通道)。我們應該建立一個指定延遲引數的通道型別,並將該型別用於網路中的所有連線。 ```cpp network Tictoc11 { types: channel Channel extends ned.DelayChannel { delay = 100ms; } submodules: ``` 如您所見,我們通過新增一個`types`欄位在網路定義中定義了新的通道型別。此型別定義僅在網路內部可見。它稱為區域性或內部型別。如果願意,您也可以將簡單模組用作內部型別。 筆記 我們通過專門內建來建立通道`DelayChannel`。(可以在`ned`包內找到內建通道。這就是為什麼我們在`extends`關鍵字後使用完整型別名稱的`ned.DelayChannel的原因`) 現在,讓我們檢查一下該`connections`部分是如何更改的。 ```cpp connections: tic[0].out++ --> Channel --> tic[1].in++; tic[0].in++ <-- Channel <-- tic[1].out++; tic[1].out++ --> Channel --> tic[2].in++; tic[1].in++ <-- Channel <-- tic[2].out++; tic[1].out++ --> Channel --> tic[4].in++; tic[1].in++ <-- Channel <-- tic[4].out++; tic[3].out++ --> Channel --> tic[4].in++; tic[3].in++ <-- Channel <-- tic[4].out++; tic[4].out++ --> Channel --> tic[5].in++; tic[4].in++ <-- Channel <-- tic[5].out++; } ``` 如您所見,我們僅在連線定義內指定通道名稱。這樣可以輕鬆更改整個網路的延遲引數。 來源:[tictoc11.ned](https://docs.omnetpp.org/showfile/?url=tutorials/tictoc/code/tictoc11.ned),[txc11.cc](https://docs.omnetpp.org/showfile/?url=tutorials/tictoc/code/txc11.cc),[omnetpp.ini](https://docs.omnetpp.org/showfile/?url=tutorials/tictoc/code/omnetpp.ini) ## 4.3使用雙向連線 如果再檢查一下該`connections`部分,我們將意識到每個節點對都通過兩個連線連線。每個方向一個。OMNeT ++ 4支援兩種方式的連線,因此讓我們使用它們。 首先,我們必須定義**雙向**(或所謂的`inout`)門,而不是之前使用的分離`input`和`output`門。 ```cpp simple Txc12 { parameters: @display("i=block/routing"); gates: inout gate[]; // declare two way connections } ``` 新`connections`部分如下所示: ```cpp connections: tic[0].gate++ <--> Channel <--> tic[1].gate++;//tic[0].gate[0]<-->tic[1].gate[0] tic[1].gate++ <--> Channel <--> tic[2].gate++;//tic[1].gate[1]<-->tic[2].gate[1] tic[1].gate++ <--> Channel <--> tic[4].gate++; tic[3].gate++ <--> Channel <--> tic[4].gate++; tic[4].gate++ <--> Channel <--> tic[5].gate++; } ``` 我們已經修改了門名稱,因此我們必須對C ++程式碼進行一些修改。 ```cpp void Txc12::forwardMessage(cMessage *msg) { // In this example, we just pick a random gate to send it on. // We draw a random number between 0 and the size of gate `gate[]'. int n = gateSize("gate"); int k = intuniform(0, n-1); EV << "Forwarding message " << msg << " on gate[" << k << "]\n"; // $o and $i 字尾被用來識別門的雙向輸入輸出 send(msg, "gate$o", k); } ``` 筆記 gate名稱後的特殊**$i**和**$o**字尾允許我們分別使用連線的兩個方向。 來源:[tictoc12.ned](https://docs.omnetpp.org/showfile/?url=tutorials/tictoc/code/tictoc12.ned),[txc12.cc](https://docs.omnetpp.org/showfile/?url=tutorials/tictoc/code/txc12.cc),[omnetpp.ini](https://docs.omnetpp.org/showfile/?url=tutorials/tictoc/code/omnetpp.ini) ## 4.4定義我們的message class 在此步驟中,不再對目標地址進行硬編碼`tic[3]`-我們繪製一個隨機目標,然後將目標地址新增到訊息中。 最好的方法是重寫cMessage的子類並將目標新增為資料成員。手動編碼訊息類通常很乏味,因為它包含許多樣板程式碼,因此我們讓OMNeT ++為我們生成該類。訊息類規範位於`tictoc13.msg`: ```cpp message TicTocMsg13 { int source; int destination; int hopCount = 0; } ``` 筆記 有關訊息的更多詳細資訊,請參見OMNeT ++手冊的[第6節](https://doc.omnetpp.org/omnetpp/manual/#cha:msg-def)。 設定makefile以便呼叫訊息編譯器opp_msgc並生成訊息宣告`tictoc13_m.h`並`tictoc13_m.cc`從訊息宣告生成(檔名是根據`tictoc13.msg`檔名而不是訊息型別名生成的)。它們將包含一個`TicTocMsg13`從[ `cMessage`]子類生成的類;該類將為每個欄位提供getter和setter方法。 我們將`tictoc13_m.h`在我們的C ++程式碼中包含該程式碼,並且可以將其`TicTocMsg13`用作任何其他類。 ```cpp #include "tictoc13_m.h" ``` 例如,我們使用以下幾行`generateMessage()`來建立訊息並填寫其欄位。 ```cpp TicTocMsg13 *msg = new TicTocMsg13(msgname); msg->setSource(src); msg->setDestination(dest); return msg; ``` 然後,`handleMessage()`像這樣開始: ```cpp void Txc13::handleMessage(cMessage *msg) { TicTocMsg13 *ttmsg = check_