Oment++ 初學者教程 第4節-將其轉變為真實網路
阿新 • • 發佈:2021-04-02
## 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_