Výukový program síťového simulátoru ns-3. Kapitola 4

Výukový program síťového simulátoru ns-3. Kapitola 4
kapitola 1,2
kapitola 3

4 Přehled konceptu
4.1 Klíčové abstrakce
4.1.1 Uzel
4.1.2 Aplikace
4.1.3 Kanál
4.1.4 Síťové zařízení
4.1.5 Topologičtí asistenti
4.2 První skript ns-3
4.2.1 Kód kotelní desky
4.2.2 Zásuvné moduly
4.2.3 jmenný prostor ns3
4.2.4 Protokolování
4.2.5 Hlavní funkce
4.2.6 Použití asistentů topologie
4.2.7 Používání aplikace
4.2.8 Simulátor
4.2.9 Vytvoření skriptu
4.3 ns-3 Zdrojový kód

Kapitola 4

Přehled konceptu

První věc, kterou musíme udělat, než se začneme učit nebo psát kód ns-3, je vysvětlit několik základních pojmů a abstrakcí v systému. Někomu se mnohé z toho může zdát samozřejmé, ale doporučujeme věnovat čas přečtení této části, abyste měli jistotu, že začínáte na pevných základech.

4.1 Klíčové abstrakce

V této části se podíváme na některé termíny, které se běžně používají na webu, ale mají specifický význam v ns-3.

4.1.1 Uzel

V internetovém žargonu se počítačové zařízení, které se připojuje k síti, nazývá hostitel nebo někdy koncový systém. Protože ns-3 je síťový simulátor a nikoli internetový simulátor, záměrně nepoužíváme termín hostitel, protože ten úzce souvisí s internetem a jeho protokoly. Místo toho používáme obecnější termín, používaný také jinými simulátory, který má původ v teorii grafů: node (uzel).

V ns-3 se základní abstrakce výpočetního zařízení nazývá uzel. Tato abstrakce je v C++ reprezentována třídou Node. Třída NodeNode (node) poskytuje metody pro manipulaci s reprezentacemi výpočetních zařízení v simulacích.

Musíte pochopit Uzel jako počítač, ke kterému přidáte funkce. Přidáte věci, jako jsou aplikace, zásobníky protokolů a periferní karty s ovladači, které umožňují počítači dělat užitečnou práci. Stejný základní model používáme v ns-3.

4.1.2 Aplikace

Obecně se počítačový software dělí do dvou širokých tříd. Systémový software organizuje různé počítačové zdroje, jako je paměť, cykly procesoru, disk, síť atd. podle nějakého výpočetního modelu. Systémový software tyto prostředky obvykle nepoužívá k provádění úkolů, které přímo prospívají uživateli. Uživatel obvykle spouští aplikaci k dosažení konkrétního cíle, která získává a využívá prostředky řízené systémovým softwarem.

Linie oddělení mezi systémovým a aplikačním softwarem je často vedena změnami na úrovni oprávnění, ke kterým dochází v pastech operačního systému. ns-3 nemá žádný skutečný koncept operačního systému, a proto ani koncept úrovní oprávnění nebo systémových volání. Máme však nápad na aplikaci. Stejně jako v „reálném světě“ softwarové aplikace běží na počítačích k provádění úkolů, aplikace ns-3 běží na uzlech ns-3 pro řízení simulací v simulovaném světě.

V ns-3 je základní abstrakcí pro uživatelský program, který generuje nějakou aktivitu pro modelování, aplikace. Tato abstrakce je v C++ reprezentována třídou Application. Třída Application poskytuje metody pro manipulaci se zobrazeními naší uživatelské verze aplikací v simulacích. Od vývojářů se očekává, že specializují třídu Application na objektově orientované programování, aby mohli vytvářet nové aplikace. V tomto tutoriálu použijeme specializace třídy Application tzv Aplikace UdpEchoClient и Aplikace UdpEchoServer. Jak můžete očekávat, tyto aplikace tvoří sadu klient/server aplikací používaných ke generování a echo síťových paketů.

4.1.3 Kanál

V reálném světě můžete připojit počítač k síti. Média, přes která jsou data přenášena v těchto sítích, se často nazývají kanály. Když zapojíte ethernetový kabel do zásuvky ve zdi, připojíte počítač k ethernetové lince. V simulovaném světě ns-3 je uzel připojen k objektu představujícímu komunikační kanál. Zde se základní abstrakce komunikační podsítě nazývá kanál a v C++ je reprezentována třídou Channel.

Třída ChannelChannel poskytuje metody pro řízení interakce objektů podsítě a připojení uzlů k nim. Kanály mohou být také specializovány vývojáři ve smyslu objektově orientovaného programování. Specializace kanálu může modelovat něco tak jednoduchého, jako je drát. Vyhrazený kanál může také modelovat složité věci, jako je velký ethernetový přepínač nebo trojrozměrný prostor plný překážek v případě bezdrátových sítí.

V tomto tutoriálu budeme používat specializované verze kanálu s názvem CsmaChannelCsmaChannel, PointToPointChannelPointToPointChannel и WifiChannelWifiChannel. CsmaChannel, například modeluje verzi komunikační podsítě, která implementuje komunikační prostředí s vícenásobným přístupem se snímáním nosného signálu. To nám dává funkcionalitu podobnou Ethernetu.

4.1.4 Síťové zařízení

Dříve platilo, že pokud jste chtěli připojit počítač k síti, museli jste si zakoupit specifický síťový kabel a hardwarové zařízení zvané (v PC terminologii) periferní karta, kterou bylo potřeba do počítače nainstalovat. Pokud periferní karta implementovala nějaké síťové funkce, nazývaly se síťové karty nebo síťové karty. Dnes se většina počítačů dodává s integrovaným hardwarem síťového rozhraní a uživatelé je nevidí jako samostatná zařízení.

Síťová karta nebude fungovat bez softwarového ovladače, který řídí její hardware. V Unixu (nebo Linuxu) je periferní zařízení klasifikováno jako zařízení. Zařízení jsou spravována pomocí ovladačů zařízení a síťová zařízení (NIC) jsou spravována pomocí ovladačů síťových zařízení (ovladače síťových zařízení) a společně se nazývají síťová zařízení (síťová zařízení). V Unixu a Linuxu odkazujete na síťová zařízení jmény jako např eth0.

V ns-3 abstrakce síťových zařízení pokrývá jak softwarový ovladač, tak modelovaný hardware. V simulaci je síťové zařízení „instalováno“ do uzlu, aby mohlo komunikovat s ostatními uzly prostřednictvím kanálů. Stejně jako skutečný počítač může být uzel připojen k více kanálům prostřednictvím více zařízení NetDevices.

Síťová abstrakce zařízení je v C++ reprezentována třídou NetDevice. Třída NetDevice poskytuje metody pro správu připojení k objektům Node a Channel; a mohou být vývojáři specializováni ve smyslu objektově orientovaného programování. V tomto tutoriálu použijeme několik specializovaných verzí NetDevice tzv CsmaNetDevice, PointToPointNetDevice и Zařízení WifiNet. Stejně jako síťový adaptér Ethernet je navržen pro práci se sítí Ethernet, CsmaNetDevice navržený pro práci s CsmaChannel, PointToPointNetDevice navržený pro práci s PointToPointChannela Zařízení WifiNet - navržený pro práci s Wifi kanál.

4.1.5 Topologičtí asistenti

Ve skutečné síti najdete hostitelské počítače s přidanými (nebo zabudovanými) síťovými kartami. V ns-3 bychom řekli, že uvidíte uzly s připojenými zařízeními NetDevices. Ve velké simulované síti budete muset zorganizovat spojení mezi mnoha objekty Uzel, NetDevice и Kanál.

Od připojení NetDevices k uzlům, NetDevices k linkám, přidělování IP adres atd. v ns-3 jsou běžným úkolem, abychom to co nejvíce usnadnili, poskytujeme tzv. topologické pomocníky. Chcete-li například vytvořit zařízení NetDevice, musíte provést mnoho operací jádra ns-3, přidat adresu MAC, nainstalovat síťové zařízení do uzlu, nakonfigurovat zásobník protokolů uzlu a poté připojit zařízení NetDevice ke kanálu. Ještě více práce bude vyžadovat připojení více zařízení k vícebodovým spojům a následné připojení jednotlivých sítí do sítě Internetworks. Poskytujeme pomocné objekty topologie, které kombinují tyto četné operace do snadno použitelného modelu pro vaše pohodlí.

4.2 První skript ns-3

Pokud jste systém nainstalovali výše uvedeným způsobem, budete mít vydání ns-3 v adresáři nazvaném repos ve vašem domovském adresáři. Přejděte do adresáře uvolněte

Pokud takový adresář nemáte, znamená to, že jste při sestavování vydané verze ns-3 nezadali výstupní adresář, sestavte takto:
$ ./waf configure —build-profile=release —out=build/release,
$ ./waf sestavení

tam byste měli vidět strukturu adresářů podobnou následujícímu:

AUTHORS       examples      scratch       utils       waf.bat*
bindings      LICENSE       src           utils.py    waf-tools
build         ns3           test.py*      utils.pyc   wscript
CHANGES.html  README        testpy-output VERSION     wutils.py
doc           RELEASE_NOTES testpy.supp   waf*        wutils.pyc

Přejděte do adresáře příklady/návod. Měli byste vidět soubor s názvem první.cc. Jedná se o skript, který vytvoří jednoduché dvoubodové spojení mezi dvěma uzly a přenese jeden paket mezi uzly. Podívejme se na tento skript řádek po řádku; k tomu otevřete first.cc ve svém oblíbeném editoru.

4.2.1 Kód kotelní desky
První řádek v souboru je řádek režimu editoru emacs. Informuje emacs o konvencích formátování (stylu kódování), které používáme v našem zdrojovém kódu.

/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */

Toto je vždy docela kontroverzní záležitost, takže musíme uvést rekord přímo, abychom to hned dostali z cesty. Projekt ns-3, stejně jako většina velkých projektů, přijal styl kódování, kterému musí odpovídat veškerý přidaný kód. Pokud chcete přispět svým kódem do projektu, budete muset nakonec vyhovět standardu kódování ns-3, jak je popsáno v souboru doc/codingstd.txt nebo zobrazené na webové stránce projektu: https://www.nsnam.org/develop/contributing-code/coding-style/.

Doporučujeme, abyste si zvykli na vzhled a chování kódu ns-3 a použili tento standard, kdykoli budete pracovat s naším kódem. Celý vývojářský tým a přispěvatelé s tím po nějakém reptání souhlasili. Řádek režimu emacs výše usnadňuje správné formátování, pokud používáte editor emacs.

Simulátor ns-3 je licencován GNU General Public License. V každém distribučním souboru ns-3 uvidíte příslušnou legální hlavičku GNU. Často uvidíte upozornění na autorská práva pro jednu z participujících institucí v projektu ns-3 nad GPL textem a autorem, jak je uvedeno níže.

/* 
* This program is free software; you can redistribute it and/or modify 
* it under the terms of the GNU General Public License version 2 as 
* published by the Free Software Foundation; 
*
* This program is distributed in the hope that it will be useful, 
* but WITHOUT ANY WARRANTY; without even the implied warranty of 
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
* GNU General Public License for more details. 
* 
* You should have received a copy of the GNU General Public License 
* along with this program; if not, write to the Free Software 
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
*/

4.2.2 Zásuvné moduly

Samotný kód začíná řadou příkazů zahrnutí (obsahovat).

#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/internet-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/applications-module.h"

Abychom našim uživatelům skriptování na vysoké úrovni pomohli vyrovnat se s velkým počtem hlavičkových souborů přítomných v systému, seskupujeme je podle jejich využití do velkých modulů. Poskytujeme jeden soubor záhlaví, který rekurzivně načte všechny soubory záhlaví použité v daném modulu. Místo toho, abyste museli hledat přesně to, jakou hlavičku potřebujete a případně získat správný seznam závislostí, dáváme vám možnost stáhnout si skupinu souborů ve velké granularitě. Není to nejúčinnější přístup, ale rozhodně to značně usnadňuje psaní skriptů.

Každý ze zahrnutých souborů ns-3 je umístěn v adresáři s názvem Ns3 (podadresář sestavení), abyste se vyhnuli konfliktům názvů souborů během procesu sestavení. Soubor ns3/core-module.h odpovídá modulu ns-3, který najdete v adresáři src/core ve verzi, kterou jste nainstalovali. Ve výpisu tohoto adresáře najdete velké množství hlavičkových souborů. Když děláte montáž, Waf umístí veřejné hlavičkové soubory do adresáře ns3 v podadresáři sestavit/ladit

Pokud takový adresář nemáte, znamená to, že jste při sestavování vydané verze ns-3 nezadali výstupní adresář, sestavte takto:
$ ./waf configure --build-profile=debug --out=build/debug
$ ./waf sestavení
nebo
$ ./waf configure --build-profile=optimized --out=build/optimized
$ ./waf sestavení

nebo sestavit/optimalizovat, v závislosti na vaší konfiguraci. Waf také automaticky vygeneruje soubor pro začlenění modulu pro načtení všech veřejných hlavičkových souborů. Protože se samozřejmě řídíte tímto návodem nábožensky, už jste to udělali

$ ./waf -d debug --enable-examples --enable-tests configure

ke konfiguraci projektu tak, aby spouštěl sestavení ladění, která zahrnují příklady a testy. Vy také

$ ./waf

sestavit projekt. Takže teď, když se podíváte do adresáře ../../build/debug/ns3, pak tam najdete mimo jiné hlavičkové soubory čtyř výše uvedených modulů. Můžete se podívat na obsah těchto souborů a zjistit, že zahrnují všechny veřejné soubory používané odpovídajícími moduly.

4.2.3 jmenný prostor ns3

Další řádek ve skriptu první.cc je deklarace jmenného prostoru.

using namespace ns3;

Projekt ns-3 je implementován v jmenném prostoru C++ s názvem ns3. To seskupuje všechny deklarace související s ns-3 do oboru mimo globální jmenný prostor, což snad pomůže s integrací s jiným kódem. Použití operátoru C++ zavádí jmenný prostor ns-3 do aktuální (globální) deklarativní oblasti. To je skvělý způsob, jak říci, že po této deklaraci nebudete muset zadávat operátor oprávnění ns3::scope před veškerý váš kód ns-3, abyste jej mohli použít. Pokud nejste obeznámeni se jmennými prostory, nahlédněte do téměř jakékoli učebnice C++ a porovnejte jmenný prostor ns3 pomocí jmenného prostoru a deklarace std using namespace std; v příkladech práce s operátorem výstupu cout a proudy.

4.2.4 Protokolování

Další řádek skriptu je,

NS_LOG_COMPONENT_DEFINE ("FirstScriptExample");

Toto prohlášení použijeme jako vhodné místo k diskusi o našem dokumentačním systému Doxygen. Pokud se podíváte na webové stránky projektu ns-3, najdete v navigační liště odkaz na dokumentaci. Pokud kliknete na tento odkaz, budete přesměrováni na naši stránku dokumentace. Existuje odkaz "Nejnovější vydání", který vás zavede do dokumentace k nejnovější stabilní verzi ns-3. Pokud vyberete odkaz "Dokumentace API", budete přesměrováni na stránku dokumentace API ns-3.

V levé části stránky naleznete grafické znázornění struktury dokumentace. Dobrým místem pro začátek je „kniha“ Modules ns-3 v navigačním stromu ns-3. Pokud odhalíte moduly, zobrazí se seznam dokumentace modulů ns-3. Jak bylo diskutováno výše, koncept modulu zde přímo souvisí se soubory obsaženými ve výše uvedeném modulu. Logovací subsystém ns-3 je diskutován v části Pomocí modulu protokolování, takže se k tomu vrátíme později v tomto tutoriálu, ale o výše uvedeném prohlášení se můžete dozvědět v modulu Jádroa pak otevřít knihu Ladicí nástrojea poté vyberte stránku Přihlášení. Klikněte na Přihlášení.

Nyní byste měli zkontrolovat dokumentaci Doxygen pro modul Přihlášení. V seznamu maker v horní části stránky uvidíte záznam pro NS_LOG_COMPONENT_DEFINE. Než kliknete na odkaz, nezapomeňte se podívat na „Podrobný popis“ registračního modulu, abyste pochopili, jak obecně funguje. Chcete-li to provést, můžete se posunout dolů nebo vybrat "Více..." pod grafem.

Jakmile budete mít obecnou představu o tom, co se děje, pokračujte a podívejte se na dokumentaci pro konkrétní NS_LOG_COMPONENT_DEFINE. Nebudu zde duplikovat dokumentaci, ale abych to shrnul, tento řádek deklaruje komponentu registrace tzv FirstScriptExample, který umožňuje povolit nebo zakázat protokolování zpráv konzoly odkazem na název.

4.2.5 Hlavní funkce

V následujících řádcích skriptu uvidíte,

int 
main (int argc, char *argv[])
{ 

Toto je jednoduše deklarace hlavní funkce vašeho programu (skriptu). Jako u každého programu v C++ je potřeba definovat hlavní funkci, ta se provede jako první. Není tu nic zvláštního. Váš skript ns-3 je pouze program v C++. Následující řádek nastavuje časové rozlišení na 1 nanosekundu, což je výchozí:

Time::SetResolution (Time::NS);

Časové rozlišení, nebo jednoduše rozlišení, je nejmenší časová hodnota, kterou lze použít (nejmenší reprezentovatelný rozdíl mezi dvěma časy). Rozlišení můžete změnit přesně jednou. Mechanismus, který tuto flexibilitu poskytuje, spotřebovává paměť, takže jakmile je rozlišení explicitně nastaveno, uvolníme paměť a zabráníme dalším aktualizacím. (Pokud rozlišení nenastavíte explicitně, nastaví se jako výchozí na jednu nanosekundu a paměť se uvolní při spuštění simulace.)

Následující dva řádky skriptu se používají k povolení dvou protokolovacích komponent, které jsou integrovány do aplikací EchoClient и EchoServer:

LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO); LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO);

Pokud si přečtete dokumentaci ke komponentě Logging, uvidíte, že existuje několik úrovní protokolování/zrnitosti, které můžete povolit u každé komponenty. Tyto dva řádky kódu umožňují protokolování ladění na úroveň INFO pro echo klienty a servery. Na této úrovni bude aplikace tisknout zprávy při odesílání a přijímání paketů během simulace.

Nyní se pustíme do vytváření topologie a spuštění simulace. Abychom tuto práci co nejvíce usnadnili, používáme pomocné objekty topologie.

4.2.6 Použití asistentů topologie

Následující dva řádky kódu v našem skriptu ve skutečnosti vytvoří objekty Node ns-3, které budou reprezentovat počítače v simulaci.

NodeContainer nodes;
nodes.Create (2);

Než budeme pokračovat, najdeme dokumentaci ke třídě NodeContainer. Další možností, jak se dostat k dokumentaci pro danou třídu, je přes záložku vyučování na stránkách Doxygen. Pokud již máte otevřený Doxygen, jednoduše přejděte nahoru na stránku a vyberte kartu Třídy. Měli byste vidět novou sadu karet, z nichž jedna je seznam tříd. Pod touto záložkou uvidíte seznam všech tříd ns-3. Přejděte dolů na ns3::NodeContainer. Když najdete třídu, vyberte ji a přejděte do dokumentace třídy.

Jak si pamatujeme, jednou z našich klíčových abstrakcí je uzel. Představuje počítač, do kterého přidáme věci jako zásobníky protokolů, aplikace a periferní karty. Asistent topologie NodeContainer poskytuje pohodlný způsob vytváření, správy a přístupu k libovolným objektům Uzel, který vytvoříme pro spuštění simulace. První řádek výše jednoduše deklaruje NodeContainer, které nazýváme uzly. Druhý řádek zavolá metodu Create na objektu nodes a požádá kontejner, aby vytvořil dva uzly. Jak je popsáno v Doxygen, kontejner požádá systém ns-3 o vytvoření dvou objektů Uzel a interně ukládá ukazatele na tyto objekty.

Uzly vytvořené ve skriptu zatím nic nedělají. Dalším krokem při budování topologie je připojení našich uzlů k síti. Nejjednodušší formou sítě, kterou podporujeme, je spojení typu point-to-point mezi dvěma uzly. Nyní vytvoříme takové spojení.

PointToPointHelper

Vytváříme spojení point-to-point pomocí známého vzoru a pomocí pomocného objektu topologie provádíme nízkoúrovňovou práci potřebnou pro spojení. Připomeňme, že naše dvě klíčové abstrakce NetDevice и Kanál. V reálném světě tyto pojmy zhruba odpovídají periferním kartám a síťovým kabelům. Obvykle spolu tyto dvě věci úzce souvisejí a nikdo nemůže počítat se sdílením například zařízení Ethernet přes bezdrátový kanál. Naši pomocníci topologie se řídí tímto úzkým vztahem, a proto v tomto scénáři použijete jeden objekt PointToPointHelper pro nastavení a připojení objektů ns-3 PointToPointNetDevice и PointToPointChannel. Následující tři řádky ve skriptu:

PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps")); 
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));

První řada,

PointToPointHelper pointToPoint;

vytvoří instanci objektu v zásobníku PointToPointHelper. Z pohledu nejvyšší úrovně následující řádek,

pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));

říká objektu PointToPointHelper použijte hodnotu "5 Mbit/s" (pět megabitů za sekundu) jako "Rychlost přenosu dat".

Z konkrétnějšího hlediska odpovídá řetězec "DataRate" tomu, co nazýváme atributem PointToPointNetDevice. Pokud se podíváte na Doxygen pro třídu ns3::PointToPointNetDevice a v dokumentaci k metodě GetTypeId naleznete seznam atributů definovaných pro zařízení. Mezi nimi bude atribut „Rychlost přenosu dat" Většina objektů ns-3 viditelných pro uživatele má podobné seznamy atributů. Tento mechanismus používáme ke snadnému nastavení simulace bez rekompilace, jak uvidíte v další části.

Podobný "Rychlost přenosu dat" v PointToPointNetDevice najdete atribut "Delay" spojený s PointToPointChannel. Poslední řádek

pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));

říká PointToPointHelper použijte hodnotu "2 ms" (dvě milisekundy) jako hodnotu zpoždění šíření pro spojení bod-bod, které následně vytvoří.

NetDeviceContainer

V tuto chvíli máme ve scénáři NodeContainer, který obsahuje dva uzly. My máme PointToPointHelper, který je připraven pro vytváření objektů PointToPointNetDevices a jejich propojení pomocí objektu PointToPointChannel. Stejně jako jsme k vytváření uzlů použili pomocný objekt topologie NodeContainer, zeptáme se PointToPointHelper provádět pro nás práce související s tvorbou, konfigurací a instalací našich zařízení. Potřebujeme seznam všech vytvořených objektů NetDevice, takže používáme NetDeviceContainer abychom je uložili stejným způsobem, jaký jsme používali my NodeContainer pro uložení uzlů, které jsme vytvořili. Další dva řádky kódu,

NetDeviceContainer devices;
devices = pointToPoint.Install (nodes);

kompletní nastavení zařízení a kanálu. První řádek deklaruje výše zmíněný kontejner zařízení a druhý dělá hlavní práci. Metoda instalovat objekt PointToPointHelper trvá NodeContainer jako parametr. Uvnitř NetDeviceContainer pro každý uzel umístěný v NodeContainer je vytvořen (pro komunikaci point-to-point musí být právě dva) PointToPointNetDevice se vytvoří a uloží do kontejneru zařízení. PointToPointChannel je vytvořen a dva jsou k němu připojeny PointToPointNetDevices. Po vytvoření objektů se atributy uloží do PointToPointHelper, se používají k inicializaci odpovídajících atributů ve vytvořených objektech.

Po uskutečnění hovoru pointToPoint.Install (uzly) budeme mít dva uzly, každý s nainstalovaným síťovým zařízením typu point-to-point a jedním spojením point-to-point mezi nimi. Obě zařízení budou nakonfigurována pro přenos dat rychlostí XNUMX megabitů za sekundu se zpožděním přenosu dvě milisekundy přes kanál.

InternetStackHelper

Nyní máme nakonfigurované uzly a zařízení, ale naše uzly nemají nainstalované zásobníky protokolů. O to se postarají následující dva řádky kódu.

InternetStackHelper stack;
stack.Install (nodes);

InternetStackHelper - je topologický pomocník pro internetové zásobníky, podobný PointToPointHelper pro síťová zařízení typu point-to-point. Metoda instalovat bere jako parametr NodeContainer. Po spuštění nainstaluje internetový zásobník (TCP, UDP, IP atd.) na každý uzel kontejneru.

Pomocník adresy IPv4

Poté musíme svá zařízení přiřadit k IP adresám. Poskytujeme asistenta topologie pro správu přidělování IP adres. Jediné API viditelné pro uživatele je nastavení základní IP adresy a síťové masky, které se mají použít při provádění skutečné distribuce adres (toto se provádí na nižší úrovni v rámci pomocníka). Další dva řádky kódu v našem vzorovém skriptu první.cc,

Ipv4AddressHelper address;
address.SetBase ("10.1.1.0", "255.255.255.0");

deklarujte pomocný objekt adresy a řekněte mu, že by měl začít přidělovat IP adresy ze sítě 10.1.1.0 pomocí bitové masky 255.255.255.0 k určení. Ve výchozím nastavení budou přidělené adresy začínat na jedné a budou monotónně přibývat, takže první adresa přidělená z této báze bude 10.1.1.1, poté 10.1.1.2 atd. Ve skutečnosti si systém ns-3 na nízké úrovni pamatuje všechny přidělené IP adresy a generuje fatální chybu, pokud náhodou vytvoříte situaci, kdy je stejná adresa vygenerována dvakrát (mimochodem, tato chyba se obtížně ladí).

Následující řádek kódu,

Ipv4InterfaceContainer interfaces = address.Assign (devices);

provádí skutečné přiřazení adresy. V ns-3 navážeme spojení mezi IP adresou a zařízením využívajícím objekt Rozhraní IPv4. Stejně jako někdy potřebujeme seznam síťových zařízení vytvořených asistentem pro pozdější použití, potřebujeme někdy seznam objektů Rozhraní IPv4. IPv4InterfaceContainer poskytuje tuto funkci.

Vybudovali jsme síť typu point-to-point s nainstalovanými zásobníky a přidělenými IP adresami. Nyní potřebujeme aplikace v každém uzlu, aby generovaly provoz.

4.2.7 Používání aplikace

Další z hlavních abstrakcí systému ns-3 je editaci videa (aplikace). V tomto scénáři používáme dvě specializace základní třídy editaci videa volalo ns-3 Aplikace UdpEchoServer и Aplikace UdpEchoClient. Stejně jako v předchozích případech používáme pro konfiguraci a správu základních objektů pomocné objekty. Zde používáme UdpEchoServerHelper и UdpEchoClientHelper předměty, které nám usnadňují život.

UdpEchoServerHelper

Následující řádky kódu v našem vzorovém skriptu first.cc se používají ke konfiguraci serverové aplikace UDP echo na jednom z uzlů, které jsme vytvořili dříve.

UdpEchoServerHelper echoServer (9);

ApplicationContainer serverApps = echoServer.Install (nodes.Get (1));
serverApps.Start (Seconds (1.0));
serverApps.Stop (Seconds (10.0));

Vytvoří se první řádek kódu ve výše uvedeném fragmentu UdpEchoServerHelper. Jako obvykle se nejedná o aplikaci samotnou, je to objekt, který nám pomáhá vytvářet skutečné aplikace. Jednou z našich konvencí je předat požadované atributy konstruktoru pomocného objektu. V tomto případě nemůže helper udělat nic užitečného, ​​pokud nedostane číslo portu, na kterém bude server naslouchat paketům, toto číslo musí znát i klient. V tomto případě předáme číslo portu pomocnému konstruktoru. Konstruktor na oplátku prostě dělá SetAttribute s předanou hodnotou. Později, pokud si to přejete, můžete použít SetAttribute k nastavení jiné hodnoty pro atribut Port.

Stejně jako mnoho dalších pomocných objektů, objekt UdpEchoServerHelper má metodu instalovat. Provedení této metody efektivně vytvoří základní aplikaci echo serveru a připojí ji k hostiteli. Zajímavé je, že metoda instalovat trvá NodeContainer jako parametr stejně jako ostatní instalovat metody, které jsme viděli.

Zde fungující implicitní konverze C++ přebírá výsledek metody node.Get(1) (což vrací inteligentní ukazatel na objekt uzlu - Ptr ) a použije jej v konstruktoru pro anonymní objekt NodeContainerkterý je pak předán metodě instalovat. Pokud nemůžete v kódu C++ určit, která signatura metody je zkompilována a spuštěna, podívejte se mezi implicitní převody.

Teď to vidíme echoServer.Instalovat chystáte aplikaci nainstalovat Aplikace UdpEchoServer na nalezen v NodeContainerkterý používáme ke správě našich uzlů, uzel s indexem 1. Metoda instalovat vrátí kontejner, který obsahuje ukazatele na všechny aplikace (v tomto případě jeden, protože jsme předali anonymní NodeContainer, obsahující jeden uzel) vytvořený pomocníkem.

Aplikace musí určit, kdy mají začít generovat provoz "Start" a může být nutné dodatečně specifikovat čas, kdy se má zastavit "stop". Nabízíme obě možnosti. Tyto časy se nastavují pomocí metod ApplicationContainer Home и Stop. Tyto metody přijímají parametry typu Čas. V tomto případě použijeme explicitní posloupnost převodů C++ k převzetí C++ zdvojnásobit 1.0 a převést jej na objekt tns-3 Time, který používá objekt Seconds k převodu na sekundy. Pamatujte, že pravidla převodu může řídit autor modelu a C++ má svá vlastní pravidla, takže nemůžete vždy počítat s tím, že parametry budou převedeny tak, jak jste očekávali. Dvě linky

serverApps.Start (Seconds (1.0));
serverApps.Stop (Seconds (10.0));

způsobí spuštění (automatické zapnutí) aplikace serveru echo jednu sekundu po spuštění simulace a zastavení (vypnutí) po deseti sekundách simulace. Vzhledem k tomu, že jsme vyhlásili simulační událost (aplikační stop událost), která se provede za deset sekund, bude simulováno minimálně deset sekund provozu sítě.

UdpEchoClientHelper

Klientská aplikace minout nakonfigurován způsobem téměř podobným serveru. Existuje základní objekt Aplikace UdpEchoClientspuštěn
UdpEchoClientHelper.

UdpEchoClientHelper echoClient (interfaces.GetAddress (1), 9);
echoClient.SetAttribute ("MaxPackets", UintegerValue (1));
echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.0)));
echoClient.SetAttribute ("PacketSize", UintegerValue (1024));

ApplicationContainer clientApps = echoClient.Install (nodes.Get (0));
clientApps.Start (Seconds (2.0));
clientApps.Stop (Seconds (10.0));;

Pro klienta echo však musíme nastavit pět různých atributů. První dva atributy jsou nastaveny v době vytvoření UdpEchoClientHelper. Předáme parametry, které se používají (uvnitř pomocníka) k nastavení atributů "Vzdálená adresa" и "RemotePort" v souladu s naší dohodou předat potřebné parametry pomocnému konstruktoru.

Připomeňme, že jsme použili IPv4InterfaceContainer ke sledování IP adres, které jsme našim zařízením přidělili. Rozhraní null v kontejneru rozhraní bude odpovídat adrese IP nulového uzlu v kontejneru uzlů. První rozhraní v kontejneru rozhraní odpovídá IP adrese prvního uzlu v kontejneru uzlů. Takže v prvním řádku kódu (výše) vytvoříme pomocníka a řekneme mu, že vzdálená adresa klienta bude IP adresa přiřazená hostiteli, kde se server nachází. Také říkáme, že musíme zařídit odesílání paketů na port devět.

Atribut „MaxPackets“ sděluje klientovi maximální počet paketů, které můžeme během simulace odeslat. Atribut "Interval" říká klientovi, jak dlouho bude čekat mezi pakety, a atribut "PacketSize" říká klientovi, jak velká by měla být užitečná zátěž paketu. Pomocí této kombinace atributů říkáme klientovi, aby poslal jeden 1024bajtový paket.

Stejně jako u echo serveru nastavujeme atributy echo klienta Home и Stop, ale zde klienta spustíme sekundu po zapnutí serveru (dvě sekundy po spuštění simulace).

4.2.8 Simulátor

V tomto okamžiku musíme spustit simulaci. To se provádí pomocí globální funkce Simulátor::Spustit.

Simulator::Run ();

Když jsme dříve nazývali metody,

serverApps.Start (Seconds (1.0));
serverApps.Stop (Seconds (10.0));
... 
clientApps.Start (Seconds (2.0));
clientApps.Stop (Seconds (10.0));

ve skutečnosti jsme naplánovali události v simulátoru na 1,0 sekundy, 2,0 sekundy a dvě události na 10,0 sekundy. Po hovoru Simulátor::Spustit, systém začne prohlížet seznam naplánovaných událostí a provádět je. Nejprve spustí událost po 1,0 sekundě, která spustí aplikaci serveru echo (tato událost může zase naplánovat mnoho dalších událostí). Poté spustí událost naplánovanou na t=2,0 sekundy, která spustí klientskou aplikaci echo. Tato událost může mít opět naplánovaných mnoho dalších akcí. Implementace události start v klientovi echo zahájí fázi přenosu dat simulace odesláním paketu na server.

Akt odeslání paketu na server spustí řetězec událostí, které budou automaticky naplánovány v zákulisí a které implementují mechaniku odesílání echo paketu podle parametrů časování, které jsme nastavili ve skriptu.

V důsledku toho, protože posíláme pouze jeden paket (pamatujte, atribut MaxPackets byla nastavena na jedna), řetězec událostí iniciovaných tímto jediným klientským pingem se ukončí a simulace přejde do pohotovostního režimu. Jakmile k tomu dojde, zbývající naplánované události budou události Stop pro server a klienta. Po provedení těchto událostí nezůstanou žádné události pro další zpracování a Simulátor::Spustit vrátí kontrolu. Simulace je dokončena.

Nezbývá než po sobě uklidit. To se provádí voláním globální funkce Simulátor::Destroy. Protože byly volány pomocné funkce (nebo nízkoúrovňový kód ns-3), které jsou organizovány tak, že do simulátoru byly vloženy háčky, které zničily všechny objekty, které byly vytvořeny. Žádný z těchto objektů jste nemuseli sami sledovat – stačilo zavolat Simulátor::Destroy a jít ven. Systém ns-3 tuto těžkou práci udělá za vás. Zbývající řádky našeho prvního skriptu ns-3, first.cc, dělají právě to:

Simulator::Destroy ();
return 0;
}

Kdy se simulátor zastaví?

ns-3 je simulátor diskrétních událostí (DE). V takovém simulátoru je každá událost spojena s dobou jejího provedení a simulace pokračuje zpracováním událostí v pořadí, v jakém nastávají, jak simulace postupuje. Události mohou způsobit naplánování budoucích událostí (například časovač se může přeplánovat, aby dokončil počítání v dalším intervalu).

Počáteční události jsou obvykle iniciovány entitou, například IPv6 naplánuje zjišťování služeb v síti, požadavky sousedů atd. Aplikace naplánuje první událost odeslání paketu a tak dále. Když je událost zpracována, může generovat nulu, jednu nebo více událostí. Jak simulace postupuje, dochází k událostem, které buď končí, nebo vytvářejí nové. Simulace se automaticky zastaví, pokud je fronta událostí prázdná nebo je detekována zvláštní událost Stop. událost Stop generované funkcí Simulátor::Stop (čas zastavení).

Existuje typický případ, kdy je Simulator::Stop absolutně nezbytný k zastavení simulace: když dojde k samoudržujícím se událostem. Samostatné (nebo opakující se) události jsou události, které jsou vždy přeplánovány. V důsledku toho vždy udržují frontu událostí neprázdnou. Existuje mnoho protokolů a modulů obsahujících opakující se události, například:

• FlowMonitor – pravidelná kontrola ztracených paketů;

• RIPng – periodické vysílání aktualizací směrovacích tabulek;

• atd.

V takových případech Simulátor::Stop nutné pro správné zastavení simulace. Navíc, když je ns-3 v emulačním režimu, RealtimeSimulator se používá k synchronizaci hodin simulace s hodinami stroje a Simulátor::Stop nutné k zastavení procesu.

Mnoho simulačních programů v učebnici nevolá Simulátor::Stop explicitně, protože se automaticky ukončí po vyčerpání událostí ve frontě. Tyto programy však také přijímají volání Simulator::Stop. Například následující dodatečný příkaz v prvním vzorovém programu by naplánoval explicitní zastavení na 11 sekund:

+ Simulator::Stop (Seconds (11.0));
  Simulator::Run ();
  Simulator::Destroy ();
  return 0;
}

Výše uvedené ve skutečnosti nezmění chování tohoto programu, protože tato konkrétní simulace přirozeně končí po 10 sekundách. Pokud byste však ve výše uvedeném příkazu změnili čas zastavení z 11 sekund na 1 sekundu, všimli byste si, že simulace se zastaví dříve, než jakýkoli výstup dopadne na obrazovku (protože výstup nastane po přibližně 2 sekundách času simulace).

Před voláním Simulator::Run je důležité zavolat Simulator::Stop; jinak Simulator::Run nemusí nikdy vrátit řízení do hlavního programu, aby provedl zastavení!

4.2.9 Vytvoření skriptu

Udělali jsme z vytváření vašich jednoduchých skriptů triviální. Jediné, co musíte udělat, je umístit skript do adresáře scratch a bude automaticky vytvořen, pokud jej spustíte Waf. Zkusme to. Vraťte se do adresáře nejvyšší úrovně a zkopírujte example/tutorial/first.cc do katalogu poškrábání

$ cd ../.. 
$ cp examples/tutorial/first.cc scratch/myfirst.cc

Nyní vytvořte svůj první ukázkový skript pomocí WAF:

$ ./waf

Měli byste vidět zprávy oznamující, že váš první příklad byl úspěšně vytvořen.

Waf: Entering directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
[614/708] cxx: scratch/myfirst.cc -> build/debug/scratch/myfirst_3.o
[706/708] cxx_link: build/debug/scratch/myfirst_3.o -> build/debug/scratch/myfirst
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' finished successfully (2.357s)

Nyní můžete spustit příklad (všimněte si, že pokud sestavujete svůj program v adresáři scratch, musíte jej spustit z poškrábání):

$ ./waf --run scratch/myfirst

Měli byste vidět podobný výstup:

Waf: Entering directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' finished successfully (0.418s) Sent 1024 bytes to 10.1.1.2
Received 1024 bytes from 10.1.1.1
Received 1024 bytes from 10.1.1.2

Zde vidíte, že systém sestavení ověří, zda byl soubor vytvořen, a poté jej spustí. Vidíte, že položka komponenty na klientovi echo znamená, že odeslal jeden 1024bajtový paket na server echo 10.1.1.2. Také vidíte komponentu protokolování na serveru echo a říká, že přijal 1024 bajtů z 10.1.1.1. Server echo paket tiše přehraje a v protokolu klienta echo můžete vidět, že přijal svůj paket zpět ze serveru.

4.3 ns-3 Zdrojový kód

Nyní, když jste použili některé z pomocníků ns-3, můžete se podívat na některé zdrojové kódy, které implementují tuto funkci. Nejnovější kód si můžete prohlédnout na našem webovém serveru pod následujícím odkazem: https://gitlab.com/nsnam/ns-3-dev.git. Zde uvidíte souhrnnou stránku Mercurial pro náš vývojový strom ns-3. V horní části stránky uvidíte několik odkazů,

summary | shortlog | changelog | graph | tags | files

Pokračujte a vyberte odkaz na soubory. Takto bude vypadat nejvyšší úroveň většiny našich úložišť:

drwxr-xr-x                               [up]
drwxr-xr-x                               bindings python  files
drwxr-xr-x                               doc              files
drwxr-xr-x                               examples         files
drwxr-xr-x                               ns3              files
drwxr-xr-x                               scratch          files
drwxr-xr-x                               src              files
drwxr-xr-x                               utils            files
-rw-r--r-- 2009-07-01 12:47 +0200 560    .hgignore        file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 1886   .hgtags          file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 1276   AUTHORS          file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 30961  CHANGES.html     file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 17987  LICENSE          file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 3742   README           file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 16171  RELEASE_NOTES    file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 6      VERSION          file | revisions | annotate
-rwxr-xr-x 2009-07-01 12:47 +0200 88110  waf              file | revisions | annotate
-rwxr-xr-x 2009-07-01 12:47 +0200 28     waf.bat          file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 35395  wscript          file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 7673   wutils.py        file | revisions | annotate

Naše ukázkové skripty jsou v adresáři Příklady. Pokud kliknete na příklady, zobrazí se seznam podadresářů. Jeden ze souborů v podadresáři tutoriál - první.cc. Pokud kliknete na první.cc uvidíte kód, který jste se právě naučili.

Zdrojový kód se nachází především v adresáři src. Zdrojový kód můžete zobrazit kliknutím na název adresáře nebo kliknutím na odkaz na soubory vpravo od názvu adresáře. Pokud kliknete na adresář src, zobrazí se seznam podadresářů src. Pokud poté kliknete na hlavní podadresář, najdete seznam souborů. První soubor, který uvidíte (v době psaní této příručky), je přerušit.h. Pokud kliknete na odkaz přerušit.h, budete přesměrováni do zdrojového souboru pro přerušit.h, který obsahuje užitečná makra pro ukončení skriptů, pokud jsou zjištěny abnormální podmínky. Zdrojový kód pomocníků, které jsme použili v této kapitole, naleznete v adresáři src/Applications/helper. Neváhejte se pohrabat ve stromu adresářů, abyste zjistili, co je kde, a porozuměli stylu programů ns-3.

Zdroj: www.habr.com

Přidat komentář