ns-3 netværkssimulator tutorial. Kapitel 4

ns-3 netværkssimulator tutorial. Kapitel 4
kapitel 1,2
kapitel 3

4 Konceptoversigt
4.1 Nøgleabstraktioner
4.1.1 Node
4.1.2 Anvendelse
4.1.3 Kanal
4.1.4 Net-enhed
4.1.5 Topologiske assistenter
4.2 Første ns-3 script
4.2.1 Boilerplate-kode
4.2.2 Plug-ins
4.2.3 ns3 navneområde
4.2.4 Logning
4.2.5 Hovedfunktion
4.2.6 Brug af topologiassistenter
4.2.7 Brug af applikation
4.2.8 Simulator
4.2.9 Opbygning af dit script
4.3 ns-3 Kildekode

Kapitel 4

Koncept oversigt

Det første, vi skal gøre, før vi begynder at lære eller skrive ns-3-kode, er at forklare nogle få grundlæggende begreber og abstraktioner i systemet. Meget af dette kan virke indlysende for nogle, men vi anbefaler, at du tager dig tid til at læse dette afsnit for at sikre, at du starter på et solidt grundlag.

4.1 Nøgleabstraktioner

I dette afsnit vil vi se på nogle udtryk, der er almindeligt brugt på nettet, men som har en specifik betydning i ns-3.

4.1.1 Node

I internetjargon kaldes en computerenhed, der forbinder til et netværk, en vært eller nogle gange et slutsystem. Fordi ns-3 er en netværkssimulator og ikke en internetsimulator, bruger vi bevidst ikke udtrykket vært, da dette er tæt forbundet med internettet og dets protokoller. I stedet bruger vi en mere generel term, også brugt af andre simulatorer, som stammer fra grafteorien: node (node).

I ns-3 kaldes den underliggende abstraktion af en computerenhed en node. Denne abstraktion er repræsenteret i C++ af Node-klassen. Klasse NodeNode (node) giver metoder til at manipulere repræsentationer af computerenheder i simuleringer.

Du skal forstå Node som en computer, som du tilføjer funktionalitet til. Du tilføjer ting som applikationer, protokolstakke og perifere kort med drivere, der gør det muligt for computeren at udføre nyttigt arbejde. Vi bruger samme grundmodel i ns-3.

4.1.2 Anvendelse

Generelt er computersoftware opdelt i to brede klasser. Systemsoftware organiserer forskellige computerressourcer såsom hukommelse, processorcyklusser, disk, netværk osv. i henhold til en eller anden computermodel. Systemsoftware bruger typisk ikke disse ressourcer til at udføre opgaver, som direkte gavner brugeren. En bruger kører typisk en applikation for at opnå et specifikt mål, som opnår og bruger ressourcer styret af systemsoftwaren.

Ofte trækkes adskillelsen mellem system- og applikationssoftware på privilegieniveauændringer, der forekommer i operativsystemfælder. ns-3 har ikke noget reelt koncept for et operativsystem og derfor intet koncept for privilegieniveauer eller systemkald. Vi har dog en idé til en app. Ligesom i den "virkelige verden" kører softwareapplikationer på computere for at udføre opgaver, kører ns-3 applikationer på ns-3 noder for at styre simuleringer i den simulerede verden.

I ns-3 er den grundlæggende abstraktion for et brugerprogram, der genererer aktivitet til modellering, en applikation. Denne abstraktion er repræsenteret i C++ af Application-klassen. Applikationsklassen giver metoder til at manipulere visninger af vores version af applikationer på brugerniveau i simuleringer. Udviklere forventes at specialisere Application-klassen i en objektorienteret programmeringsforstand for at skabe nye applikationer. I denne tutorial vil vi bruge specialiseringer af applikationsklassen kaldet UdpEchoClientApplication и UdpEchoServerApplication. Som du kunne forvente, udgør disse applikationer et sæt klient-/serverapplikationer, der bruges til at generere og ekko netværkspakker.

4.1.3 Kanal

I den virkelige verden kan du tilslutte en computer til et netværk. Ofte kaldes de medier, som data transmitteres over i disse netværk, kanaler. Når du tilslutter et Ethernet-kabel til en stikkontakt, forbinder du din computer til et Ethernet-link. I den simulerede ns-3 verden er en node forbundet med et objekt, der repræsenterer en kommunikationskanal. Her kaldes den grundlæggende abstraktion af kommunikationsundernetværket en kanal og er repræsenteret i C++ af Channel-klassen.

Klasse KanalKanal giver metoder til at styre interaktionen af ​​subnet-objekter og forbinde noder til dem. Kanaler kan også specialiseres af udviklere i en objektorienteret programmeringsforstand. Kanalspecialisering kan modellere noget så simpelt som en ledning. En dedikeret kanal kan også modellere komplekse ting som en stor Ethernet-switch eller et tredimensionelt rum fyldt med forhindringer i tilfælde af trådløse netværk.

Vi vil bruge specialiserede versioner af kanalen i denne tutorial kaldet CsmaChannelCsmaChannel, PointToPointChannelPointToPointChannel и WifiChannelWifiChannel. CsmaChannelmodellerer for eksempel en version af et kommunikationsundernet, der implementerer et kommunikationsmiljø med flere adgangsbærere. Dette giver os Ethernet-lignende funktionalitet.

4.1.4 Net-enhed

Det plejede at være sådan, at hvis man ville tilslutte en computer til et netværk, skulle man købe et specifikt netværkskabel og en hardwareenhed kaldet (i pc-terminologi) et perifert kort, der skulle installeres i computeren. Hvis et perifert kort implementerede nogle netværksfunktioner, blev de kaldt netværkskort eller netværkskort. I dag kommer de fleste computere med integreret netværksinterface hardware og ses ikke af brugerne som separate enheder.

Et netværkskort fungerer ikke uden en softwaredriver, der styrer dets hardware. I Unix (eller Linux) er et stykke perifert udstyr klassificeret som en enhed. Enheder administreres ved hjælp af enhedsdrivere, og netværksenheder (NIC'er) administreres ved hjælp af netværksenhedsdrivere (netværksenhedsdrivere) og kaldes under ét netværksenheder (net enheder). I Unix og Linux refererer du til netværksenheder med navne som f.eks eth0.

I ns-3 dækker netværksenhedsabstraktionen både softwaredriveren og den hardware, der modelleres. I simuleringen "installeres" en netværksenhed i en node for at give den mulighed for at kommunikere med andre noder gennem kanaler. Ligesom en rigtig computer kan en node forbindes til flere kanaler gennem flere enheder NetDevices.

Netværksabstraktionen af ​​en enhed er repræsenteret i C++ af klassen NetDevice. Klasse NetDevice giver metoder til styring af forbindelser til node- og kanalobjekter; og kan specialiseres af udviklere i betydningen objektorienteret programmering. I denne tutorial vil vi bruge flere specialiserede versioner af NetDevice kaldet CsmaNetDevice, PointToPointNetDevice и WifiNet-enhed. Ligesom en Ethernet-netværksadapter er designet til at fungere med et netværk Ethernet, CsmaNetDevice designet til at arbejde med CsmaChannel, PointToPointNetDevice designet til at arbejde med PointToPointChannelOg WifiNet-enhed - designet til at arbejde med WifiChannel.

4.1.5 Topologiske assistenter

I et rigtigt netværk finder du værtscomputere med tilføjet netværkskort (eller indbygget). I ns-3 vil vi sige, at du vil se noder med NetDevices tilknyttet. I et stort simuleret netværk bliver du nødt til at organisere forbindelser mellem mange objekter Node, NetDevice и Kanal.

Siden tilslutning af NetDevices til noder, NetDevices til links, tildeling af IP-adresser osv. i ns-3 er en fælles opgave, for at gøre dette så nemt som muligt leverer vi såkaldte topologihjælpere. For at oprette en NetDevice skal du for eksempel udføre mange ns-3-kerneoperationer, tilføje en MAC-adresse, installere netværksenheden i Node, konfigurere nodens protokolstak og derefter forbinde NetDevicen til kanalen. Der kræves endnu mere arbejde for at forbinde flere enheder til multipoint-links og derefter forbinde de enkelte netværk til et Internetworks-netværk. Vi leverer topologihjælpeobjekter, der kombinerer disse mange operationer til en letanvendelig model for din bekvemmelighed.

4.2 Første ns-3 script

Hvis du installerede systemet som foreslået ovenfor, vil du have ns-3-udgivelsen i en mappe kaldet repos i din hjemmemappe. Gå til biblioteket frigive

Hvis du ikke har sådan en mappe, betyder det, at du ikke specificerede output-mappen, da du byggede udgivelsesversionen af ​​ns-3, byg sådan:
$ ./waf configure —build-profile=release —out=build/release,
$ ./waf opbygning

der skulle du se en mappestruktur, der ligner følgende:

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

Gå til biblioteket eksempler/tutorial. Du bør se en fil, der ligger der, kaldet første.cc. Dette er et script, der vil skabe en simpel punkt-til-punkt-forbindelse mellem to noder og sende en pakke mellem noderne. Lad os se på dette script linje for linje; for at gøre dette skal du åbne first.cc i din foretrukne editor.

4.2.1 Boilerplate-kode
Den første linje i filen er editor mode linje emacs. Det fortæller emacs om formateringskonventionerne (kodningsstil), som vi bruger i vores kildekode.

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

Dette er altid et ret kontroversielt spørgsmål, så vi er nødt til at sætte rekorden lige for at få det af vejen med det samme. ns-3-projektet har, som de fleste store projekter, vedtaget en kodningsstil, som al indsendt kode skal overholde. Hvis du ønsker at bidrage med din kode til projektet, skal du til sidst overholde ns-3 kodningsstandarden, som beskrevet i filen doc/codingstd.txt eller vist på projektets hjemmeside: https://www.nsnam.org/develop/contributing-code/coding-style/.

Vi anbefaler, at du vænner dig til udseendet og følelsen af ​​ns-3-kode og anvender denne standard, når du arbejder med vores kode. Hele udviklingsteamet og bidragyderne gik med til dette efter noget brokken. Emacs-tilstandslinjen ovenfor gør det nemt at formatere korrekt, hvis du bruger emacs-editoren.

ns-3 simulatoren er licenseret vha GNU General Public License. Du vil se den passende GNU juridiske header i hver ns-3 distributionsfil. Ofte vil du se en ophavsretsmeddelelse for en af ​​de deltagende institutioner i ns-3-projektet over GPL-teksten og forfatteren, vist nedenfor.

/* 
* 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 Plug-ins

Selve koden begynder med en række inklusionsudsagn (omfatter).

#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"

For at hjælpe vores brugere af scripting på højt niveau med at klare det store antal header-filer, der findes i systemet, grupperer vi dem efter deres brug i store moduler. Vi leverer en enkelt header-fil, der rekursivt indlæser alle header-filer, der bruges i et givet modul. I stedet for at skulle søge efter præcis hvilken header du har brug for og muligvis få den korrekte liste over afhængigheder, giver vi dig muligheden for at downloade en gruppe filer i stor granularitet. Det er ikke den mest effektive tilgang, men det gør bestemt at skrive scripts meget nemmere.

Hver af ns-3 include-filerne placeres i en mappe med navn ns3 (build undermappe) for at undgå filnavnekonflikter under byggeprocessen. Fil ns3/kerne-modul.h svarer til ns-3 modulet, som du finder i mappen src/kerne i den udgivelse, du har installeret. I listen over denne mappe finder du et stort antal header-filer. Når du laver monteringen, Waf placerer de offentlige header-filer i ns3-mappen i en undermappe bygge/debug

Hvis du ikke har sådan en mappe, betyder det, at du ikke specificerede output-mappen, da du byggede udgivelsesversionen af ​​ns-3, byg sådan:
$ ./waf configure --build-profile=debug --out=build/debug
$ ./waf opbygning
eller
$ ./waf configure --build-profile=optimeret --out=build/optimeret
$ ./waf opbygning

eller bygge/optimeret, afhængigt af din konfiguration. Waf vil også automatisk generere en modul-inkluderingsfil for at indlæse alle offentlige header-filer. Da du selvfølgelig følger denne guide religiøst, har du allerede gjort det

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

at konfigurere projektet til at køre debug-builds, der inkluderer eksempler og tests. Det gjorde du også

$ ./waf

at samle projektet. Så nu når du kigger i mappen ../../build/debug/ns3, så finder du der blandt andet header-filerne for de fire moduler vist ovenfor. Du kan se på indholdet af disse filer og finde ud af, at de inkluderer alle de offentlige filer, der bruges af de tilsvarende moduler.

4.2.3 ns3 navneområde

Næste linje i manuskriptet første.cc er en navneområdedeklaration.

using namespace ns3;

ns-3 projektet er implementeret i et C++ navneområde kaldet ns3. Dette grupperer alle ns-3-relaterede erklæringer i et omfang uden for det globale navneområde, hvilket forhåbentlig vil hjælpe med integration med anden kode. Brug af C++-operatoren introducerer ns-3-navneområdet i det aktuelle (globale) deklarative område. Dette er en fancy måde at sige, at efter denne erklæring, behøver du ikke at skrive ns3::scope tilladelsesoperatøren før hele din ns-3 kode for at bruge den. Hvis du ikke er bekendt med navnerum, skal du henvise til næsten enhver C++-tutorial og sammenligne ns3-navnerummet ved hjælp af std-navnerummet og deklarationen using namespace std; i eksempler på at arbejde med output-operatøren cout og vandløb.

4.2.4 Logning

Den næste linje i scriptet er:

NS_LOG_COMPONENT_DEFINE ("FirstScriptExample");

Vi vil bruge denne erklæring som et praktisk sted at diskutere vores dokumentationssystem doxygen. Hvis du kigger på ns-3-projektets hjemmeside, finder du et Dokumentationslink i navigationslinjen. Hvis du klikker på dette link, kommer du til vores dokumentationsside. Der er et "Seneste udgivelse"-link, der fører dig til dokumentationen for den seneste stabile version af ns-3. Hvis du vælger linket "API Documentation", vil du blive ført til ns-3 API-dokumentationssiden.

I venstre side af siden finder du en grafisk fremstilling af dokumentationsstrukturen. Et godt sted at starte er Modules ns-3 "bogen" i ns-3 navigationstræet. Hvis du afslører Moduler, vil du se en liste over ns-3 moduler dokumentation. Som diskuteret ovenfor er konceptet med et modul her direkte relateret til filerne inkluderet i modulet ovenfor. ns-3 logningsundersystemet er diskuteret i afsnittet Brug af logningsmodulet, så vi vender tilbage til det senere i denne vejledning, men du kan lære om ovenstående udsagn ved at se på modulet Coreog derefter åbne bogen Fejlsøgningsværktøjerog derefter vælge siden Logning. Klik på Logning.

Du bør nu gennemgå dokumentationen doxygen til modul Logning. På listen over makroer øverst på siden vil du se en post for NS_LOG_COMPONENT_DEFINE. Før du klikker på linket, skal du sørge for at se på "Detaljeret beskrivelse" af registreringsmodulet for at forstå, hvordan det fungerer generelt. For at gøre dette kan du rulle ned eller vælge "Mere..." under diagrammet.

Når du har en generel idé om, hvad der foregår, skal du gå videre og se på dokumentationen for den specifikke NS_LOG_COMPONENT_DEFINE. Jeg vil ikke duplikere dokumentationen her, men for at opsummere erklærer denne linje en registreringskomponent kaldet FirstScriptEksempel, som giver dig mulighed for at aktivere eller deaktivere konsollogning af beskeder ved henvisning til et navn.

4.2.5 Hovedfunktion

I de følgende linjer i scriptet vil du se,

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

Dette er blot en erklæring om hovedfunktionen af ​​dit program (script). Som med ethvert C++-program skal du definere en hovedfunktion, denne udføres først. Der er ikke noget særligt her. Dit ns-3 script er kun et C++ program. Følgende linje indstiller tidsopløsningen til 1 nanosekund, som er standard:

Time::SetResolution (Time::NS);

Tidsopløsning, eller blot opløsning, er den mindste tidsværdi, der kan bruges (den mindste repræsentative forskel mellem to gange). Du kan ændre opløsningen nøjagtigt én gang. Mekanismen, der giver denne fleksibilitet, bruger hukommelse, så når opløsningen er udtrykkeligt indstillet, frigør vi hukommelsen og forhindrer yderligere opdateringer. (Hvis du ikke indstiller opløsningen eksplicit, vil den som standard være et nanosekund, og hukommelsen frigøres, når simuleringen starter.)

De følgende to scriptlinjer bruges til at aktivere to logningskomponenter, der er indbygget i applikationer EchoClient и EchoServer:

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

Hvis du læser dokumentationen for Logning-komponenten, vil du se, at der er flere niveauer af logning/granularitet, som du kan aktivere på hver komponent. Disse to linjer kode muliggør debug-logning til INFO-niveauet for ekko-klienter og -servere. På dette niveau vil applikationen udskrive beskeder, mens den sender og modtager pakker under simulering.

Nu går vi i gang med at skabe topologien og køre simuleringen. Vi bruger topologihjælpeobjekter for at gøre dette job så nemt som muligt.

4.2.6 Brug af topologiassistenter

De næste to linjer kode i vores script vil faktisk skabe Node ns-3-objekterne, der repræsenterer computerne i simuleringen.

NodeContainer nodes;
nodes.Create (2);

Inden vi fortsætter, lad os finde dokumentationen til klassen NodeContainer. En anden måde at komme til dokumentationen for en given klasse på er gennem fanen Klasser på siderne doxygen. Hvis du allerede har Doxygen åben, skal du blot scrolle op til toppen af ​​siden og vælge fanen Klasser. Du bør se et nyt sæt faner, hvoraf den ene er en liste over klasser. Under denne fane vil du se en liste over alle ns-3 klasser. Rul ned til ns3::NodeContainer. Når du finder en klasse, skal du vælge den for at gå til dokumentationen for klassen.

Som vi husker, er en af ​​vores vigtigste abstraktioner noden. Det repræsenterer den computer, som vi vil tilføje ting som protokolstakke, applikationer og perifere kort. Topologi assistent NodeContainer giver en bekvem måde at oprette, administrere og få adgang til alle objekter Node, som vi laver for at køre simuleringen. Den første linje ovenfor erklærer simpelthen NodeContainer, som vi kalder noder. Den anden linje kalder Create-metoden på nodes-objektet og beder containeren om at oprette to noder. Som beskrevet i doxygen, anmoder containeren ns-3-systemet om at oprette to objekter Node og gemmer pointere til disse objekter internt.

Noderne oprettet i scriptet gør intet endnu. Det næste trin i opbygningen af ​​topologien er at forbinde vores noder til netværket. Den enkleste form for netværk, som vi understøtter, er en punkt-til-punkt-forbindelse mellem to noder. Vi vil nu skabe en sådan forbindelse.

PointToPointHelper

Vi opretter en punkt-til-punkt-forbindelse ved hjælp af et velkendt mønster, ved hjælp af et topologihjælpeobjekt til at udføre det arbejde på lavt niveau, der kræves til forbindelsen. Husk, at vores to vigtigste abstraktioner NetDevice и Kanal. I den virkelige verden svarer disse udtryk nogenlunde til perifere kort og netværkskabler. Typisk er disse to ting tæt forbundet med hinanden, og ingen kan regne med at dele for eksempel enheder Ethernet over en trådløs kanal. Vores topologihjælpere følger dette tætte forhold, og derfor vil du bruge et enkelt objekt i dette scenarie PointToPointHelper til opsætning og tilslutning af ns-3 objekter PointToPointNetDevice и PointToPointChannel. De næste tre linjer i scriptet:

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

Første linje,

PointToPointHelper pointToPoint;

opretter en forekomst af et objekt på stakken PointToPointHelper. Fra et topniveau synspunkt følgende linje,

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

fortæller objektet PointToPointHelper brug værdien "5 Mbit/s" (fem megabit pr. sekund) som "Datahastighed'.

Fra et mere specifikt synspunkt svarer strengen "DataRate" til det, vi kalder en attribut PointToPointNetDevice. Hvis man ser på doxygen for klasse ns3::PointToPointNetDevice og i dokumentationen for metoden GetTypeId du vil finde en liste over attributter, der er defineret for enheden. Blandt dem vil være attributten "Datahastighed" De fleste brugersynlige ns-3-objekter har lignende lister over attributter. Vi bruger denne mekanisme til nemt at opsætte simuleringen uden rekompilering, som du vil se i næste afsnit.

Svarende til "Datahastighed" i PointToPointNetDevice, vil du finde "Delay"-attributten forbundet med PointToPointChannel. Den sidste linje

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

Han taler PointToPointHelper brug værdien "2 ms" (to millisekunder) som udbredelsesforsinkelsesværdien for det punkt-til-punkt-link, det efterfølgende opretter.

NetDeviceContainer

I øjeblikket har vi i manuskriptet NodeContainer, som indeholder to noder. Vi har PointToPointHelper, som er forberedt til at skabe objekter PointToPointNetDevices og forbinde dem ved hjælp af et PointToPointChannel-objekt. Ligesom vi brugte NodeContainer topologihjælperobjektet til at oprette noder, vil vi spørge PointToPointHelper udføre arbejde for os i forbindelse med oprettelse, konfiguration og installation af vores enheder. Vi har brug for en liste over alle oprettede objekter NetDevice, så vi bruger NetDeviceContainer at opbevare dem på samme måde, som vi brugte NodeContainer at gemme de noder, vi har oprettet. De næste to linjer kode,

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

komplet enhed og kanalopsætning. Den første linje erklærer enhedsbeholderen nævnt ovenfor, og den anden gør hovedarbejdet. Metode Installer et objekt PointToPointHelper tager NodeContainer som en parameter. Inde NetDeviceContainer for hver node placeret i NodeContainer er oprettet (for punkt-til-punkt kommunikation skal der være præcis to af dem) PointToPointNetDevice oprettes og gemmes i enhedsbeholderen. PointToPointChannel er oprettet og to er knyttet til det PointToPointNetDevices. Efter oprettelse af objekter gemmes attributterne i PointToPointHelper, bruges til at initialisere de tilsvarende attributter i de oprettede objekter.

Efter at have foretaget et opkald pointToPoint.Install (noder) vi vil have to noder, hver med en punkt-til-punkt netværksenhed installeret og en punkt-til-punkt-forbindelse mellem dem. Begge enheder vil blive konfigureret til at transmittere data med en hastighed på fem megabit pr. sekund med en transmissionsforsinkelse på to millisekunder over kanalen.

InternetStackHelper

Vi har nu noder og enheder konfigureret, men vores noder har ikke protokolstakke installeret. De næste to linjer kode vil tage sig af dette.

InternetStackHelper stack;
stack.Install (nodes);

InternetStackHelper - er en topologihjælper til internetstakke, svarende til PointToPointHelper til punkt-til-punkt netværksenheder. Metode Installer tager NodeContainer som en parameter. Når den udføres, installerer den internetstakken (TCP, UDP, IP osv.) på hver containernode.

IPv4 AddressHelper

Så skal vi forbinde vores enheder med IP-adresser. Vi leverer en topologiassistent til at administrere IP-adressetildeling. Den eneste API, der er synlig for brugeren, er at indstille den grundlæggende IP-adresse og netmaske, der skal bruges, når den faktiske adressefordeling udføres (dette gøres på et lavere niveau i hjælperen). De næste to linjer kode i vores eksempelscript første.cc,

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

deklarer adressehjælperobjektet og fortæl det, at det skal begynde at allokere IP-adresser fra netværk 10.1.1.0 ved at bruge bitmasken 255.255.255.0 til at bestemme. Som standard vil tildelte adresser starte med én og stige monotont, så den første adresse, der tildeles fra denne base, vil være 10.1.1.1, derefter 10.1.1.2 osv. I virkeligheden, på et lavt niveau, husker ns-3-systemet alle tildelte IP-adresser og genererer en fatal fejl, hvis du ved et uheld skaber en situation, hvor den samme adresse genereres to gange (denne fejl er i øvrigt svær at fejlfinde).

Følgende kodelinje,

Ipv4InterfaceContainer interfaces = address.Assign (devices);

udfører selve adressetildelingen. I ns-3 etablerer vi en forbindelse mellem en IP-adresse og en enhed ved hjælp af objektet IPv4-grænseflade. Ligesom vi nogle gange har brug for en liste over netværksenheder oprettet af assistenten til senere brug, har vi nogle gange brug for en liste over objekter IPv4-grænseflade. IPv4 InterfaceContainer giver denne funktionalitet.

Vi byggede et punkt-til-punkt-netværk med stakke installeret og tildelt IP-adresser. Nu har vi brug for applikationer i hver node til at generere trafik.

4.2.7 Brug af applikation

En anden af ​​de vigtigste abstraktioner af ns-3 systemet er Anvendelse (Ansøgning). I dette scenarie bruger vi to basisklassespecialiseringer Anvendelse ns-3 kaldet UdpEchoServerApplication и UdpEchoClientApplication. Som i tidligere tilfælde bruger vi hjælpeobjekter til at konfigurere og administrere basisobjekterne. Her bruger vi UdpEchoServerHelper и UdpEchoClientHelper objekter for at gøre vores liv lettere.

UdpEchoServerHelper

Følgende kodelinjer i vores first.cc-eksempelscript bruges til at konfigurere en UDP-ekkoserverapplikation på en af ​​de noder, vi oprettede tidligere.

UdpEchoServerHelper echoServer (9);

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

Den første kodelinje i ovenstående kodestykke opretter UdpEchoServerHelper. Som sædvanligt er dette ikke en applikation i sig selv, det er et objekt, der hjælper os med at skabe rigtige applikationer. En af vores konventioner er at videregive de nødvendige attributter til konstruktøren af ​​hjælpeobjektet. I dette tilfælde kan hjælperen ikke gøre noget nyttigt, medmindre den får det portnummer, som serveren vil lytte efter pakker på, dette nummer skal også være kendt af klienten. I dette tilfælde videregiver vi portnummeret til hjælpekonstruktøren. Det gør konstruktøren til gengæld ganske enkelt SetAttribute med den beståede værdi. Senere, hvis det ønskes, kan du bruge SetAttribute til at indstille en anden værdi for Port-attributten.

Som mange andre hjælpeobjekter er objektet UdpEchoServerHelper har en metode Installer. Udførelse af denne metode skaber effektivt en grundlæggende ekkoserverapplikation og binder den til værten. Interessant nok metoden Installer tager NodeContainer som parameter ligesom de andre Installer metoder vi har set.

Den C++ implicitte konvertering, der arbejder her, tager resultatet af metoden node.Get(1) (som returnerer en smart pointer til nodeobjektet - Ptr ) og bruger det i konstruktøren til det anonyme objekt NodeContainersom derefter videregives til metoden Installer. Hvis du ikke kan bestemme i C++-kode, hvilken metodesignatur der er kompileret og udført, så kig blandt de implicitte konverteringer.

Nu ser vi det echoServer.Install om at installere applikationen UdpEchoServerApplication på fundet i NodeContainersom vi bruger til at styre vores noder, node med indeks 1. Metode Installer returnerer en beholder, der indeholder pointere til alle applikationer (i dette tilfælde en, da vi har bestået en anonym NodeContainer, der indeholder én node) oprettet af hjælperen.

Applikationer skal angive, hvornår de skal begynde at generere trafik "Start" og skal muligvis desuden angive et tidspunkt, hvor det skal stoppes "hold op". Vi tilbyder begge muligheder. Disse tider er fastsat ved hjælp af metoderne Applikationsbeholder Starten и Stands. Disse metoder accepterer typeparametre Tid. I dette tilfælde bruger vi en eksplicit sekvens af C++-konverteringer til at tage C++ fordoble 1.0 og konverter det til et tns-3 Time-objekt, der bruger Seconds-objektet til at konvertere til sekunder. Husk at konverteringsreglerne kan styres af modelforfatteren, og C++ har sine egne regler, så du kan ikke altid regne med at parametrene bliver konverteret som du havde forventet. To linjer

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

vil få ekkoserverapplikationen til at starte (tænde automatisk) et sekund efter simuleringen starter og stoppe (slukke) efter ti sekunder af simuleringen. På grund af det faktum, at vi har erklæret en simuleringshændelse (applikationsstophændelse), som vil blive udført om ti sekunder, vil mindst ti sekunders netværksdrift blive simuleret.

UdpEchoClientHelper

Klientapplikation ekko konfigureret på en måde, der næsten ligner serveren. Der er et basisobjekt UdpEchoClientApplication, som administreres
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));;

Til echo-klienten skal vi dog indstille fem forskellige attributter. De første to attributter indstilles på oprettelsestidspunktet UdpEchoClientHelper. Vi sender parametre, der bruges (inde i hjælperen) til at indstille attributterne "Fjernadresse" и "RemotePort" i overensstemmelse med vores aftale om at videregive de nødvendige parametre til hjælpekonstruktøren.

Lad os huske, at vi brugte IPv4 InterfaceContainer at spore de IP-adresser, vi har tildelt vores enheder. Null-grænsefladen i grænsefladebeholderen vil svare til IP-adressen på nulknuden i nodebeholderen. Den første grænseflade i grænsefladebeholderen svarer til IP-adressen på den første node i nodebeholderen. Så i den første kodelinje (ovenfor) opretter vi en hjælper og fortæller den, at klientens fjernadresse vil være den IP-adresse, der er tildelt værten, hvor serveren er placeret. Vi siger også, at vi skal sørge for, at pakker sendes til port ni.

"MaxPackets"-attributten fortæller klienten det maksimale antal pakker, vi kan sende under simuleringen. "Interval"-attributten fortæller klienten, hvor længe den skal vente mellem pakker, og "PacketSize"-attributten fortæller klienten, hvor stor pakkens nyttelast skal være. Med denne attributkombination fortæller vi klienten at sende en enkelt 1024-byte pakke.

Som med ekkoserveren indstiller vi attributterne for ekkoklienten Starten и Stands, men her starter vi klienten et sekund efter serveren er tændt (to sekunder efter starten af ​​simuleringen).

4.2.8 Simulator

På dette tidspunkt skal vi køre simuleringen. Dette gøres ved hjælp af den globale funktion Simulator::Kør.

Simulator::Run ();

Da vi kaldte metoderne tidligere,

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

vi planlagde faktisk begivenheder i simulatoren på 1,0 sekunder, 2,0 sekunder og to begivenheder på 10,0 sekunder. Efter opkaldet Simulator::Kør, vil systemet begynde at se listen over planlagte hændelser og udføre dem. Den udløser først en hændelse efter 1,0 sekunder, hvilket vil udløse ekkoserverapplikationen (denne hændelse kan igen planlægge mange andre hændelser). Det vil derefter udløse en hændelse, der er planlagt til t=2,0 sekunder, som vil starte echo-klientapplikationen. Igen, denne begivenhed kan have mange flere begivenheder planlagt. Implementeringen af ​​starthændelse i ekkoklienten vil begynde simuleringens dataoverførselsfase ved at sende en pakke til serveren.

Handlingen med at sende en pakke til serveren vil udløse en kæde af begivenheder, der automatisk vil blive planlagt bag kulisserne, og som vil implementere mekanikken ved at sende en ekkopakke i henhold til de timingparametre, vi har sat i scriptet.

Som et resultat, da vi kun sender én pakke (husk attributten MaxPackets blev indstillet til én), vil kæden af ​​hændelser, der blev initieret af denne enkelte klient-ping, afsluttes, og simuleringen går i standbytilstand. Når dette sker, vil de resterende planlagte begivenheder være begivenhederne Stands til server og klient. Når disse hændelser udføres, vil der ikke være nogen hændelser tilbage til videre behandling og Simulator::Kør vil returnere kontrollen. Simuleringen er færdig.

Tilbage er kun at rydde op efter dig selv. Dette gøres ved at kalde den globale funktion Simulator::Ødelæg. Fordi hjælpefunktionerne (eller low-level ns-3-koden) blev kaldt, som er organiseret således, at kroge blev indsat i simulatoren for at ødelægge alle objekter, der blev skabt. Du behøvede ikke selv at spore nogen af ​​disse objekter - alt du skulle gøre var at ringe Simulator::Ødelæg og gå ud. ns-3-systemet vil gøre dette hårde arbejde for dig. De resterende linjer i vores første ns-3 script, first.cc, gør netop det:

Simulator::Destroy ();
return 0;
}

Hvornår stopper simulatoren?

ns-3 er en diskret hændelse (DE) simulator. I en sådan simulator er hver hændelse forbundet med dens eksekveringstid, og simuleringen fortsætter med at behandle hændelser i den rækkefølge, de opstår, efterhånden som simuleringen skrider frem. Hændelser kan få fremtidige hændelser til at blive planlagt (for eksempel kan en timer omplanlægge sig selv til at afslutte optællingen i det næste interval).

Indledende begivenheder initieres normalt af enheden, for eksempel vil IPv6 planlægge opdagelsen af ​​tjenester på netværket, naboanmodninger osv. Applikationen planlægger den første pakkeafsendelsesbegivenhed og så videre. Når en hændelse behandles, kan den generere nul, én eller flere hændelser. Efterhånden som simuleringen skrider frem, sker der begivenheder, som enten slutter eller skaber nye. Simuleringen stopper automatisk, hvis hændelseskøen er tom, eller en særlig hændelse detekteres Stands. Begivenhed Stands genereret af funktionen Simulator::Stop (stoptid).

Der er et typisk tilfælde, hvor Simulator::Stop er absolut nødvendigt for at stoppe simuleringen: når der er selvopretholdende begivenheder. Selvbærende (eller gentagne) begivenheder er begivenheder, der altid bliver omlagt. Som følge heraf holder de altid begivenhedskøen ikke tom. Der er mange protokoller og moduler, der indeholder gentagne begivenheder, for eksempel:

• FlowMonitor - periodisk kontrol for tabte pakker;

• RIPng – periodisk udsendelse af opdateringer af rutetabeller;

• etc.

I sådanne tilfælde Simulator::Stop nødvendigt for at stoppe simuleringen korrekt. Derudover, når ns-3 er i emuleringstilstand, bruges RealtimeSimulator til at synkronisere simuleringsuret med maskinens ur, og Simulator::Stop nødvendigt for at stoppe processen.

Mange af simuleringsprogrammerne i lærebogen kalder ikke Simulator::Stop eksplicit, da de afsluttes automatisk, når de kølige begivenheder er opbrugt. Disse programmer vil dog også acceptere Simulator::Stop-opkaldet. For eksempel vil følgende yderligere sætning i det første programeksempel planlægge et eksplicit stop ved 11 sekunder:

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

Ovenstående vil faktisk ikke ændre dette programs opførsel, da netop denne simulering slutter naturligt efter 10 sekunder. Men hvis du skulle ændre stoptiden i ovenstående udsagn fra 11 sekunder til 1 sekund, vil du bemærke, at simuleringen stopper, før et output rammer skærmen (da outputtet sker efter ca. 2 sekunders simuleringstid).

Det er vigtigt at kalde Simulator::Stop før du kalder Simulator::Run; ellers vil Simulator::Run muligvis aldrig returnere kontrol til hovedprogrammet for at udføre stoppet!

4.2.9 Opbygning af dit script

Vi har gjort det trivielt at lave dine enkle scripts. Alt du skal gøre er at lægge dit script i scratch-mappen, og det bliver automatisk bygget, hvis du kører Waf. Lad os prøve. Gå tilbage til biblioteket på øverste niveau og kopier eksempler/tutorial/first.cc til kataloget ridse

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

Byg nu dit første eksempelscript ved hjælp af WAF:

$ ./waf

Du bør se meddelelser, der indikerer, at dit første eksempel blev oprettet.

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)

Nu kan du køre eksemplet (bemærk at hvis du bygger dit program i scratch-mappen, så skal du køre det fra ridse):

$ ./waf --run scratch/myfirst

Du bør se lignende output:

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

Her kan du se, at build-systemet verificerer, at filen er bygget og derefter kører den. Du ser, at komponentindgangen på echo-klienten indikerer, at den sendte en enkelt 1024-byte-pakke til echo-server 10.1.1.2. Du ser også logningskomponenten på ekkoserveren for at sige, at den modtog 1024 bytes fra 10.1.1.1. Ekkoserveren afspiller lydløst pakken, og du kan se i ekkoklientens log, at den modtog sin pakke tilbage fra serveren.

4.3 ns-3 Kildekode

Nu hvor du har brugt nogle af ns-3 hjælperne, kan du tage et kig på noget af kildekoden, der implementerer denne funktionalitet. Den seneste kode kan ses på vores webserver på følgende link: https://gitlab.com/nsnam/ns-3-dev.git. Der vil du se Mercurial-oversigtssiden for vores ns-3 udviklingstræ. Øverst på siden vil du se flere links,

summary | shortlog | changelog | graph | tags | files

Gå videre og vælg fillinket. Sådan vil det øverste niveau i de fleste af vores depoter se ud:

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

Vores eksempelscripts er i mappen eksempler. Hvis du klikker på eksemplerne, vil du se en liste over undermapper. En af filerne i undermappen tutorial - first.cc. Hvis du klikker på første.cc du vil se den kode, du lige har lært.

Kildekoden er hovedsageligt placeret i mappen src. Du kan se kildekoden ved at klikke på mappenavnet eller klikke på fillinket til højre for mappenavnet. Hvis du klikker på src-biblioteket, får du en liste over src-undermapper. Hvis du derefter klikker på kerneunderbiblioteket, vil du finde en liste over filer. Den første fil, du vil se (på tidspunktet for skrivning af denne vejledning), er abort.h. Hvis du klikker på linket abort.h, vil du blive sendt til kildefilen for abort.h, som indeholder nyttige makroer til at afslutte scripts, hvis der opdages unormale forhold. Kildekoden til de hjælpere, vi brugte i dette kapitel, kan findes i mappen src/Applications/helper. Du er velkommen til at søge rundt i mappetræet for at finde ud af, hvad der er hvor, og stilen på ns-3-programmer.

Kilde: www.habr.com

Tilføj en kommentar