
4 Pregled koncepta
4.1 Ključne apstrakcije
4.1.1 Čvor (Node)
4.1.2 Aplikacija (Application)
4.1.3 Kanal (Channel)
4.1.4 Mrežni uređaj (Net Device)
4.1.5 Topološki pomagači
4.2 Prvi skript ns-3
4.2.1 Osnovni kod (Boilerplate code)
4.2.2 Ugrađeni moduli (Plug-ins)
4.2.3 Prostorni naziv ns3 (Namespace)
4.2.4 Zapisivanje (Logging)
4.2.5 Glavna funkcija (Main function)
4.2.6 Korišćenje topoloških pomagača
4.2.7 Korišćenje aplikacije (Application)
4.2.8 Simulator
4.2.9 Skupljanje vašeg scenarija
4.3 Izvorni kod ns-3
Poglavje 4
Pregled koncepta
Prvo što moramo učiniti pre nego što počnemo da učimo ili pišemo kod ns-3 je da objasnimo nekoliko osnovnih pojmova i apstrakcija u sistemu. Mnogi od ovih pojmova mogu delovati očigledno, ali preporučujemo da odvojite vreme za čitanje ovog dela kako biste bili sigurni da počinjete na čvrstoj osnovi.
4.1 Ključne apstrakcije
U ovom odeljku razmotrićemo neke termine koji se obično koriste u mreži, ali imaju posebno značenje u ns-3.
4.1.1 Čvor (Node)
U internet žargonu, računar koji se povezuje na mrežu naziva se host ili ponekad krajnji sistem. Zbog toga što je ns-3 simulator mreže, a ne simulator Interneta, namerno ne koristimo termin host, pošto je taj pojam usko povezan sa Internetom i njegovim protokolima. Umesto toga, koristimo opštiji termin, koji koriste i drugi simulatori, koji potiče iz teorije grafova — čvor (Node)node).
U ns-3, osnovna apstrakcija računarske jedinice naziva se čvor. Ova apstrakcija je predstavljena u C++ klasi Node. Klasa NodeNode (čvor) pruža metode za upravljanje reprezentacijama računalnih uređaja u simulacijama.
Trebalo bi da razumete Čvor kako računar na koji ćete dodati funkcionalnosti. Dodaćete stvari poput aplikacija, stekova protokola i perifernih kartica sa drajverima, što omogućava računaru da obavlja korisni rad. Koristimo istu osnovnu modela u ns-3.
4.1.2 Aplikacija (Application)
Običajno se računalniški programski nazivi delijo v dva široka razreda. Sistem programske opreme organizira različne računalniške vire, kot so pomnilnik, procesorski cikli, disk, omrežje itd., v skladu z neko računalniško modelom. Sistem programska oprema običajno ne uporablja teh virov za opravljanje nalog, ki prinašajo neposredno korist uporabniku. Uporabnik običajno za dosego določenega cilja zažene aplikacijo, ki pridobi in uporablja vire, ki jih nadzira sistemska programska oprema.
Pogosto se meja med sistemsko in aplikativno programsko opremo postavi z večanjem nivoja privilegijev, ki se zgodi v prekinitvah operacijskega sistema. V ns‑3 ni pravega koncepta operacijskega sistema in zato ni pojmov nivojev privilegijev ali sistemskih klicev. Imamo pa idejo aplikacije. Tako kot v 'resničnem svetu' za izvajanje nalog programske aplikacije delujejo na računalnikih, aplikacije ns‑3 delujejo na vozliščih ns‑3 za upravljanje simulacij v simuliranem svetu.
V ns‑3 je osnovna abstrakcija za uporabniški program, ki generira določeno aktivnost za modeliranje, aplikacija. Ta abstrakcija je predstavljena v C++ razredu Application (aplikacija). Razred Application nudi metode za upravljanje v simulacijah zamejitev naše različice aplikacij nivoja uporabnika. Od razvijalcev se pričakuje, da bodo za ustvarjanje novih aplikacij specializirali razred Application v smislu objektno usmerjenega programiranja. V tem vodniku bomo uporabljali specializacije razreda Application, imenovane UdpEchoClientApplication in UdpEchoServerApplication. Kot pričakovano, te aplikacije predstavljajo niz aplikacij odjemalca / strežnika, ki se uporabljajo za generiranje in eho-simulacijo omrežnih paketov.
4.1.3 Kanal (Channel)
V resničnem svetu lahko povežete računalnik z omrežjem. Pogosto se okolja, prek katerih se prenašajo podatki v teh omrežjih, imenujejo kanali. Ko priključite Ethernet kabel v vtičnico na steni, povežete računalnik z Ethernet komunikacijskim kanalom. V simuliranem svetu ns-3 je vozlišče povezano z objektom, ki predstavlja komunikacijski kanal. Tukaj je osnovna abstrakcija komunikacijske podmreže imenovana kanal in je predstavljena s C++ razredom Channel (kanal).
Razred ChannelChannel nudi metode za upravljanje interakcij med objekti podmreže in povezovanjem vozlišč nanje. Kanali so lahko tudi specializirani s strani razvijalcev v smislu objektno usmerjenega programiranja. Specializacija kanala lahko modelira nekaj preprostega, kot je žica. Specializirani kanal lahko prav tako modelira kompleksne stvari, kot je velik Ethernet preklopnik ali tridimenzionalni prostor, poln ovir v primeru brezžičnih omrežij.
V tem priročniku bomo uporabljali specializirane različice kanala, imenovane CsmaChannelCsmaChannel, PointToPointChannelPointToPointChannel in WifiChannelWifiChannel. CsmaChannel, na primer, modelira različico komunikacijske podmreže, ki implementira okolje komunikacije z večjim dostopom s kontrolo nosilca. To nam daje funkcionalnost podobno Ethernetu.
4.1.4 Mrežni uređaj (Net Device)
Pred tem je bilo tako, da je bilo potrebno kupiti določen omrežni kabel in strojno opremo, imenovano (v terminologiji računalnikov) periferna kartica, ki jo je bilo treba namestiti v računalnik. Če je bila na periferne kartici implementirana neka omrežna funkcija, so jih imenovali omrežne vmesne kartice ali omrežne kartice. Danes večina računalnikov pride z vgrajeno strojno opremo za omrežni vmesnik, in uporabniki je ne dojemajo kot ločena naprava.
Omrežna kartica ne bo delovala brez programske gonilnike, ki upravljajo njeno strojno opremo. V Unixu (ali Linuxu) se del opreme razvršča kot naprava. Naprave se upravljajo z gonilniki naprav (device drivers), omrežne naprave (NIC) pa se upravljajo z uporabo gonilnikov omrežnih naprav (network device drivers) in imajo zbirno ime omrežne naprave (net devices). V Unixu in Linuxu se na omrežne naprave obrnete z imeni, kot so na primer eth0.
V ns-3 abstrakcija omrežne naprave zajema tako programski vmesnik kot tudi modelirano opremo. Pri simulaciji je omrežna naprava »nameščena« v vozlišču, da mu omogoči povezovanje z drugimi vozlišči prek kanalov. Tako kot v realnem računalniku je vozlišče lahko povezano z več kanali prek več naprav NetDevices.
Omrežna abstrakcija naprave je predstavljena v C++ s razredom NetDevice. Razred NetDevice ponuja metode za upravljanje povezav z objekti Node in Channel; in jih lahko razvijalci specializirajo v smislu objektno usmerjenega programiranja. V tem vodniku bomo uporabili več specializiranih različic NetDevice z imeni CsmaNetDevice, PointToPointNetDevice in WifiNetDevice. Tako kot je omrežni adapter Ethernet namenjen delu z omrežjem Ethernet, CsmaNetDevice je namenjen delu z CsmaChannel, PointToPointNetDevice je namenjen delu z PointToPointChannel, a WifiNetDevice — je namenjen delu z WifiChannel.
4.1.5 Topološki pomagači
V resničnem 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 povezanimi NetDevices. V veliki simulirani mreži boste morali organizirati povezave med številnimi objekti Čvor, NetDevice in Channel.
Ker so povezovanje NetDevices z vozli, NetDevices s kanali, dodeljevanje IP naslovov itd. v ns-3 skupna naloga, da bi to naredili čim lažje, nudimo tako imenovane topološke pomočnike. Na primer, za ustvarjanje NetDevice je potrebno izvesti več jedrnih operacij ns-3, dodati MAC naslov, namestiti to omrežno napravo v Node, konfigurirati protokolni sklad vozlišča in nato povezati NetDevice s Channel. Še več operacij bo potrebno za povezovanje več naprav z večtočkovnimi kanali in nato povezovanje posameznih omrežij v povezano omrežje (Internetworks). Nudimo pomožne topološke objekte, ki združujejo te številne operacije v enostavno uporabno strukturo za vašo udobnost.
4.2 Prvi skript ns-3
Če ste sistem namestili, kot je bilo predlagano zgoraj, boste imeli izdajo ns-3 v imeniku z imenom repos v vaši domači mapi. Pojdite v direktorij release
Če takega direktorija nimate, to pomeni, da pri gradnji izdaje ns-3 niste navedli izhodnega direktorija, izvedite gradnjo tako:
$ .\/waf configure —build-profile=release —out=build\/release,
$ .\/waf build
tu morate videti strukturo direktorij, podobno naslednjemu:
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.pycPojdite v direktorij examples/tutorial. Tam bi morali videti datoteko z imenom first.cc. To je skript, ki bo ustvaril preprosto točko do točke povezavo med dvema vozlišči in prenesel en paket med vozlišči. Poglejmo ta skript vrstico po vrstici, zato odprite first.cc v vašem priljubljenem urejevalniku.
4.2.1 Osnovni kod (Boilerplate code)
Prva vrstica v datoteki je vrstica načina urejevalnika emacs. Ta vrstica pove emacsu o konvencijah oblikovanja (slog kodiranja), ki jih bomo uporabili v našem izvorni kodi.
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */To je vedno precej sporno vprašanje, zato moramo priti do jasnosti, da ga takoj odstranimo s poti. Projekt ns‑3, tako kot večina večjih projektov, je sprejel slog kodiranja, ki mu mora slediti vse predloženo kodo. Če želite vključiti svojo kodo v projekt, boste na koncu morali ustrezati standardu kodiranja ns‑3, kot je opisano v datoteki doc/codingstd.txt ali prikazan na spletni strani projekta: .
Priporočamo vam, da se navadite na videz kode ns‑3 in uporabljate ta standard vsakič, ko delate z našo kodo. Vsa ekipa razvijalcev in prispevkov se je strinjala s tem po nekem pritožovanju. Enačba načina emacs, navedena zgoraj, poenostavi pravilno oblikovanje, če uporabljate urejevalnik emacs.
Simulator ns‑3 je licenciran z uporabo GNU General Public License. V vsakem datotečnem paketu ns‑3 boste videli ustrezen pravni naslov GNU. Pogosto lahko vidite obvestilo o avtorskih pravicah za eno od sodelujočih institucij v projektu ns‑3 nad besedilom GPL in avtorjem, prikazanem 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 Ugrađeni moduli (Plug-ins)
Dejansko se koda začne s številnimi direktivami za vključitev (include).
#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 korisnicima visokog nivoa skripti olakšali rad s velikim brojem zaglavlja prisutnih u sistemu, grupišemo ih prema njihovoj upotrebi u velike module. Pružamo jedno zaglavlje koje će rekurzivno učitati sva zaglavlja koja se koriste u datom modulu. Umesto da tražite koje tačno zaglavlje vam je potrebno, i možda dobijete pravilnu listu zavisnosti, omogućavamo vam da učitate grupu fajlova sa visokom stepenom detaljnosti. Ovo nije najefikasniji pristup, ali sigurno čini pisanje skripti mnogo lakšim.
Svaki od uključivanih fajlova ns-3 smešten je u direktorijum pod imenom ns3 (poddirektorijum izgradnje), kako bi se tokom procesa izgradnje izbegli konflikti imena fajlova. Fajl ns3/core-module.h odgovara ns-3 modu koji ćete pronaći u direktorijumu src/core u izdanju koje ste instalirali. U listi ovog direktorijuma naći ćete veliki broj zaglavlja. Kada izvršite izgradnju, Waf stavlja javna zaglavlja u direktorijum ns3 u poddirektorijum build/debug
Če takega direktorija nimate, to pomeni, da pri gradnji izdaje ns-3 niste navedli izhodnega direktorija, izvedite gradnjo tako:
$ ./waf configure --build-profile=debug --out=build/debug
$ .\/waf build
ili
$ ./waf configure --build-profile=optimized --out=build/optimized
$ .\/waf build
ili build/optimized, u zavisnosti od vaše konfiguracije. Waf takođe će automatski generisati uključeni fajl modula za učitavanje svih javnih zaglavlja. Pošto naravno strogo pratite ovaj vodič, već ste uradili
$ ./waf -d debug --enable-examples --enable-tests configureda biste podesili projekat na izvršavanje debug izgradnji, uključujući primere i testove. Takođe ste uradili
$ ./wafda biste izgradili projekat. Tako da sada, kada pogledate u direktorijum ../..../build/debug/ns3, tamo, među ostalim, naći ćete zaglavlja četiri modula koja su prikazana iznad. Možete pogledati sadržaj ovih fajlova i otkriti da uključuju sve javne fajlove koje koriste odgovarajući moduli.
4.2.3 Prostorni naziv ns3 (Namespace)
Sledeća linija u skripti first.cc je deklaracija prostora imena.
using namespace ns3;Projekt ns‑3 je implementiran u C++ imenskom prostoru nazvanom ns3. Ovo grupiše sve ns‑3 povezane deklaracije u opsegu van globalnog imenskog prostora, što, nadamo se, će pomoći u integraciji s drugim kodom. Korišćenje C++ operatora uvodi imenski prostor ns‑3 u trenutni (globalni) deklarativni region. Ovo je neobičan način da se kaže da nakon ove deklaracije nećete morati da unosite ns3:: operator pre celog ns‑3 koda da biste ga koristili. Ako niste upoznati sa imenskim prostorima, obratite se bilo kojoj C++ literaturi i uporedite imenski prostor ns3 sa korišćenjem imenskog prostora std i deklaracija. using namespace std; u primerima rada sa izlaznim operatorom cout i tokovima.
4.2.4 Zapisivanje (Logging)
Sledeća linija skripta je ovakva,
NS_LOG_COMPONENT_DEFINE ("FirstScriptExample");Koristićemo ovu izjavu kao zgodno mesto za raspravu o našem sistemu dokumentacije Doxygen. Ako pogledate veb sajt projekta ns‑3, naći ćete link "Dokumentacija" (Documentation) na navigacionoj traci. Ako izaberete ovaj link, odvešće vas na našu stranu dokumentacije. Postoji link za "Poslednje izdanje", koji će vas odvesti do dokumentacije za najnoviju stabilnu verziju ns‑3. Ako izaberete link "API Documentation", doći ćete do stranice za API dokumentaciju ns‑3.
Sa leve strane stranice naći ćete grafički prikaz strukture dokumentacije. Dobro mesto za početak je "knjiga" Moduli ns‑3 u navigacionom stablu ns‑3. Ako otvorite Modules, videćete spisak dokumentacije modula ns‑3. Kao što je ranije pomenuto, koncept modula ovde je direktno povezan sa datotekama uključenim u modul iznad. Podsistem logovanja (vođenja dnevnika) ns‑3 diskutuje se u odeljku Korišćenje modula za logovanje, zato ćemo se tome vratiti kasnije u ovom priručniku, ali možete saznati o pomenutoj izjavi tako što ćete pogledati modul Jedro, a zatim otvoriti knjigu Debugging tools, a zatim izabrati stranicu Logging. Kliknite na Logging.
Sada treba da pregledate dokumentaciju Doxygen za modul Logging. Na seznamu makrov na vrhu strani boste videli vnos za NS_LOG_COMPONENT_DEFINE. Preden nadaljujete po povezavi, obvezno preberite 'Podrobno opis' modula za beleženje, da boste razumeli njegovo delovanje v celoti. To lahko storite tako, da se pomikate navzdol ali izberete 'Več…' pod diagramom.
Ko boste imeli splošno predstavo o tem, kar se dogaja, nadaljujte in preberite dokumentacijo za konkretne NS_LOG_COMPONENT_DEFINE. Tukaj ne bom ponavljal dokumentacije, vendar, povzemam, ta vrstica razglaša komponento beleženja z imenom FirstScriptExample, ki omogoča vklop in izklop beleženja sporočil po konzoli s povezavo do imena.
4.2.5 Glavna funkcija (Main function)
V naslednjih vrsticah skripta boste videli,
int
main (int argc, char *argv[])
{ To je preprosta deklaracija glavne funkcije vašega programa (skripta). Tako kot v katerem koli programu v C++ morate definirati glavno funkcijo, ki se izvaja prva. Tu ni nič posebnega. Vaš skript ns-3 je preprosto C++ program. Naslednja vrstica nastavi časovno razmerje na 1 nanosekundo, kar je privzeta vrednost:
Time::SetResolution (Time::NS);Časovno razmerje ali preprosto razmerje je najmanjša vrednost časa, ki se lahko uporabi (najmanjša predstavljiva razlika med dvema vrednostma časa). Razmerje lahko spremenite samo enkrat. Mehanizem, ki zagotavlja to fleksibilnost, porabi spomin, zato, ko je razmerje enkrat eksplicitno nastavljeno, sprostimo pomnilnik, da preprečimo nadaljnje posodobitve. (Če razmerja ne nastavite eksplicitno, bo privzeto enako eni nanosekundi in pomnilnik se sprosti ob začetku simulacije.)
Naslednji dve vrstici skripta se uporabljata za vklop dveh komponent beleženja, ki sta vgrajeni v aplikacije EchoClient in EchoServer:
LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO); LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO);Če ste prebrali dokumentacijo komponenta Logging, boste opazili, da obstajajo različne ravni podrobnosti beleženja, ki jih lahko vključite pri vsaki komponenti. Ti dve vrstici kode vključujeta beleženje odpravljanja napak na ravni INFO za echo stranke in strežnike. Na tej ravni bo aplikacija med simulacijo tiskala sporočila ob pošiljanju in prejemu paketov.
Sedaj se bomo neposredno lotili ustvarjanja topologije in zagon simulacije. Uporabili bomo objekte topoloških pomočnikov, da bo ta naloga čim enostavnejša.
4.2.6 Korišćenje topoloških pomagača
Naslednji dve vrstici kode v našem skriptu dejansko ustvarjata 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 dostopa do dokumentacije za ta razred je prek zavihka Classes na straneh Doxygen. Če je Doxygen že odprt, preprosto pomaknite navzgor do vrha strani in izberite zavihek Classes. Videli boste nov niz zavihkov, eden od njih pa je 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 ta razred.
Kot se spomnimo, je ena naših ključnih abstrakcij vozlišče. Predstavlja računalnik, kiu bomo dodali elemente, kot so protokoli, aplikacije in strojne komponente. Topološki pomočnik NodeContainer nudi enostaven način za ustvarjanje, upravljanje in dostop do vseh objektov Čvor, ki jih ustvarjamo za zagon simulacije. Prva vrstica zgoraj samo razglaša NodeContainer, ki ga imenujemo nodes. Druga vrstica kliče metodo Create za objekt nodes in prosi, da kontejner ustvari dva vozlišča. Kot je opisano v Doxygen, kontejner zahteva od sistema ns-3 ustvarjanje dveh objektov Čvor in ohranja kazalce na te objekte v sebi.
Ustvarjena vozlišča v skriptu še nič ne počnejo. Naslednji korak pri gradnji topologije je povezava naših vozlišč v omrežje. Najenostavnejša oblika omrežja, ki jo podpiramo, je povezava med dvema vozliščema. Zdaj bomo ustvarili to povezavo.
PointToPointHelper
Ustvarjamo dvotočkovno povezavo, delujemo po znanem vzorcu, uporabljamo topološki pomožni objekt za opravljanje nizko nivojskega dela, potrebnega za povezovanje. Ponovimo, da sta naši dve ključni abstrakciji NetDevice in Channel. V resničnem svetu ti izrazi približno ustrezajo perifernim karticam in omrežnim kablom. Na splošno sta ti dve stvari tesno povezani in nihče ne more računati na izmenjavo, na primer, naprave Ethernet prek brezžičnega kanala. Naši topološki pomočniki sledijo tej tesni povezanosti in zato boste v tem scenariju uporabili en objekt PointToPointHelper za konfiguracijo in povezovanje ns-3 objektov PointToPointNetDevice in PointToPointChannel. Naslednje tri vrstice v scenariju:
PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));Prva vrstica,
PointToPointHelper pointToPoint;ustvari v steku instanco objekta PointToPointHelper. Z vidika višje ravni naslednja vrstica,
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));pove objektu PointToPointHelper uporabiti vrednost "5 Mbps" (pet megabitov na sekundo) kot "DataRate».
Z bolj specifičnega vidika vrstica "DataRate" ustreza temu, kar imenujemo atribut PointToPointNetDevice. Če pogledate na Doxygen za razred ns3::PointToPointNetDevice in v dokumentaciji za metodo GetTypeId boste našli seznam atributov, ki so določeni za napravo. Med njimi bo atribut "DataRate". Večina objektov ns-3, vidnih uporabniku, ima podoben seznam atributov. Ta mehanizem uporabljamo za enostavno prilagajanje simulacije brez ponovnega prevajanja, kot boste videli v naslednjem razdelku.
Podobno kot "DataRate" v PointToPointNetDevice, boste našli atribut "Delay", povezan s PointToPointChannel. Končna vrstica,
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));kaže PointToPointHelper uporablja vrednost "2 ms" (dve milisekundi) kot vrednost zakasnitve širjenja preko kanala točka-točka, ki ga nato ustvari.
NetDeviceContainer
Trenutno imamo v scenariju NodeContainer, ki vsebuje dve vozli. Imamo PointToPointHelper, ki je pripravljen za ustvarjanje objektov PointToPointNetDevices in njihovo povezovanje z uporabo objekta PointToPointChannel. Tako kot smo uporabili pomožni objekt NodeContainer za ustvarjanje vozlov, bomo zaprosili PointToPointHelper da opravi delo, povezano z ustvarjanjem, konfiguracijo in nastavitvijo naših naprav. Potrebovali bomo seznam vseh ustvarjenih objektov NetDevice, zato uporabimo NetDeviceContainer za njihovo skladiščenje tako kot smo uporabili NodeContainer za shranjevanje vozlišč, ki smo jih ustvarili. Naslednji dve vrstici kode,
NetDeviceContainer devices;
devices = pointToPoint.Install (nodes);zaključujeta nastavitev naprav in povezave. Prva vrstica deklarira zgoraj omenjeni vsebnik naprav, druga pa opravi glavno delo. Metoda Namestite objekta PointToPointHelper sprejema NodeContainer kot parameter. Znotraj NetDeviceContainer za vsako vozlišče v NodeContainer se ustvari (za točno dva mora biti povezava točka-točka) PointToPointNetDevice se ustvari in shrani v vsebniku naprav. PointToPointChannel se ustvari in ji priključita dve PointToPointNetDevices. Po ustvaritvi objektov se atributi, shranjeni v PointToPointHelper, uporabijo za inicializacijo ustreznih atributov v ustvarjenih objektih.
Po izvedbi klica pointToPoint.Install (nodes) bomo imeli dve vozlišči, vsako z nameščenim omrežnim uređajem 'točka-točka' in eno 'točka-točka' povezavo med njima. Obe napravi bosta nastavljeni za prenos podatkov s hitrostjo pet megabitov na sekundo z zakasnitev prenosa po povezavi dveh milisekund.
InternetStackHelper
Sedaj imamo nastavljena vozlišča in naprave, vendar naši vozlišča nimajo nameščenih protokolskih skladov. Naslednji dve vrstici kode poskrbita za to.
InternetStackHelper stack;
stack.Install (nodes);InternetStackHelper — predstavlja topološkega pomočnika za internetne skladov, podobno kot PointToPointHelper za dvo-točkovne omrežne naprave. Metoda Namestite sprejme NodeContainer kot parameter. Pri izvedbi bo namestila internetni sklad (TCP, UDP, IP itd.) na vsakem vozlišču v vsebniku.
Ipv4AddressHelper
Nato moramo povežeti naše naprave z IP naslovi. Nudimo topološkega pomočnika za upravljanje razdeljevanja IP naslovov. Edini vidni API za uporabnika je nastavitev osnovnega IP naslova in maske omrežja za uporabo pri dejanskem razdeljevanju naslovov (to se izvaja na nižji ravni v okviru pomočnika). Naslednji dve vrstici kode v našem primeru skripta first.cc,
Ipv4AddressHelper address;
address.SetBase ("10.1.1.0", "255.255.255.0");deklarirajo pomožni objekt naslova in mu naročijo, da začne dodeljevati IP-naslove iz omrežja 10.1.1.0, pri čemer za določitev uporabi bitno masko 255.255.255.0. Privzeto bodo dodeljeni naslovi začeli z enico in se monotono povečevali, zato bo prvi naslov, dodeljen iz te baze, 10.1.1.1, nato 10.1.1.2 itd. V resnici sistem ns‑3 na nizki ravni beleži vse dodeljene IP-naslove in generira usodno napako, če slučajno ustvarite situacijo, ko je isti naslov ustvarjen dvakrat (mimogrede, to napako je težko odpraviti).
Naslednja vrstica kode,
Ipv4InterfaceContainer interfaces = address.Assign (devices);izvaja dejansko dodelitev naslova. V ns‑3 vzpostavljamo povezavo med IP-naslovom in napravo z uporabo objekta Ipv4Interface. Tako kot občasno potrebujemo seznam omrežnih naprav, ki jih je ustvaril pomočnik za nadaljnjo uporabo, občasno potrebujemo tudi seznam objektov Ipv4Interface. Ipv4InterfaceContainer ponuja to funkcionalnost.
Zgradili smo omrežje točka-to-točka, z nameščenimi skladovnimi in dodeljenimi IP-naslovi. Zdaj potrebujemo v vsakem vozlišču aplikacijo za generiranje prometa.
4.2.7 Korišćenje aplikacije (Application)
Še ena od osnovnih abstrakcij sistema ns‑3 je Aplikacija (aplikacija). V tem scenariju uporabljamo dve specializaciji osnovne klase Aplikacija ns‑3 z imenom UdpEchoServerApplication in UdpEchoClientApplication. Tako kot v prejšnjih primerih uporabljamo pomožne objekte za nastavitev in upravljanje osnovnih objektov. Tukaj uporabljamo UdpEchoServerHelper in UdpEchoClientHelperobjekte, da si olajšamo življenje.
UdpEchoServerHelper
Naslednje vrstice kode v našem primeru skripta first.cc, se uporabljajo za nastavitev aplikacije UDP echo strežnika 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 odlomku ustvari UdpEchoServerHelper. Kot običajno, to ni le aplikacija, temveč objekt, ki nam pomaga ustvarjati prave aplikacije. Ena od naših dogovorov je, da prenesemo potrebne atribute konstruktorju pomožnega objekta (asistenta). V tem primeru asistent ne more narediti nič koristnega, če mu ni na voljo številka vrat, na katerih bo strežnik pričakoval pakete, ta številka mora biti znana tudi stranki. V tem primeru prenašamo konstruktorju asistenta številko vrat. Konstruktor pa preprosto izvrši SetAttribute s preneseno vrednostjo. Kasneje, po želji, lahko z uporabo SetAttribute nastavite drugo vrednost atributa 'Port'.
Podobno kot mnogi drugi pomožni objekti, objekt UdpEchoServerHelper ima metodo Namestite. Izvedba te metode dejansko vodi do ustvarjanja osnovne aplikacije eho-strežnika in njene vezave na vozlišče. Zanimivo je, da metoda Namestite sprejema NodeContainter kot parameter, prav tako kot druge Namestite metode, ki smo jih videli.
Implicitna pretvorba C++, ki deluje tukaj, sprejme rezultat metode node.Get (1) (ki vrne pametni kazalec na objekt vozlišča — Ptr) in ga uporablja v konstruktorju anonimnega objekta NodeContainer, ki je nato prenesen metodi Namestite. Če v C++ kodi ne morete določiti, katera podpisna metoda se prevaja in izvaja, iščite med implicitnimi pretvorbami.
Zdaj vidimo, da echoServer.Install namerava namestiti aplikacijo UdpEchoServerApplication na najdenem v NodeContainer, ki ga uporabljamo za upravljanje naših vozlišč, vozlišče z indeksom 1. Metoda Namestite bo vrnila kontejner, ki vsebuje kazalce na vse aplikacije (v tem primeru eno, saj smo prenesli anonimni NodeContainer, ki vsebuje eno vozlišče), ki ga je ustvaril asistent.
Aplikacije morajo določiti trenutek začetka generiranja prometa 'start' in morda bo potrebno dodatno navesti čas, ko ga ustaviti 'stop'.Oba parametra zagotavljamo. Ta časi se nastavijo z metodami ApplicationContainer Začni in Ustavi. Te metode sprejemajo parametre tipa Vreme. V tem primeru uporabljamo eksplicitno zaporedje pretvorb C++, da vzamemo C++ double 1.0 in het object tns‑3 Time omzetten, wat gebruikmaakt van het object Seconds voor conversie naar seconden. Houd er rekening mee dat de conversieregels door de modelmaker kunnen worden beheerd en dat C++ zijn eigen regels heeft, dus je kunt er niet altijd op rekenen dat de parameters worden omgezet zoals je had verwacht. Twee regels,
serverApps.Start (Seconds (1.0));
serverApps.Stop (Seconds (10.0));zal ervoor zorgen dat de echo-server applicatie automatisch wordt gestart (ingeprobeerd) één seconde na het begin van de simulatie en na tien seconden simulatie stopt (uitgeschakeld). Aangezien we een simulatie-evenement hebben gedeclareerd (stop-evenement van de applicatie), dat na tien seconden zal worden uitgevoerd, zal er minstens tien seconden netwerktijd worden gesimuleerd.
UdpEchoClientHelper
De clientapplicatie echo wordt op een manier ingesteld die bijna identiek is aan die van de server. Er is een basiselement UdpEchoClientApplication, beheerd door
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));Echter, voor de echo-client moeten we vijf verschillende attributen instellen. De eerste twee attributen worden ingesteld tijdens de creatie UdpEchoClientHelper. We geven parameters door die (binnen de helper) worden gebruikt om attributen in te stellen "RemoteAddress" in "RemotePort" overeenkomstig onze afspraak over het doorgeven van de noodzakelijke parameters aan de constructor van de helper.
Laten we niet vergeten dat we hebben gebruikt Ipv4InterfaceContainer om IP-adressen bij te houden die we aan onze apparaten hebben toegewezen. Het nul-interface in de interfacecontainer komt overeen met het IP-adres van de nul-knooppunt in de knooppuntcontainer. De eerste interface in de interfacecontainer komt overeen met het IP-adres van de eerste knooppunt in de knooppuntcontainer. Dus, in de eerste regel van de code (bovenaan) creëren we de helper en vertellen we hem dat het externe adres van de client het IP-adres is dat is toegewezen aan de knooppunt waarop de server is. We geven ook aan dat we de pakketten naar poort negen moeten sturen.
Atribut «MaxPackets» obvešča odjemalca o največjem številu paketov, ki jih lahko pošljemo med simulacijo. Atribut «Interval» odjemalcu sporoča, kako dolgo naj čaka med paketi, in atribut «PacketSize» pove, kakšne velikosti naj bo uporabniški paket. S to kombinacijo atributov obveščamo odjemalca, da pošlje en paket velikosti 1024 bajtov.
Kot v primeru eho strežnika, nastavljamo atribute eho odjemalca, Začni in Ustavi, vendar tukaj zaženemo odjemalca sekundo po zagonu strežnika (dve sekundi po začetku simulacije).
4.2.8 Simulator
Na tej točki moramo zagnati simulacijo. To se izvede z globalno funkcijo Simulator::Run.
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));smo v resnici načrtovali dogodke v simulatorju za 1,0 sekunde, 2,0 sekunde in dva dogodka na 10,0 sekunde. Po klicu Simulator::Run, bo sistem začel pregledovati seznam načrtovanih dogodkov in jih izvajati. Najprej bo sprožil dogodek po 1,0 sekunde, kar aktivira aplikacijo eho strežnika (ta dogodek lahko posledično načrtuje še mnoge druge dogodke). Nato bo sprožil dogodek, načrtovan za t = 2,0 sekunde, ki bo zagnal aplikacijo eho odjemalca. Tudi ta dogodek lahko načrtuje še mnoge druge dogodke. Izvedba dogodka sprožitve v eho odjemalcu bo začela fazo prenosov podatkov simulacije, tako da bo poslala paket strežniku.
Akt pošiljanja paketa strežniku bo sprožil verigo dogodkov, ki bodo avtomatsko načrtovani v ozadju in realizirali mehaniko pošiljanja eho signalov glede na nastavitve sinhronizacije, ki smo jih nastavili v scenariju.
Kot rezultat, saj pošiljamo samo en paket (ne pozabite, da je atribut MaxPackets bil nastavljen na enoto), bo veriga dogodkov, ki jih sproži ta edini odjemalski eho zahtevek, končala in simulacija bo prešla v stanje čakanja. Ko se to zgodi, bodo preostali načrtovani dogodki dogodki Ustavi za strežnik in odjemalca. Ko se ti dogodki izvedejo, ne bo več dogodkov za obdelavo in Simulator::Run bo vrnilo nadzor. Modelliranje se konča.
Ostane samo, da pospravimo za seboj. To se izvede z klicem globalne funkcije Simulator::Destroy. Ker zaradi klicev pomožnih funkcij (ali nizkolegorskega kode ns‑3), ki so organizirane tako, da v simulator povežejo ključe za uničenje vseh ustvarjenih objektov. Ne potrebujete samostojno spremljati nobenega od teh objektov — vse, kar morate storiti, je, da pokličete Simulator::Destroy in izstopite. Sistem ns‑3 bo opravil to zahtevno nalogo namesto vas. Preostale vrstice našega prvega ns‑3 skripta, first.cc, to tudi počnejo:
Simulator::Destroy ();
return 0;
}Kdaj se simulator ustavi?
ns‑3 je simulator diskretnih dogodkov (DE). V tem simulatorju je vsak dogodek povezan s časom njegove izvedbe, simulacija pa se nadaljuje z obdelavo dogodkov v vrstnem redu njihovega nastanka med simulacijo. Dogodki lahko povzročijo načrtovanje prihodnjih dogodkov (na primer, časovnik se lahko ponovno načrtuje, da konča štetje v naslednjem intervalu).
Začetni dogodki običajno sproži objekt, na primer, IPv6 bo načrtoval določitev storitev v omrežju, zahteve za sosede itd. Aplikacija načrtuje prvi dogodek pošiljanja paketa itd. Ko se dogodek obdeluje, lahko ustvari nič, enega ali več dogodkov. Med izvajanjem simulacije se dogodki preprosto končajo ali ustvarjajo nove. Simulacija se bo samodejno ustavila, če je vrsta dogodkov prazna ali če se odkrije poseben dogodek Ustavi. Dogodek Ustavi se ustvari z metodo Simulator::Stop (ustavi čas).
Obstaja tipičen primer, ko je Simulator::Stop nujno potrebna za ustavitev simulacije: ko obstajajo samopodporni dogodki. Samopodporni (ali ponavljajoči) dogodki so dogodki, ki se vedno ponovno načrtujejo. Kot posledica tega vedno ohranjajo vrsto dogodkov neprazno. Obstaja veliko protokolov in modulov, ki vsebujejo ponavljajoče dogodke, na primer:
• FlowMonitor — periodično preverjanje izgubljenih paketov;
• RIPng — periodično pošiljanje posodobitev usmerjevalnih tabel;
• itd.
V takih primerih Simulator::Stop je nujno za pravilno ustavitev simulacije. Poleg tega, ko je ns‑3 v načinu emulacije, se uporablja RealtimeSimulator za usklajevanje ur simulacije s transportom ur stroja, in Simulator::Stop je potreben za ustavitev procesa.
Številni programi simulacije v učbeniku ne pokličejo Simulator::Stop Jasno, ker se avtomatsko končajo, ko se dogodki v vrsti izčrpajo. Vendar pa tePrograms tudi sprejmejo klic Simulator::Stop. Na primer, naslednji dodaten ukaz v prvem primeru programa načrtuje jasno ustavitev ob 11. sekundi:
+ Simulator::Stop (Seconds (11.0));
Simulator::Run ();
Simulator::Destroy ();
return 0;
}Zgoraj omenjeno dejansko ne bo spremenilo obnašanja tega programa, saj se to posebno simulacijo naravno konča po 10 sekundah. Če pa bi spremenili čas ustavitve v zgoraj navezanem ukazu s 11 sekund na 1 sekundo, boste opazili, da se simulacija ustavi, preden kateri koli izhod pride na ekran (saj izhod pride približno po 2 sekundah simulacijskega časa).
Pomembno je, da pokličete Simulator::Stop pred klicem Simulator::Run; v nasprotnem primeru Simulator::Run morda nikoli ne bo vrnil nadzora glavni programu za izpolnitev ustavitve!
4.2.9 Skupljanje vašeg scenarija
Ustvarjanje vaših preprostih skriptov smo naredili enostavno. Vse, kar morate storiti, je, da svoj skript postavite v imenik scratch, in bo samodejno zgrajen, če zaženete Waf. Poglejmo. Vrnite se v vrhnji imenik in kopirajte examples/tutorial/first.cc v imeniku scratch
$ cd ../..
$ cp examples/tutorial/first.cc scratch/myfirst.ccZdaj zgradite svoj prvi primer skripta, z uporabo waf:
$ ./wafMoral bi videti sporočila, da je vaš prvi primer uspešno ustvarjen.
Waf: Vstop v imenik `/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: Izhod iz imenika `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' uspešno končano (2.357s)Zdaj lahko zaženete primer (upoštevajte, da če program zgradite v imeniku scratch, ga morate tudi zagnati iz scratch):
$ ./waf --run scratch/myfirstMoral bi videti podoben izhod:
Waf: Vstop v imenik `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Izhod iz imenika `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' uspešno končano (0.418s) Poslano 1024 bajtov na 10.1.1.2
Prejeto 1024 bajtov z 10.1.1.1
Prejeto 1024 bajtov z 10.1.1.2Tukaj lahko vidite, da sistem gradnje preveri, ali je bila datoteka zgrajena, in jo nato zažene. Vidite, da zapis komponente na echo odjemalcu kaže, da je poslal en 1024-bajtni paket na echo strežnik 10.1.1.2. Prav tako lahko vidite zapis v dnevniku na echo strežniku, ki navaja, da je prejel 1024 byte od 10.1.1.1. Echo strežnik tiho ponovi paket in vidite v dnevniku echo odjemalca, da je prejel svoj paket nazaj s strežnika.
4.3 Izvorni kod ns-3
Zdaj, ko ste uporabili nekatere ns-3 pomočnike, se lahko pogledate nekaj izvornih kod, ki implementirajo to funkcionalnost. Najnovejši kodo lahko pregledate na našem spletni strežnik po naslednji povezavi: . Tam boste videli povzetek strani Mercurial za našo razvojno drevo ns-3. Na vrhu strani boste videli več povezav:
summary | shortlog | changelog | graph | tags | filesPojdite naprej in izberite povezavo na datoteke. Tako bo videti vrhnja raven večine naših repozitorijev:
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 | annotateNaši primeri skriptov so v imeniku examples. Če kliknete na primere, boste videli seznam podimenikov. Ena od datotek v podimeniku tutorial — first.cc. Če kliknete na first.cc boste videli kodo, ki ste jo pravkar preučili.
Izvorna koda se večinoma nahaja v imeniku src. Lahko si ogledate izvorno kodo tako, da kliknete na ime imenika ali na povezavo datoteke desno od imena direktorija. Če kliknete na imenik src, boste dobili seznam poddirektorijev src. Če nato kliknete na poddirektorij core, boste našli seznam datotek. Prva datoteka, ki jo boste videli (ob trenutnem pisanju tega priročnika) — abort.h. Če kliknete na povezavo abort.h, vas bo to preusmerilo na izvorno datoteko za abort.h, ki vsebuje uporabne makroje za izhod iz skript, če so odkrite nenormalne razmere. Izvorna koda za pomočnike, ki smo jih uporabili v tem poglavju, se nahaja v imeniku src/Applications/helper. Ne oklevajte in raziskujte drevo imenikov, da bi razumeli, kaj je kje in da se seznanite s stilom programiranja ns‑3.
Izvor: habr.com
