Vadnica simulatorja omrežja ns-3. 4. poglavje

Vadnica simulatorja omrežja ns-3. 4. poglavje
poglavje 1,2
poglavje 3

4 Pregled koncepta
4.1 Ključne abstrakcije
4.1.1 Vozlišče
4.1.2 Uporaba
4.1.3 Kanal
4.1.4 Omrežna naprava
4.1.5 Topološki pomočniki
4.2 Prvi skript ns-3
4.2.1 Standardna koda
4.2.2 Vtičniki
4.2.3 imenski prostor ns3
4.2.4 Beleženje
4.2.5 Glavna funkcija
4.2.6 Uporaba topoloških pomočnikov
4.2.7 Uporaba aplikacije
4.2.8 Simulator
4.2.9 Gradnja vašega skripta
4.3 ns-3 Izvorna koda

Poglavje 4

Pregled koncepta

Prva stvar, ki jo moramo narediti, preden se začnemo učiti ali pisati kodo ns-3, je razložiti nekaj osnovnih konceptov in abstrakcij v sistemu. Marsikaj od tega se morda komu zdi očitno, vendar priporočamo, da si vzamete čas in preberete ta razdelek, da se prepričate, da začenjate na trdnih temeljih.

4.1 Ključne abstrakcije

V tem razdelku si bomo ogledali nekaj izrazov, ki se običajno uporabljajo v spletu, vendar imajo poseben pomen v ns-3.

4.1.1 Vozlišče

V internetnem žargonu se računalniška naprava, ki se poveže z omrežjem, imenuje gostitelj ali včasih končni sistem. Ker je ns-3 simulator omrežja in ne simulator interneta, namenoma ne uporabljamo izraza gostitelj, saj je ta tesno povezan z internetom in njegovimi protokoli. Namesto tega uporabljamo bolj splošen izraz, ki ga uporabljajo tudi drugi simulatorji in izvira iz teorije grafov: vozlišče (Vozel).

V ns-3 se osnovna abstrakcija računalniške naprave imenuje vozlišče. To abstrakcijo v C++ predstavlja razred Node. Razred NodeNode (vozlišče) zagotavlja metode za manipulacijo predstavitev računalniških naprav v simulacijah.

Morate razumeti Node kot računalnik, ki mu dodaš funkcionalnost. Dodali boste stvari, kot so aplikacije, skladi protokolov in periferne kartice z gonilniki, ki računalniku omogočajo koristno delo. Isti osnovni model uporabljamo v ns-3.

4.1.2 Uporaba

Na splošno je računalniška programska oprema razdeljena na dva široka razreda. Sistemska programska oprema organizira različne računalniške vire, kot so pomnilnik, procesorski cikli, disk, omrežje itd., glede na neki računalniški model. Sistemska programska oprema običajno ne uporablja teh virov za izvajanje nalog, ki neposredno koristijo uporabniku. Uporabnik običajno zažene aplikacijo za dosego določenega cilja, ki pridobi in uporablja vire, ki jih nadzoruje sistemska programska oprema.

Pogosto se ločnica med sistemsko in aplikacijsko programsko opremo nariše pri spremembah ravni privilegijev, ki se pojavijo v pasteh operacijskega sistema. ns-3 nima pravega koncepta operacijskega sistema in zato tudi ne koncepta ravni privilegijev ali sistemskih klicev. Imamo pa idejo za aplikacijo. Tako kot se programske aplikacije v »resničnem svetu« izvajajo na računalnikih za izvajanje nalog, se aplikacije ns-3 izvajajo na vozliščih ns-3 za nadzor simulacij v simuliranem svetu.

V ns-3 je osnovna abstrakcija za uporabniški program, ki generira neko dejavnost za modeliranje, aplikacija. To abstrakcijo v C++ predstavlja razred Application. Razred aplikacije ponuja metode za manipulacijo pogledov naše različice aplikacij na ravni uporabnika v simulacijah. Od razvijalcev se pričakuje, da bodo specializirali razred aplikacij v smislu objektno usmerjenega programiranja za ustvarjanje novih aplikacij. V tej vadnici bomo uporabili specializacije razreda aplikacije, imenovane UdpEchoClientApplication и UdpEchoServerApplication. Kot lahko pričakujete, te aplikacije sestavljajo nabor aplikacij odjemalec/strežnik, ki se uporabljajo za ustvarjanje in odmev omrežnih paketov.

4.1.3 Kanal

V resničnem svetu lahko računalnik povežete z omrežjem. Mediji, po katerih se prenašajo podatki v teh omrežjih, se pogosto imenujejo kanali. Ko priključite ethernetni kabel v stensko vtičnico, povežete svoj računalnik z ethernetno povezavo. V simuliranem svetu ns-3 je vozlišče povezano z objektom, ki predstavlja komunikacijski kanal. Tu se osnovna abstrakcija komunikacijskega podomrežja imenuje kanal in je v C++ predstavljena z razredom Channel.

Razred ChannelChannel ponuja metode za upravljanje interakcije objektov podomrežja in povezovanje gostiteljev z njimi. Kanale lahko razvijalci specializirajo tudi v smislu objektno usmerjenega programiranja. Specializacija kanala lahko oblikuje nekaj tako preprostega, kot je žica. Namenski kanal lahko modelira tudi kompleksne stvari, kot je veliko ethernet stikalo ali tridimenzionalni prostor, poln ovir v primeru brezžičnih omrežij.

V tej vadnici bomo uporabljali specializirane različice kanala, imenovane CsmaChannelCsmaChannel, PointToPointChannelPointToPointChannel и WifiChannelWifiChannel. CsmaChannel, na primer, modelira različico komunikacijskega podomrežja, ki izvaja komunikacijsko okolje z večkratnim dostopom z zaznavanjem nosilca. To nam daje funkcionalnost, podobno ethernetu.

4.1.4 Omrežna naprava

Včasih je veljalo, da ste morali, če ste želeli povezati računalnik v omrežje, kupiti poseben omrežni kabel in strojno napravo, imenovano (v terminologiji osebnega računalnika) periferna kartica, ki jo je bilo treba namestiti v računalnik. Če je periferna kartica izvajala nekatere omrežne funkcije, so jih imenovali omrežne vmesniške kartice ali omrežne kartice. Danes ima večina računalnikov vgrajeno strojno opremo omrežnega vmesnika in jih uporabniki ne vidijo kot ločene naprave.

Omrežna kartica ne bo delovala brez programskega gonilnika, ki nadzoruje njeno strojno opremo. V Unixu (ali Linuxu) je kos periferne opreme razvrščen kot naprava. Naprave se upravljajo z gonilniki naprav, omrežne naprave (NIC) pa se upravljajo z gonilniki omrežnih naprav (gonilniki omrežnih naprav) in se skupaj imenujejo omrežne naprave (net naprave). V Unixu in Linuxu omrežne naprave imenujete z imeni, kot je npr eth0.

V ns-3 abstrakcija omrežne naprave zajema gonilnik programske opreme in strojno opremo, ki se modelira. V simulaciji je omrežna naprava "nameščena" v vozlišču, da ji omogoči komunikacijo z drugimi vozlišči prek kanalov. Tako kot pravi računalnik je lahko vozlišče povezano z več kanali prek več naprav NetDevices.

Omrežna abstrakcija naprave je v C++ predstavljena z razredom NetDevice. Razred NetDevice nudi metode za upravljanje povezav z objekti Node in Channel; razvijalci pa ga lahko specializirajo v smislu objektno usmerjenega programiranja. V tej vadnici bomo uporabili več specializiranih različic NetDevice, imenovanih CsmaNetDevice, PointToPointNetDevice и WifiNetDevice. Tako kot je omrežni vmesnik Ethernet zasnovan za delo z omrežjem Ethernet, CsmaNetDevice zasnovan za delo z CsmaChannel, PointToPointNetDevice zasnovan za delo z PointToPointChannelIn WifiNetDevice - zasnovan za delo z WifiChannel.

4.1.5 Topološki pomočniki

V pravem omrežju boste našli gostiteljske računalnike z dodanimi (ali vgrajenimi) omrežnimi karticami. V ns-3 bi rekli, da boste videli vozlišča s priključenimi napravami NetDevices. V velikem simuliranem omrežju boste morali organizirati povezave med številnimi objekti Node, NetDevice и Channel.

Od povezovanja NetDevices z vozlišči, NetDevices s povezavami, dodeljevanjem naslovov IP itd. v ns-3 so pogosta naloga, da bi bilo to čim bolj enostavno, nudimo tako imenovane topološke pomočnike. Če želite na primer ustvariti NetDevice, morate izvesti številne operacije jedra ns-3, dodati naslov MAC, namestiti omrežno napravo v Node, konfigurirati sklad protokolov vozlišča in nato NetDevice povezati s kanalom. Še več dela bo potrebno za povezovanje več naprav v večtočkovne povezave in nato povezovanje posameznih omrežij v omrežje Internetworks. Nudimo objekte za pomoč pri topologiji, ki združujejo te številne operacije v model, enostaven za uporabo, za vaše udobje.

4.2 Prvi skript ns-3

Če ste sistem namestili, kot je predlagano zgoraj, boste imeli izdajo ns-3 v imeniku, imenovanem repos, v domačem imeniku. Pojdi v imenik sprostitev

Če nimate takega imenika, to pomeni, da niste navedli izhodnega imenika pri izdelavi različice izdaje ns-3, sestavite takole:
$ ./waf configure —build-profile=release —out=build/release,
$ ./waf build

tam bi morali videti strukturo imenika, podobno naslednji:

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

Pojdi v imenik primeri/vadnice. Morali bi videti datoteko, ki se tam nahaja najprej.cc. To je skript, ki bo ustvaril preprosto povezavo od točke do točke med dvema vozliščema in posredoval en paket med vozlišči. Oglejmo si ta skript vrstico za vrstico; za to odprite first.cc v svojem najljubšem urejevalniku.

4.2.1 Standardna koda
Prva vrstica v datoteki je vrstica načina urejevalnika emacs. Emacsu pove o konvencijah oblikovanja (slog kodiranja), ki jih uporabljamo v izvorni kodi.

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

To je vedno precej kontroverzno vprašanje, zato moramo postaviti rekord, da ga takoj odstranimo s poti. Projekt ns-3 je tako kot večina velikih projektov sprejel slog kodiranja, ki mu mora ustrezati vsa prispevana koda. Če želite k projektu prispevati svojo kodo, se boste sčasoma morali uskladiti s standardom kodiranja ns-3, kot je opisano v datoteki doc/codingstd.txt ali prikazano na spletni strani projekta: https://www.nsnam.org/develop/contributing-code/coding-style/.

Priporočamo, da se navadite na videz in občutek kode ns-3 in uporabite ta standard vedno, ko delate z našo kodo. Celotna razvojna ekipa in sodelavci so se s tem strinjali po nekaj godrnjanja. Zgornja vrstica načina emacs olajša pravilno formatiranje, če uporabljate urejevalnik emacs.

Simulator ns-3 je licenciran z uporabo GNU General Public License. V vsaki distribucijski datoteki ns-3 boste videli ustrezno pravno glavo GNU. Pogosto boste nad besedilom GPL in avtorjem videli obvestilo o avtorskih pravicah za eno od sodelujočih ustanov v projektu ns-3, prikazano spodaj.

/* 
* 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 Vtičniki

Sama koda se začne z nizom stavkov o vključitvi (vključujejo).

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

Da bi našim uporabnikom skriptov na visoki ravni pomagali pri obvladovanju velikega števila datotek glave, ki so prisotne v sistemu, jih združujemo glede na njihovo uporabo v velike module. Ponujamo eno samo datoteko glave, ki bo rekurzivno naložila vse datoteke glave, uporabljene v danem modulu. Namesto da bi morali iskati točno tisto glavo, ki jo potrebujete, in morda dobiti pravilen seznam odvisnosti, vam nudimo možnost, da prenesete skupino datotek v veliki razdrobljenosti. To ni najučinkovitejši pristop, vsekakor pa zelo olajša pisanje skriptov.

Vsaka od vključenih datotek ns-3 je postavljena v imenik z imenom ns3 (podimenik gradnje), da se izognete konfliktom imen datotek med postopkom gradnje. mapa ns3/core-module.h ustreza modulu ns-3, ki ga boste našli v imeniku src/jedro v izdaji, ki ste jo namestili. V seznamu tega imenika boste našli veliko število datotek glave. Ko opravite montažo, Waf postavi javne datoteke glave v imenik ns3 v podimenik zgraditi/odpraviti napake

Če nimate takega imenika, to pomeni, da niste navedli izhodnega imenika pri izdelavi različice izdaje ns-3, sestavite takole:
$ ./waf configure --build-profile=debug --out=build/debug
$ ./waf build
ali
$ ./waf configure --build-profile=optimized --out=build/optimized
$ ./waf build

ali zgraditi/optimizirati, odvisno od vaše konfiguracije. Waf bo prav tako samodejno ustvaril vključno datoteko modula za nalaganje vseh javnih datotek glave. Ker seveda sledite temu vodniku verno, ste to že storili

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

da konfigurirate projekt za izvajanje gradenj za odpravljanje napak, ki vključujejo primere in teste. Tudi vi ste

$ ./waf

sestaviti projekt. Torej zdaj, ko pogledate v imenik ../../build/debug/ns3, potem boste tam med drugim našli datoteke glave štirih zgoraj prikazanih modulov. Ogledate si lahko vsebino teh datotek in ugotovite, da vključujejo vse javne datoteke, ki jih uporabljajo ustrezni moduli.

4.2.3 imenski prostor ns3

Naslednja vrstica v skriptu najprej.cc je deklaracija imenskega prostora.

using namespace ns3;

Projekt ns-3 je implementiran v imenskem prostoru C++, imenovanem ns3. To združuje vse deklaracije, povezane z ns-3, v obseg zunaj globalnega imenskega prostora, kar bo, upajmo, pomagalo pri integraciji z drugo kodo. Uporaba operatorja C++ uvede imenski prostor ns-3 v trenutno (globalno) deklarativno regijo. To je domiseln način povedati, da vam po tej izjavi ne bo treba vnesti operaterja dovoljenja ns3::scope pred vso vašo kodo ns-3, da jo lahko uporabite. Če niste seznanjeni z imenskimi prostori, si oglejte skoraj vsak učbenik C++ in primerjajte imenski prostor ns3 z uporabo imenskega prostora in deklaracije std using namespace std; v primerih dela z izhodnim operatorjem cout in potoki.

4.2.4 Beleženje

Naslednja vrstica skripta je,

NS_LOG_COMPONENT_DEFINE ("FirstScriptExample");

To izjavo bomo uporabili kot priročno mesto za razpravo o našem dokumentacijskem sistemu Doksigen. Če pogledate spletno mesto projekta ns-3, boste v navigacijski vrstici našli povezavo Dokumentacija. Če kliknete to povezavo, boste preusmerjeni na našo stran z dokumentacijo. Obstaja povezava »Najnovejša izdaja«, ki vas popelje do dokumentacije za najnovejšo stabilno različico ns-3. Če izberete povezavo »Dokumentacija API-ja«, boste preusmerjeni na stran z dokumentacijo API-ja ns-3.

Na levi strani strani najdete grafični prikaz strukture dokumentacije. Dobro mesto za začetek je »knjiga« Modules ns-3 v navigacijskem drevesu ns-3. Če razkrijete Moduli, boste videli seznam dokumentacije modulov ns-3. Kot je razloženo zgoraj, je koncept modula tukaj neposredno povezan z datotekami, vključenimi v zgornji modul. Podsistem beleženja ns-3 je obravnavan v razdelku Uporaba modula za beleženje, zato se bomo k temu vrnili pozneje v tej vadnici, vendar se o zgornji izjavi lahko naučite tako, da si ogledate modul Corein nato odpiranje knjige Orodja za odpravljanje napakin nato izberite stran Beleženje. Kliknite na Beleženje.

Zdaj bi morali pregledati dokumentacijo Doksigen za modul Beleženje. Na seznamu makrov na vrhu strani boste videli vnos za NS_LOG_COMPONENT_DEFINE. Preden kliknete povezavo, si oglejte »Podroben opis« registracijskega modula, da boste razumeli, kako na splošno deluje. Če želite to narediti, se lahko pomaknete navzdol ali izberete »Več ...« pod grafikonom.

Ko boste imeli splošno predstavo o tem, kaj se dogaja, nadaljujte in si oglejte dokumentacijo za določeno NS_LOG_COMPONENT_DEFINE. Tukaj ne bom podvajal dokumentacije, ampak če povzamem, ta vrstica deklarira registracijsko komponento, imenovano FirstScriptExample, ki vam omogoča, da omogočite ali onemogočite beleženje sporočil v konzolo s sklicevanjem na ime.

4.2.5 Glavna funkcija

V naslednjih vrsticah skripta boste videli,

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

To je preprosto deklaracija glavne funkcije vašega programa (skripta). Kot pri vsakem programu C++ morate definirati glavno funkcijo, ta se najprej izvede. Tukaj ni nič posebnega. Vaš skript ns-3 je samo program C++. Naslednja vrstica nastavi časovno ločljivost na 1 nanosekundo, kar je privzeto:

Time::SetResolution (Time::NS);

Časovna ločljivost ali preprosto ločljivost je najmanjša časovna vrednost, ki jo je mogoče uporabiti (najmanjša predstavljiva razlika med dvema časoma). Ločljivost lahko spremenite natanko enkrat. Mehanizem, ki zagotavlja to prilagodljivost, porablja pomnilnik, tako da, ko je ločljivost izrecno nastavljena, sprostimo pomnilnik in preprečimo nadaljnje posodobitve. (Če ločljivosti ne nastavite izrecno, bo privzeta na eno nanosekundo in pomnilnik bo sproščen, ko se simulacija začne.)

Naslednji dve vrstici skripta se uporabljata za omogočanje dveh komponent beleženja, ki sta vgrajeni v aplikacije EchoClient и EchoServer:

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

Če preberete dokumentacijo za komponento beleženja, boste videli, da obstaja več ravni beleženja/razdrobljenosti, ki jih lahko omogočite za vsako komponento. Ti dve vrstici kode omogočata beleženje odpravljanja napak na nivo INFO za odjemalce in strežnike echo. Na tej ravni bo aplikacija tiskala sporočila med pošiljanjem in prejemanjem paketov med simulacijo.

Zdaj se bomo lotili ustvarjanja topologije in izvajanja simulacije. Uporabljamo topološke pomožne objekte, da bi bilo to delo kar se da enostavno.

4.2.6 Uporaba topoloških pomočnikov

Naslednji dve vrstici kode v našem skriptu bosta dejansko ustvarili objekte Node ns-3, ki bodo predstavljali računalnike v simulaciji.

NodeContainer nodes;
nodes.Create (2);

Preden nadaljujemo, poiščimo dokumentacijo za razred NodeContainer. Drug način za dostop do dokumentacije za določen razred je prek zavihka razredi na straneh Doksigen. Če že imate odprt Doxygen, se preprosto pomaknite na vrh strani in izberite zavihek Razredi. Morali bi videti nov nabor zavihkov, od katerih je eden seznam razredov. Pod tem zavihkom boste videli seznam vseh razredov ns-3. Pomaknite se navzdol do ns3::NodeContainer. Ko najdete razred, ga izberite, da odprete dokumentacijo za razred.

Kot se spomnimo, je ena naših ključnih abstrakcij vozlišče. Predstavlja računalnik, ki mu bomo dodali stvari, kot so skladi protokolov, aplikacije in periferne kartice. Topološki asistent NodeContainer ponuja priročen način za ustvarjanje, upravljanje in dostop do vseh predmetov Node, ki ga ustvarimo za izvajanje simulacije. Prva vrstica zgoraj preprosto navaja NodeContainer, ki jih imenujemo vozlišča. Druga vrstica pokliče metodo Create na objektu vozlišč in zahteva, da vsebnik ustvari dve vozlišči. Kot je opisano v Doksigen, vsebnik zahteva od sistema ns-3, da ustvari dva objekta Node in interno shranjuje kazalce na te objekte.

Vozlišča, ustvarjena v skriptu, še ne delajo ničesar. Naslednji korak pri gradnji topologije je povezovanje naših vozlišč z omrežjem. Najenostavnejša oblika omrežja, ki jo podpiramo, je povezava od točke do točke med dvema vozliščema. Zdaj bomo ustvarili takšno povezavo.

PointToPointHelper

Povezavo od točke do točke ustvarimo z uporabo znanega vzorca, z uporabo topološkega pomožnega objekta za opravljanje dela na nizki ravni, potrebnega za povezavo. Spomnimo se, da sta naši dve ključni abstrakciji NetDevice и Channel. V resničnem svetu ti izrazi približno ustrezajo perifernim karticam in omrežnim kablom. Običajno sta ti dve stvari med seboj tesno povezani in nihče ne more računati na skupno rabo naprav, na primer Ethernet prek brezžičnega kanala. Naši topološki pomočniki sledijo tej tesni povezavi, zato boste v tem scenariju uporabili en sam objekt PointToPointHelper za postavitev in povezovanje objektov ns-3 PointToPointNetDevice и PointToPointChannel. Naslednje tri vrstice v skriptu:

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

Prva vrsta,

PointToPointHelper pointToPoint;

ustvari primerek predmeta na skladu PointToPointHelper. Z vidika najvišje ravni naslednja vrstica,

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

pove predmetu PointToPointHelper uporabite vrednost "5 Mbit/s" (pet megabitov na sekundo) kot "Hitrost prenosa podatkov".

Z bolj specifičnega vidika niz "DataRate" ustreza temu, kar imenujemo atribut PointToPointNetDevice. Če pogledate Doksigen za razred ns3::PointToPointNetDevice in v dokumentaciji za metodo GetTypeId boste našli seznam atributov, definiranih za napravo. Med njimi bo atribut "Hitrost prenosa podatkov" Večina uporabniku vidnih objektov ns-3 ima podobne sezname atributov. Ta mehanizem uporabljamo za enostavno nastavitev simulacije brez ponovnega prevajanja, kot boste videli v naslednjem razdelku.

Podoben "Hitrost prenosa podatkov" v napravi PointToPointNetDevice boste našli atribut "Delay", povezan s kanalom PointToPointChannel. Končna vrstica

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

pravi PointToPointHelper uporabite vrednost "2 ms" (dve milisekundi) kot vrednost zakasnitve širjenja za povezavo od točke do točke, ki jo pozneje ustvari.

NetDeviceContainer

Trenutno imamo v scenariju NodeContainer, ki vsebuje dve vozlišči. Imamo PointToPointHelper, ki je pripravljen za ustvarjanje objektov PointToPointNetDevices in jih povezati z uporabo predmeta PointToPointChannel. Tako kot smo za ustvarjanje vozlišč uporabili pomožni predmet topologije NodeContainer, bomo vprašali PointToPointHelper za nas opravlja delo v zvezi z izdelavo, konfiguracijo in namestitvijo naših naprav. Potrebujemo seznam vseh ustvarjenih predmetov NetDevice, zato uporabljamo NetDeviceContainer da jih shranimo na enak način, kot smo ga uporabili NodeContainer za shranjevanje vozlišč, ki smo jih ustvarili. Naslednji dve vrstici kode,

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

popolna nastavitev naprave in kanala. Prva vrstica deklarira zgoraj omenjeni vsebnik naprave, druga pa opravi glavno delo. Metoda namestitev objekt PointToPointHelper sprejema NodeContainer kot parameter. V notranjosti NetDeviceContainer za vsako vozlišče, ki se nahaja v NodeContainer se ustvari (za komunikacijo od točke do točke morata biti natanko dva) PointToPointNetDevice se ustvari in shrani v vsebnik naprave. PointToPointChannel je ustvarjen in nanj sta priložena dva PointToPointNetDevices. Po ustvarjanju predmetov so atributi, shranjeni v PointToPointHelper, se uporabljajo za inicializacijo ustreznih atributov v ustvarjenih objektih.

Po klicu pointToPoint.Install (vozlišča) imeli bomo dve vozlišči, vsako z nameščeno omrežno napravo točka-točka in eno povezavo točka-točka med njima. Obe napravi bosta konfigurirani za prenos podatkov s hitrostjo pet megabitov na sekundo z zakasnitvijo prenosa dveh milisekund po kanalu.

InternetStackHelper

Zdaj imamo konfigurirana vozlišča in naprave, vendar naša vozlišča nimajo nameščenih skladov protokolov. Za to bosta poskrbeli naslednji dve vrstici kode.

InternetStackHelper stack;
stack.Install (nodes);

InternetStackHelper - je topološki pomočnik za internetne sklade, podoben PointToPointHelperju za omrežne naprave od točke do točke. Metoda namestitev vzame NodeContainer kot parameter. Ko se izvede, bo namestil internetni sklad (TCP, UDP, IP itd.) na vsako vozlišče vsebnika.

IPv4AddressHelper

Nato moramo naše naprave povezati z naslovi IP. Ponujamo pomočnika za topologijo za upravljanje dodeljevanja naslovov IP. Edini API, ki je viden uporabniku, je nastavitev osnovnega naslova IP in omrežne maske za uporabo pri dejanski distribuciji naslovov (to se izvede na nižji ravni znotraj pomočnika). Naslednji dve vrstici kode v našem primeru skripta najprej.cc,

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

deklarirajte objekt pomočnika za naslove in mu povejte, da bi moral začeti dodeljevati naslove IP iz omrežja 10.1.1.0, pri čemer za določitev uporabite bitno masko 255.255.255.0. Privzeto se bodo dodeljeni naslovi začeli pri enem in monotono povečevali, tako da bo prvi naslov, dodeljen iz te baze, 10.1.1.1, nato 10.1.1.2 itd. V resnici si sistem ns-3 na nizki ravni zapomni vse dodeljene naslove IP in ustvari usodno napako, če pomotoma ustvarite situacijo, v kateri se isti naslov ustvari dvakrat (mimogrede, to napako je težko odpraviti).

Naslednja vrstica kode,

Ipv4InterfaceContainer interfaces = address.Assign (devices);

izvede dejansko dodelitev naslova. V ns-3 vzpostavimo povezavo med naslovom IP in napravo, ki uporablja objekt Vmesnik IPv4. Tako kot včasih potrebujemo seznam omrežnih naprav, ki jih ustvari pomočnik za poznejšo uporabo, včasih potrebujemo seznam predmetov Vmesnik IPv4. IPv4InterfaceContainer zagotavlja to funkcionalnost.

Zgradili smo omrežje od točke do točke z nameščenimi skladi in dodeljenimi naslovi IP. Zdaj potrebujemo aplikacije v vsakem vozlišču za ustvarjanje prometa.

4.2.7 Uporaba aplikacije

Druga glavna abstrakcija sistema ns-3 je uporaba (prijava). V tem scenariju uporabljamo dve specializaciji osnovnega razreda uporaba poklican ns-3 UdpEchoServerApplication и UdpEchoClientApplication. Kot v prejšnjih primerih uporabljamo pomožne objekte za konfiguracijo in upravljanje osnovnih objektov. Tukaj uporabljamo UdpEchoServerHelper и UdpEchoClientHelper predmetov, ki nam olajšajo življenje.

UdpEchoServerHelper

Naslednje vrstice kode v našem vzorčnem skriptu first.cc se uporabljajo za konfiguriranje strežniške aplikacije UDP echo na enem od vozlišč, ki smo jih ustvarili prej.

UdpEchoServerHelper echoServer (9);

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

Prva vrstica kode v zgornjem izrezku ustvari UdpEchoServerHelper. Kot običajno, to ni aplikacija sama, je predmet, ki nam pomaga ustvarjati prave aplikacije. Ena od naših konvencij je posredovanje zahtevanih atributov konstruktorju pomožnega objekta. V tem primeru pomočnik ne more narediti nič koristnega, razen če dobi številko vrat, na katerih bo strežnik poslušal pakete, to številko mora poznati tudi odjemalec. V tem primeru posredujemo številko vrat pomožnemu konstruktorju. Konstruktor pa preprosto naredi SetAttribute s posredovano vrednostjo. Pozneje lahko po želji uporabite SetAttribute, da nastavite drugo vrednost za atribut Port.

Tako kot mnogi drugi pomožni objekti tudi objekt UdpEchoServerHelper ima metodo namestitev. Izvajanje te metode učinkovito ustvari osnovno aplikacijo strežnika echo in jo poveže z gostiteljem. Zanimivo, metoda namestitev sprejema NodeContainer kot parameter tako kot drugi namestitev metode, ki smo jih videli.

Implicitna pretvorba C++, ki deluje tukaj, vzame rezultat metode vozlišče.Get(1) (ki vrne pametni kazalec na objekt vozlišča - Ptr ) in ga uporabi v konstruktorju za anonimni objekt NodeContainerki se nato posreduje metodi namestitev. Če v kodi C++ ne morete določiti, kateri podpis metode je preveden in izveden, poiščite med implicitnimi pretvorbami.

Zdaj to vidimo echoServer.Install namerava namestiti aplikacijo UdpEchoServerApplication na najdenem v NodeContainerki ga uporabljamo za upravljanje naših vozlišč, vozlišče z indeksom 1. Metoda namestitev bo vrnil vsebnik, ki vsebuje kazalce na vse aplikacije (v tem primeru eno, ker smo posredovali anonimni NodeContainer, ki vsebuje eno vozlišče), ki ga je ustvaril pomočnik.

Aplikacije morajo določiti, kdaj naj začnejo ustvarjati promet "začetek" in morda bo treba dodatno določiti čas, ko naj se ustavi "stop". Ponujamo obe možnosti. Ti časi so nastavljeni z uporabo metod ApplicationContainer Začetek и stop. Te metode sprejemajo parametre tipa čas. V tem primeru uporabimo eksplicitno zaporedje pretvorb C++, da vzamemo C++ podvojila 1.0 in ga pretvorite v časovni objekt tns-3, ki za pretvorbo v sekunde uporablja predmet Seconds. Ne pozabite, da lahko pravila pretvorbe nadzira avtor modela, C++ pa ima svoja lastna pravila, tako da ne morete vedno računati, da bodo parametri pretvorjeni tako, kot ste pričakovali. Dve vrstici

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

bo povzročil, da se aplikacija strežnika echo zažene (samodejno vklopi) eno sekundo po začetku simulacije in se ustavi (izklopi) po desetih sekundah simulacije. Ker smo razglasili simulacijski dogodek (dogodek zaustavitve aplikacije), ki se bo izvedel v desetih sekundah, bo simulirano vsaj deset sekund delovanja omrežja.

UdpEchoClientHelper

Odjemalska aplikacija echo konfiguriran na skoraj podoben način kot strežnik. Obstaja osnovni objekt UdpEchoClientApplication, ki je nadzorovana
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));;

Vendar pa moramo za odjemalca echo nastaviti pet različnih atributov. Prva dva atributa sta nastavljena ob ustvarjanju UdpEchoClientHelper. Posredujemo parametre, ki se uporabljajo (znotraj pomočnika) za nastavitev atributov "RemoteAddress" и "RemotePort" v skladu z našim dogovorom o posredovanju potrebnih parametrov pomožnemu konstruktorju.

Spomnimo se, da smo uporabili IPv4InterfaceContainer za sledenje naslovom IP, ki smo jih dodelili našim napravam. Ničelni vmesnik v vsebniku vmesnikov bo ustrezal naslovu IP ničelnega vozlišča v vsebniku vozlišč. Prvi vmesnik v vsebniku vmesnikov ustreza naslovu IP prvega vozlišča v vsebniku vozlišč. Torej, v prvi vrstici kode (zgoraj) ustvarimo pomočnika in mu povemo, da bo oddaljeni naslov odjemalca naslov IP, dodeljen gostitelju, kjer se nahaja strežnik. Povemo tudi, da moramo urediti pošiljanje paketov na vrata devet.

Atribut "MaxPackets" odjemalcu pove največje število paketov, ki jih lahko pošljemo med simulacijo. Atribut "Interval" odjemalcu pove, kako dolgo mora čakati med paketi, atribut "PacketSize" pa odjemalcu pove, kako velika mora biti koristna obremenitev paketa. S to kombinacijo atributov povemo odjemalcu, naj pošlje en sam 1024-bajtni paket.

Tako kot pri echo strežniku nastavimo atribute odjemalca echo Začetek и stop, tukaj pa odjemalca zaženemo sekundo po vklopu strežnika (dve sekundi po začetku simulacije).

4.2.8 Simulator

Na tej točki moramo zagnati simulacijo. To se naredi z uporabo globalne funkcije Simulator::Zaženi.

Simulator::Run ();

Ko smo prej klicali metode,

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

dejansko smo načrtovali dogodke v simulatorju na 1,0 sekunde, 2,0 sekunde in dva dogodka na 10,0 sekunde. Po klicu Simulator::Zaženi, bo sistem začel pregledovati seznam načrtovanih dogodkov in jih izvajati. Po 1,0 sekundah bo najprej sprožil dogodek, ki bo sprožil aplikacijo strežnika echo (ta dogodek lahko načrtuje številne druge dogodke). Nato bo sprožil dogodek, načrtovan pri t=2,0 sekundah, ki bo zagnal aplikacijo odjemalca echo. Tudi ta dogodek ima morda načrtovanih veliko več dogodkov. Izvedba začetnega dogodka v odjemalcu echo bo začela fazo prenosa podatkov simulacije s pošiljanjem paketa strežniku.

Dejanje pošiljanja paketa na strežnik bo sprožilo verigo dogodkov, ki bodo samodejno načrtovani v zakulisju in ki bodo izvajali mehaniko pošiljanja odmevnega paketa v skladu s časovnimi parametri, ki smo jih nastavili v skriptu.

Kot rezultat, ker pošiljamo samo en paket (ne pozabite, atribut MaxPackets je bila nastavljena na ena), se bo veriga dogodkov, ki jih sproži ta posamezen odjemalski ping, končala in simulacija bo prešla v stanje pripravljenosti. Ko se to zgodi, bodo preostali načrtovani dogodki dogodki stop za strežnik in odjemalec. Ko se ti dogodki izvedejo, ne bo več dogodkov za nadaljnjo obdelavo in Simulator::Zaženi bo vrnil nadzor. Simulacija je končana.

Ostane le še pospraviti za seboj. To se naredi s klicem globalne funkcije Simulator::Uniči. Ker so bile poklicane pomožne funkcije (ali nizkonivojska koda ns-3), ki so organizirane tako, da so bile v simulator vstavljene kljuke za uničenje vseh ustvarjenih objektov. Nobenega od teh predmetov vam ni bilo treba slediti sami – vse, kar ste morali storiti, je bilo poklicati Simulator::Uniči in pojdi ven. Sistem ns-3 bo to težko delo opravil namesto vas. Preostale vrstice našega prvega skripta ns-3, first.cc, naredijo prav to:

Simulator::Destroy ();
return 0;
}

Kdaj se bo simulator ustavil?

ns-3 je simulator diskretnih dogodkov (DE). V takem simulatorju je vsak dogodek povezan s svojim časom izvajanja, simulacija pa se nadaljuje z obdelavo dogodkov v vrstnem redu, v katerem se pojavijo, ko simulacija napreduje. Dogodki lahko povzročijo načrtovanje prihodnjih dogodkov (na primer, časovnik se lahko prestavi, da konča štetje v naslednjem intervalu).

Začetne dogodke običajno sproži entiteta, IPv6 bo na primer načrtoval odkrivanje storitev v omrežju, sosednje zahteve itd. Aplikacija načrtuje dogodek pošiljanja prvega paketa itd. Ko je dogodek obdelan, lahko ustvari nič, enega ali več dogodkov. Ko simulacija napreduje, se dogajajo dogodki, ki se končajo ali ustvarijo nove. Simulacija se bo samodejno ustavila, če je čakalna vrsta dogodkov prazna ali je zaznan poseben dogodek stop. Dogodek stop ki jih ustvari funkcija Simulator::Stop (ustavi čas).

Obstaja tipičen primer, ko je Simulator::Stop absolutno potreben za zaustavitev simulacije: ko pride do samozadostnih dogodkov. Samozadostni (ali ponavljajoči se) dogodki so dogodki, ki so vedno prestavljeni. Zato čakalna vrsta dogodkov vedno ostane prazna. Obstaja veliko protokolov in modulov, ki vsebujejo ponavljajoče se dogodke, na primer:

• FlowMonitor - periodično preverjanje izgubljenih paketov;

• RIPng – periodično oddajanje posodobitev usmerjevalnih tabel;

• itd.

V takih primerih Simulator::Stop potrebno za pravilno zaustavitev simulacije. Poleg tega, ko je ns-3 v emulacijskem načinu, se RealtimeSimulator uporablja za sinhronizacijo simulacijske ure z uro stroja in Simulator::Stop potrebno za ustavitev postopka.

Številni simulacijski programi v učbeniku ne kličejo Simulator::Stop izrecno, saj se samodejno končajo, ko so dogodki v čakalni vrsti izčrpani. Vendar bodo ti programi sprejeli tudi klic Simulator::Stop. Na primer, naslednji dodatni stavek v prvem vzorčnem programu bi načrtoval izrecno zaustavitev na 11 sekund:

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

Zgoraj navedeno ne bo dejansko spremenilo obnašanja tega programa, saj se ta posebna simulacija seveda konča po 10 sekundah. Toda če bi spremenili čas zaustavitve v zgornjem stavku z 11 sekund na 1 sekundo, bi opazili, da se simulacija ustavi, preden kateri koli izhod zadene zaslon (ker se izhod pojavi po približno 2 sekundah časa simulacije).

Pomembno je, da pokličete Simulator::Stop, preden pokličete Simulator::Run; sicer Simulator::Run morda nikoli ne vrne nadzora glavnemu programu za izvedbo zaustavitve!

4.2.9 Gradnja vašega skripta

Ustvarjanje preprostih skriptov smo naredili trivialno. Vse, kar morate storiti, je, da svoj skript postavite v scratch imenik in samodejno bo zgrajen, če ga zaženete Waf. Poskusimo. Vrnite se v imenik najvišje ravni in kopirajte examples/tutorial/first.cc v katalog praska

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

Zdaj sestavite svoj prvi vzorčni skript z uporabo WAF:

$ ./waf

Morali bi videti sporočila, ki kažejo, da je bil vaš prvi primer uspešno ustvarjen.

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)

Zdaj lahko zaženete primer (upoštevajte, da če gradite svoj program v scratch imeniku, ga morate zagnati iz praska):

$ ./waf --run scratch/myfirst

Morali bi videti podoben rezultat:

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

Tukaj lahko vidite, da sistem gradnje preveri, ali je bila datoteka zgrajena, in jo nato zažene. V odjemalcu echo vidite vnos komponente, ki označuje, da je strežniku echo 1024 poslal en sam 10.1.1.2-bajtni paket. Tudi vi vidite komponento beleženja na strežniku echo, ki pravi, da je prejel 1024 bajtov od 10.1.1.1. Strežnik echo tiho ponovno predvaja paket in v dnevniku odjemalca echo lahko vidite, da je prejel svoj paket nazaj od strežnika.

4.3 ns-3 Izvorna koda

Zdaj, ko ste uporabili nekaj pomočnikov ns-3, si lahko ogledate nekaj izvorne kode, ki izvaja to funkcionalnost. Najnovejšo kodo si lahko ogledate na našem spletnem strežniku na naslednji povezavi: https://gitlab.com/nsnam/ns-3-dev.git. Tam boste videli stran s povzetkom Mercurial za naše razvojno drevo ns-3. Na vrhu strani boste videli več povezav,

summary | shortlog | changelog | graph | tags | files

Nadaljujte in izberite povezavo datotek. Tako bo videti najvišja raven večine naših skladišč:

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ši primeri skriptov so v imeniku Primeri. Če kliknete na primere, boste videli seznam podimenikov. Ena od datotek v podimeniku vadnica - first.cc. Če kliknete na najprej.cc videli boste kodo, ki ste se jo pravkar naučili.

Izvorna koda se večinoma nahaja v imeniku src. Izvorno kodo si lahko ogledate tako, da kliknete ime imenika ali kliknete povezavo do datotek desno od imena imenika. Če kliknete imenik src, se prikaže seznam podimenikov src. Če nato kliknete osnovni podimenik, boste našli seznam datotek. Prva datoteka, ki jo boste videli (v času pisanja tega priročnika), je abort.h. Če kliknete na povezavo abort.h, boste poslani v izvorno datoteko za abort.h, ki vsebuje uporabne makre za izhod iz skriptov, če so zaznane nenormalne razmere. Izvorno kodo za pomočnike, ki smo jih uporabili v tem poglavju, lahko najdete v imeniku src/Aplikacije/pomočnik. Pobrskajte po drevesu imenikov, da ugotovite, kaj je kje, in razumete slog programov ns-3.

Vir: www.habr.com

Dodaj komentar