Udhëzues për simulatorin e rrjetit ns-3. Kapitulli 4

Udhëzues për simulatorin e rrjetit ns-3. Kapitulli 4
kapitulli 1,2
kapitulli 3

4 Vështrim i përgjithshëm i konceptit
4.1 Abstraksionet kryesore
4.1.1 Nyja
4.1.2 Aplikimi
4.1.3 Kanali
4.1.4 Pajisja Net
4.1.5 Asistentë topologjikë
4.2 Skripti i parë ns-3
4.2.1 Kodi i pllakës së bojlerit
4.2.2 Plug-in
4.2.3 ns3 hapësira e emrave
4.2.4 Regjistrimi
4.2.5 Funksioni kryesor
4.2.6 Përdorimi i asistentëve të topologjisë
4.2.7 Përdorimi i aplikacionit
4.2.8 Simulator
4.2.9 Ndërtimi i skenarit tuaj
4.3 ns-3 Kodi burimor

Kapitulli 4

Vështrim i përgjithshëm i konceptit

Gjëja e parë që duhet të bëjmë përpara se të fillojmë të mësojmë ose shkruajmë kodin ns-3 është të shpjegojmë disa koncepte bazë dhe abstraksione në sistem. Pjesa më e madhe e kësaj mund të duket e qartë për disa, por ne ju rekomandojmë të merrni kohë për të lexuar këtë seksion për t'u siguruar që po filloni me një themel të fortë.

4.1 Abstraksionet kryesore

Në këtë seksion, ne do të shikojmë disa terma që përdoren zakonisht në ueb, por që kanë një kuptim specifik në ns-3.

4.1.1 Nyja

Në zhargonin e Internetit, një pajisje kompjuterike që lidhet me një rrjet quhet host ose ndonjëherë një sistem fundor. Për shkak se ns-3 është një simulator rrjeti dhe jo një simulator interneti, ne nuk e përdorim qëllimisht termin host, pasi kjo është e lidhur ngushtë me internetin dhe protokollet e tij. Në vend të kësaj, ne përdorim një term më të përgjithshëm, të përdorur edhe nga simulatorë të tjerë, i cili e ka origjinën në teorinë e grafikut: nyja (nyjë).

Në ns-3, abstraksioni themelor i një pajisjeje llogaritëse quhet një nyje. Ky abstraksion përfaqësohet në C++ nga klasa Node. Klasa NodeNode (nyja) ofron metoda për manipulimin e paraqitjeve të pajisjeve kompjuterike në simulime.

Ju duhet të kuptoni Nyjë Si një kompjuter në të cilin shtoni funksionalitet. Do të shtoni gjëra të tilla si aplikacione, grupe protokollesh dhe karta periferike me drejtues që lejojnë kompjuterin të bëjë punë të dobishme. Ne përdorim të njëjtin model bazë në ns-3.

4.1.2 Aplikimi

Në përgjithësi, programet kompjuterike ndahen në dy klasa të gjera. Softueri i sistemit organizon burime të ndryshme kompjuterike si kujtesa, ciklet e procesorit, disku, rrjeti etj. sipas disa modeleve kompjuterike. Softueri i sistemit zakonisht nuk i përdor këto burime për të kryer detyra që përfitojnë drejtpërdrejt nga përdoruesi. Një përdorues zakonisht drejton një aplikacion për të arritur një qëllim specifik, i cili merr dhe përdor burime të kontrolluara nga softueri i sistemit.

Shpesh linja e ndarjes ndërmjet sistemit dhe softuerit aplikativ vizatohet në ndryshimet e nivelit të privilegjit që ndodhin në kurthe të sistemit operativ. ns-3 nuk ka koncept të vërtetë të një sistemi operativ dhe për rrjedhojë nuk ka koncept të niveleve të privilegjeve ose thirrjeve të sistemit. Megjithatë, ne kemi një ide për një aplikacion. Ashtu si në "botën reale" aplikacionet softuerike ekzekutohen në kompjuterë për të kryer detyra, aplikacionet ns-3 ekzekutohen në nyje ns-3 për të kontrolluar simulimet në botën e simuluar.

Në ns-3, abstraksioni bazë për një program përdoruesi që gjeneron disa aktivitete për modelim është një aplikacion. Ky abstraksion përfaqësohet në C++ nga klasa Application. Klasa Application ofron metoda për manipulimin e pamjeve të versionit tonë të aplikacioneve të nivelit të përdoruesit në simulime. Zhvilluesit pritet të specializojnë klasën Application në kuptimin e programimit të orientuar nga objekti për të krijuar aplikacione të reja. Në këtë tutorial, ne do të përdorim specializimet e klasës Application të quajtur Aplikimi UdpEchoClient и Aplikimi UdpEchoServer. Siç mund ta prisni, këto aplikacione përbëjnë një grup aplikacionesh klient/server që përdoren për të gjeneruar dhe jehonë paketat e rrjetit.

4.1.3 Kanali

Në botën reale, ju mund të lidhni një kompjuter me një rrjet. Shpesh mediat mbi të cilat transmetohen të dhënat në këto rrjete quhen kanale. Kur lidhni një kabllo Ethernet në një prizë muri, po e lidhni kompjuterin tuaj me një lidhje Ethernet. Në botën e simuluar ns-3, një nyje lidhet me një objekt që përfaqëson një kanal komunikimi. Këtu, abstraksioni bazë i nënrrjetit të komunikimit quhet kanal dhe përfaqësohet në C++ nga klasa Channel.

Klasë Kanali i Kanalit ofron metoda për menaxhimin e ndërveprimit të objekteve të nënrrjetit dhe lidhjen e nyjeve me to. Kanalet gjithashtu mund të specializohen nga zhvilluesit në kuptimin e programimit të orientuar nga objekti. Specializimi i kanalit mund të modelojë diçka aq të thjeshtë sa një tel. Një kanal i dedikuar gjithashtu mund të modelojë gjëra komplekse si një ndërprerës i madh Ethernet ose një hapësirë ​​tredimensionale plot me pengesa në rastin e rrjeteve pa tel.

Ne do të përdorim versione të specializuara të kanalit në këtë tutorial të quajtur CsmaChannelCsmaChannel, PointToPointChannelPointToPointChannel и Wifichannelnannelnannel. CsmaChannel, për shembull, modelon një version të një nënrrjeti komunikimi që zbaton një mjedis komunikimi me akses të shumëfishtë me sens transportues. Kjo na jep funksionalitet të ngjashëm me Ethernet.

4.1.4 Pajisja Net

Më parë, nëse dëshironi të lidhni një kompjuter me një rrjet, duhet të blini një kabllo rrjeti specifik dhe një pajisje harduerike të quajtur (në terminologjinë e PC-së) një kartë periferike që duhej instaluar në kompjuter. Nëse një kartë periferike zbatonte disa funksione rrjeti, ato quheshin kartat e ndërfaqes së rrjetit ose kartat e rrjetit. Sot, shumica e kompjuterëve vijnë me pajisje të integruara të ndërfaqes së rrjetit dhe nuk shihen nga përdoruesit si pajisje të veçanta.

Një kartë rrjeti nuk do të funksionojë pa një drejtues softueri që kontrollon harduerin e saj. Në Unix (ose Linux), një pjesë e pajisjeve periferike klasifikohet si pajisje. Pajisjet menaxhohen duke përdorur drejtuesit e pajisjes dhe pajisjet e rrjetit (NIC) menaxhohen duke përdorur drejtuesit e pajisjeve të rrjetit (drejtuesit e pajisjeve të rrjetit) dhe quhen kolektivisht pajisje rrjeti (pajisje neto). Në Unix dhe Linux, ju i referoheni pajisjeve të rrjetit me emra të tillë si eth0.

Në ns-3, abstraksioni i pajisjes së rrjetit mbulon si drejtuesin e softuerit ashtu edhe harduerin që modelohet. Në simulim, një pajisje rrjeti është "instaluar" në një nyje për ta lejuar atë të komunikojë me nyjet e tjera përmes kanaleve. Ashtu si një kompjuter i vërtetë, një nyje mund të lidhet me kanale të shumta përmes pajisjeve të shumta NetDevices.

Abstraksioni i rrjetit të një pajisjeje përfaqësohet në C++ nga klasa NetDevice. Klasa NetDevice ofron metoda për menaxhimin e lidhjeve me objektet Node dhe Channel; dhe mund të specializohet nga zhvilluesit në kuptimin e programimit të orientuar drejt objektit. Në këtë tutorial do të përdorim disa versione të specializuara të NetDevice të quajtura CsmaNetDevice, Pajisja PointToPointNet и Pajisje WifiNet. Ashtu si një përshtatës rrjeti Ethernet është krijuar për të punuar me një rrjet Ethernet, CsmaNetDevice projektuar për të punuar me CsmaChannel, Pajisja PointToPointNet projektuar për të punuar me PointToPointChannelDhe Pajisje WifiNet - projektuar për të punuar me të WifiChannel.

4.1.5 Asistentë topologjikë

Në një rrjet të vërtetë, do të gjeni kompjuterë pritës me karta rrjeti të shtuara (ose të integruara). Në ns-3 do të thoshim se do të shihni nyje me NetDevices të bashkangjitur. Në një rrjet të madh të simuluar, do t'ju duhet të organizoni lidhje midis shumë objekteve Nyjë, NetDevice и kanal.

Që nga lidhja e NetDevices me nyjet, NetDevices me lidhjet, caktimi i adresave IP, etj. në ns-3 janë një detyrë e zakonshme, për ta bërë këtë sa më të lehtë që të jetë e mundur ne ofrojmë të ashtuquajturat ndihmës të topologjisë. Për shembull, për të krijuar një NetDevice, ju duhet të kryeni shumë operacione të kernelit NS-3, të shtoni një adresë MAC, të instaloni pajisjen e rrjetit në nyje, të konfiguroni pirgun e protokollit të nyjes dhe pastaj të lidhni NetDevice me kanalin. Do të kërkohet edhe më shumë punë për të lidhur pajisje të shumta me lidhjet e shumëfishta dhe më pas të lidhni rrjetet individuale në një rrjet të Internetworks. Ne ofrojmë objekte ndihmëse të topologjisë që kombinojnë këto shumë operacione në një model të lehtë për t'u përdorur për lehtësinë tuaj.

4.2 Skripti i parë ns-3

Nëse e keni instaluar sistemin siç sugjerohet më sipër, do të keni lëshimin ns-3 në një drejtori të quajtur repos në direktorinë tuaj kryesore. Shkoni te drejtoria lirimin

Nëse nuk keni një direktori të tillë, kjo do të thotë që nuk e keni specifikuar drejtorinë e daljes kur ndërtoni versionin e lëshimit të NS-3, ndërtoni si kjo:
$ ./waf configure —build-profile=release —out=build/release,
$ ./waf ndërtuar

aty duhet të shihni një strukturë drejtorie të ngjashme me sa vijon:

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

Shkoni te drejtoria shembuj/tutorial. Ju duhet të shihni një skedar të vendosur atje të quajtur së pari.cc. Ky është një skript që do të krijojë një lidhje të thjeshtë pikë-për-pikë midis dy nyjeve dhe do të transmetojë një paketë midis nyjeve. Le ta shohim këtë skript rresht pas rreshti; për ta bërë këtë, hapni first.cc në redaktorin tuaj të preferuar.

4.2.1 Kodi i pllakës së bojlerit
Rreshti i parë në skedar është linja e modalitetit të redaktuesit Emacs. Ai i tregon emacs për konventat e formatimit (stili i kodimit) që përdorim në kodin tonë burimor.

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

Kjo është gjithmonë një çështje mjaft e diskutueshme, kështu që ne duhet të vendosim rekordin drejt për ta hequr atë menjëherë. Projekti ns-3, si shumica e projekteve të mëdha, ka adoptuar një stil kodimi me të cilin duhet të përputhen të gjithë kodet e kontribuar. Nëse dëshironi të kontribuoni kodin tuaj në projekt, përfundimisht do t'ju duhet të përputheni me standardin e kodimit ns-3, siç përshkruhet në skedar doc/codingstd.txt ose treguar në faqen e internetit të projektit: https://www.nsnam.org/develop/contributing-code/coding-style/.

Ne ju rekomandojmë që të mësoheni me pamjen dhe ndjesinë e kodit ns-3 dhe ta zbatoni këtë standard sa herë që punoni me kodin tonë. I gjithë ekipi i zhvillimit dhe kontribuesit ranë dakord për këtë pas disa ankesave. Linja e modalitetit emacs më sipër e bën të lehtë formatimin e saktë nëse jeni duke përdorur redaktuesin emacs.

Simulatori ns-3 është i licencuar duke përdorur Leje e Përgjithshme Publike GNU. Ju do të shihni titullin e duhur ligjor GNU në çdo skedar shpërndarjeje ns-3. Shpesh do të shihni një njoftim për të drejtën e autorit për një nga institucionet pjesëmarrëse në projektin ns-3 mbi tekstin dhe autorin e GPL, të paraqitur më poshtë.

/* 
* 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-in

Vetë kodi fillon me një sërë deklaratash përfshirjeje (përfshin).

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

Për të ndihmuar përdoruesit tanë të skriptimit të nivelit të lartë të përballen me numrin e madh të skedarëve të titullit të pranishëm në sistem, ne i grupojmë ato sipas përdorimit të tyre në module të mëdha. Ne ofrojmë një skedar të vetëm kokë që do të ngarkojë në mënyrë rekursive të gjithë skedarët e titullit të përdorur në një modul të caktuar. Në vend që të kërkoni saktësisht se çfarë titulli ju nevojitet dhe ndoshta të merrni listën e saktë të varësive, ne ju japim mundësinë për të shkarkuar një grup skedarësh në shkallë të madhe. Nuk është qasja më efikase, por sigurisht që e bën shumë më të lehtë shkrimin e skenarëve.

Secili prej skedarëve të përfshirë ns-3 vendoset në një direktori të emërtuar ns3 (ndërtoni nëndrejtori) për të shmangur konfliktet e emrit të skedarit gjatë procesit të ndërtimit. Skedari ns3/core-module.h korrespondon me modulin ns-3, të cilin do ta gjeni në direktori src/core Në lëshimin e instaluar. Në listën e kësaj drejtorie do të gjeni një numër të madh skedarësh të titullit. Kur e bëni asamblenë, WAF vendos skedarët e titullit publik në drejtorinë ns3 në një nëndrejtori ndërtoj/debug

Nëse nuk keni një direktori të tillë, kjo do të thotë që nuk e keni specifikuar drejtorinë e daljes kur ndërtoni versionin e lëshimit të NS-3, ndërtoni si kjo:
$ ./waf configure --build-profile=debug --out=build/debug
$ ./waf ndërtuar
ose
$ ./waf configure --build-profile=optimized --out=build/optimized
$ ./waf ndërtuar

ose ndërtuar/optimizuar, në varësi të konfigurimit tuaj. WAF gjithashtu do të gjenerojë automatikisht një skedar të përfshirë në modul për të ngarkuar të gjithë skedarët e kokës publike. Meqenëse sigurisht që po e ndiqni këtë udhëzues nga ana fetare, tashmë e keni bërë

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

për të konfiguruar projektin për të ekzekutuar ndërtime të korrigjimit që përfshijnë shembuj dhe teste. Ju gjithashtu keni bërë

$ ./waf

Për të mbledhur projektin. Pra, tani kur shikoni në drejtori ../../build/debug/ns3, më pas aty do të gjeni, ndër të tjera, skedarët e kokës së katër moduleve të paraqitura më sipër. Mund të shikoni përmbajtjen e këtyre skedarëve dhe të zbuloni se ato përfshijnë të gjithë skedarët publikë të përdorur nga modulet përkatëse.

4.2.3 ns3 hapësira e emrave

Rreshti tjetër në skenar së pari.cc është një deklaratë e hapësirës së emrit.

using namespace ns3;

Projekti ns-3 zbatohet në një hapësirë ​​emri C++ të quajtur ns3. Kjo grupon të gjitha deklaratat e lidhura me ns-3 në një fushë jashtë hapësirës globale të emrave, e cila shpresojmë se do të ndihmojë në integrimin me kode të tjera. Përdorimi i operatorit C++ prezanton hapësirën e emrave ns-3 në rajonin aktual (global) deklarativ. Kjo është një mënyrë fantastike për të thënë se pas kësaj deklarate, nuk do t'ju duhet të shkruani operatorin e lejes ns3::scope përpara të gjithë kodit tuaj ns-3 për ta përdorur atë. Nëse nuk jeni të njohur me hapësirat e emrave, referojuni pothuajse çdo teksti shkollor C++ dhe krahasoni hapësirën e emrave ns3 duke përdorur hapësirën e emrave std dhe deklaratën using namespace std; në shembujt e punës me operatorin e daljes kosto dhe përrenj.

4.2.4 Regjistrimi

Rreshti tjetër i skenarit është:

NS_LOG_COMPONENT_DEFINE ("FirstScriptExample");

Ne do ta përdorim këtë deklaratë si një vend të përshtatshëm për të diskutuar sistemin tonë të dokumentacionit Oksigjeni. Nëse shikoni faqen e internetit të projektit ns-3, do të gjeni një lidhje Dokumentacioni në shiritin e navigimit. Nëse klikoni këtë lidhje, do të çoheni në faqen tonë të dokumentacionit. Ekziston një lidhje "Latest Release" që do t'ju çojë te dokumentacioni për versionin më të fundit të qëndrueshëm të ns-3. Nëse zgjidhni lidhjen "API Documentation", do të çoheni në faqen e dokumentacionit ns-3 API.

Në anën e majtë të faqes do të gjeni një paraqitje grafike të strukturës së dokumentacionit. Një vend i mirë për të filluar është "libri" i Modules ns-3 në pemën e navigimit ns-3. Nëse zbuloni Modulet, do të shihni një listë të dokumentacionit të moduleve ns-3. Siç u diskutua më lart, koncepti i një moduli këtu lidhet drejtpërdrejt me skedarët e përfshirë në modulin e mësipërm. Nënsistemi i regjistrimit ns-3 është diskutuar në seksion Duke përdorur modulin e Regjistrimit, kështu që ne do të kthehemi tek ajo më vonë në këtë tutorial, por ju mund të mësoni rreth deklaratës së mësipërme duke parë modulin Bërthamëdhe më pas hapja e librit Mjetet e debugimitdhe më pas duke zgjedhur faqen Prerje-transportim trupash. Klikoni mbi Prerje-transportim trupash.

Tani duhet të rishikoni dokumentacionin Oksigjeni për modul Prerje-transportim trupash. Në listën e makrove në krye të faqes, do të shihni një hyrje për NS_LOG_COMPONENT_DEFINE. Përpara se të klikoni lidhjen, sigurohuni që të shikoni "Përshkrimin e Detajuar" të modulit të regjistrimit për të kuptuar se si funksionon në përgjithësi. Për ta bërë këtë, mund të lëvizni poshtë ose të zgjidhni "Më shumë..." poshtë grafikut.

Pasi të keni një ide të përgjithshme se çfarë po ndodh, shkoni përpara dhe shikoni dokumentacionin për NS_LOG_COMPONENT_DEFINE specifike. Nuk do ta kopjoj dokumentacionin këtu, por për ta përmbledhur, kjo linjë deklaron një komponent regjistrimi të quajtur Shembull FirstScript, i cili ju lejon të aktivizoni ose çaktivizoni regjistrimin e mesazheve në konsolë duke iu referuar një emri.

4.2.5 Funksioni kryesor

Në rreshtat e mëposhtëm të skenarit do të shihni,

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

Kjo është thjesht një deklaratë e funksionit kryesor të programit tuaj (skriptit). Ashtu si me çdo program C++, ju duhet të përcaktoni një funksion kryesor, ky ekzekutohet së pari. Nuk ka asgjë të veçantë këtu. Skripti juaj ns-3 është thjesht një program C++. Rreshti i mëposhtëm vendos rezolucionin e kohës në 1 nanosekondë, që është parazgjedhja:

Time::SetResolution (Time::NS);

Rezolucioni i kohës, ose thjesht rezolucioni, është vlera më e vogël kohore që mund të përdoret (diferenca më e vogël e përfaqësueshme midis dy kohëve). Ju mund ta ndryshoni rezolucionin saktësisht një herë. Mekanizmi që ofron këtë fleksibilitet konsumon kujtesën, kështu që pasi të vendoset qartë rezolucioni, ne e çlirojmë kujtesën, duke parandaluar përditësimet e mëtejshme. (Nëse nuk e vendosni rezolucionin në mënyrë eksplicite, ajo do të jetë e paracaktuar në një nanosekondë dhe kujtesa do të lirohet kur të fillojë simulimi.)

Dy linjat e mëposhtme të skriptit përdoren për të mundësuar dy komponentë të regjistrimit që janë të integruara në aplikacione EchoClient и EchoServer:

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

Nëse lexoni dokumentacionin për komponentin Logging, do të shihni se ka disa nivele të logimit/granularitetit që mund t'i aktivizoni në secilin komponent. Këto dy rreshta kodi mundësojnë regjistrimin e korrigjimit në nivelin INFO për klientët dhe serverët echo. Në këtë nivel, aplikacioni do të printojë mesazhe ndërsa dërgon dhe merr pako gjatë simulimit.

Tani do të zbresim në biznesin e krijimit të topologjisë dhe ekzekutimit të simulimit. Ne përdorim objekte ndihmëse të topologjisë për ta bërë këtë punë sa më të lehtë.

4.2.6 Përdorimi i asistentëve të topologjisë

Dy rreshtat e ardhshëm të kodit në skriptin tonë do të krijojnë në fakt objektet Node ns-3 që do të përfaqësojnë kompjuterët në simulim.

NodeContainer nodes;
nodes.Create (2);

Përpara se të vazhdojmë, le të gjejmë dokumentacionin për klasën NodeContainer. Një mënyrë tjetër për të arritur te dokumentacioni për një klasë të caktuar është përmes skedës Klasat në faqet Oksigjeni. Nëse tashmë e keni hapur Doxygen, thjesht lëvizni lart në krye të faqes dhe zgjidhni skedën Klasat. Ju duhet të shihni një grup të ri skedash, njëra prej të cilave është një listë klasash. Nën këtë skedë do të shihni një listë të të gjitha klasave ns-3. Lëvizni poshtë te ns3::NodeContainer. Kur të gjeni një klasë, zgjidhni atë për të shkuar te dokumentacioni për klasën.

Siç e kujtojmë, një nga abstraksionet tona kryesore është nyja. Ai përfaqëson kompjuterin në të cilin do të shtojmë gjëra të tilla si pirgjet e protokollit, aplikacionet dhe kartat periferike. Asistent i topologjisë NodeContainer ofron një mënyrë të përshtatshme për të krijuar, menaxhuar dhe aksesuar çdo objekt Nyjë, të cilën ne krijojmë për të ekzekutuar simulimin. Rreshti i parë më lart thjesht deklaron NodeContainer, të cilat i quajmë nyje. Rreshti i dytë thërret metodën Create në objektin e nyjeve dhe i kërkon kontejnerit të krijojë dy nyje. Siç përshkruhet në Oksigjeni, kontejneri kërkon që sistemi ns-3 të krijojë dy objekte Nyjë dhe ruan treguesit për këto objekte brenda.

Nyjet e krijuara në skript ende nuk bëjnë asgjë. Hapi tjetër në ndërtimin e topologjisë është lidhja e nyjeve tona me rrjetin. Forma më e thjeshtë e rrjetit që ne mbështesim është një lidhje pikë-për-pikë midis dy nyjeve. Tani do të krijojmë një lidhje të tillë.

PointToPointHelper

Ne krijojmë një lidhje pikë-për-pikë duke përdorur një model të njohur, duke përdorur një objekt ndihmës të topologjisë për të kryer punën e nivelit të ulët të kërkuar për lidhjen. Kujtoni se dy abstraksionet tona kryesore NetDevice и kanal. Në botën reale, këto terma përafërsisht korrespondojnë me kartat periferike dhe kabllot e rrjetit. Në mënyrë tipike, këto dy gjëra janë të lidhura ngushtë me njëra-tjetrën dhe askush nuk mund të llogarisë në ndarjen, për shembull, pajisjet Ethernet mbi një kanal me valë. Ndihmësit tanë të topologjisë ndjekin këtë marrëdhënie të ngushtë dhe për këtë arsye ju do të përdorni një objekt të vetëm në këtë skenar PointToPointHelper për vendosjen dhe lidhjen e objekteve ns-3 Pajisja PointToPointNet и PointToPointChannel. Tre rreshtat e ardhshëm në skenar:

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

Linja e parë,

PointToPointHelper pointToPoint;

krijon një shembull të një objekti në pirg PointToPointHelper. Nga pikëpamja e nivelit të lartë, vija e mëposhtme,

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

tregon objektin PointToPointHelper përdorni vlerën "5 Mbit/s" (pesë megabit për sekondë) si "Norma e të Dhënave'.

Nga një këndvështrim më specifik, vargu "DataRate" korrespondon me atë që ne e quajmë atribut Pajisja PointToPointNet. Nëse shikoni Oksigjeni për klasën ns3 :: pointopointnetDevice dhe në dokumentacionin për metodën GetTypeId do të gjeni një listë të atributeve të përcaktuara për pajisjen. Midis tyre do të jetë atributi "Norma e të Dhënave" Shumica e objekteve ns-3 të dukshme nga përdoruesi kanë lista të ngjashme të atributeve. Ne e përdorim këtë mekanizëm për të vendosur lehtësisht simulimin pa ripërpilim, siç do ta shihni në pjesën tjetër.

Të ngjashme me "Norma e të Dhënave" në PointToPointNetDevice, do të gjeni atributin "Vonesë" të lidhur me PointToPointChannel. Linja e fundit

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

говорит PointToPointHelper përdorni vlerën "2 ms" (dy milisekonda) si vlerën e vonesës së përhapjes për lidhjen pikë-pikë që krijon më pas.

NetDeviceContainer

Për momentin kemi në skenar NodeContainer, i cili përmban dy nyje. Ne kemi PointToPointHelper, e cila është e përgatitur për krijimin e objekteve Pajisjet PointToPointNet dhe duke i lidhur ato duke përdorur një objekt PointToPointChannel. Ashtu siç kemi përdorur objektin ndihmës të topologjisë NodeContainer për të krijuar nyje, do të pyesim PointToPointHelper kryejnë punë për ne në lidhje me krijimin, konfigurimin dhe instalimin e pajisjeve tona. Ne kemi nevojë për një listë të të gjitha objekteve të krijuara NetDevice, kështu që ne përdorim NetDeviceContainer Për t'i ruajtur ato në të njëjtën mënyrë që kemi përdorur NodeContainer për të ruajtur nyjet që kemi krijuar. Dy rreshtat e ardhshëm të kodit,

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

konfigurimi i plotë i pajisjes dhe kanalit. Rreshti i parë deklaron kontejnerin e pajisjes të përmendur më sipër, dhe i dyti bën punën kryesore. Metoda Instaloj Objekt PointToPointHelper merr NodeContainer si parametër. Brenda NetDeviceContainer për secilën nyje të vendosur në NodeContainer është krijuar (për komunikim pikë-për-pikë duhet të jenë saktësisht dy prej tyre) Pajisja PointToPointNet krijohet dhe ruhet në kontejnerin e pajisjes. PointToPointChannel krijohet dhe i bashkangjiten dy Pajisjet PointToPointNet. Pas krijimit të objekteve, atributet ruhen në PointToPointHelper, përdoren për të inicializuar atributet përkatëse në objektet e krijuara.

Pas kryerjes së një telefonate pointToPoint.Install (nyjet) do të kemi dy nyje, secila me një pajisje rrjeti pikë-për-pikë të instaluar dhe një lidhje pikë-për-pikë ndërmjet tyre. Të dy pajisjet do të konfigurohen për të transmetuar të dhëna me një shpejtësi prej pesë megabits për sekondë me një vonesë transmetimi prej dy milisekonda mbi kanalin.

InternetStackHelper

Tani kemi nyje dhe pajisje të konfiguruara, por nyjet tona nuk kanë të instaluar rafte protokolli. Dy rreshtat e ardhshëm të kodit do të kujdesen për këtë.

InternetStackHelper stack;
stack.Install (nodes);

InternetStackHelper - është një ndihmës i topologjisë për pirgjet e Internetit, i ngjashëm me PointToPointHelper për pajisjet e rrjetit pikë-për-pikë. Metoda Instaloj merr NodeContainer si parametër. Kur të ekzekutohet, do të instalojë pirgun e Internetit (TCP, UDP, IP, etj.) në çdo nyje kontejneri.

Ndihmësi i adresës IPv4

Pastaj ne duhet të lidhim pajisjet tona me adresat IP. Ne ofrojmë një asistent topologjie për të menaxhuar shpërndarjen e adresave IP. E vetmja API e dukshme për përdoruesin është vendosja e adresës IP bazë dhe maskës së rrjetit për t'u përdorur kur bëhet shpërndarja aktuale e adresës (kjo bëhet në një nivel më të ulët brenda ndihmësit). Dy rreshtat e ardhshëm të kodit në skenarin tonë të shembullit së pari.cc,

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

deklaroni objektin ndihmës të adresës dhe i tregoni se duhet të fillojë të ndajë adresat IP nga rrjeti 10.1.1.0, duke përdorur bitmaskën 255.255.255.0 për të përcaktuar. Si parazgjedhje, adresat e alokuara do të fillojnë në një dhe do të rriten në mënyrë monotone, kështu që adresa e parë e alokuar nga kjo bazë do të jetë 10.1.1.1, pastaj 10.1.1.2, etj. Në realitet, në një nivel të ulët, sistemi ns-3 kujton të gjitha adresat IP të alokuara dhe gjeneron një gabim fatal nëse aksidentalisht krijoni një situatë ku e njëjta adresë gjenerohet dy herë (nga rruga, ky gabim është i vështirë për tu korrigjuar).

Linja e mëposhtme e kodit,

Ipv4InterfaceContainer interfaces = address.Assign (devices);

kryen caktimin e adresës aktuale. Në ns-3 ne krijojmë një lidhje midis një adrese IP dhe një pajisjeje që përdor objektin Ndërfaqja IPv4. Ashtu si ndonjëherë na nevojitet një listë e pajisjeve të rrjetit të krijuara nga asistenti për përdorim të mëvonshëm, ndonjëherë na duhet një listë e objekteve Ndërfaqja IPv4. IPv4InterfaceContainer ofron këtë funksionalitet.

Ne ndërtuam një rrjet pikë-për-pikë, me rafte të instaluara dhe adresa IP të caktuara. Tani na duhen aplikacione në secilën nyje për të gjeneruar trafik.

4.2.7 Përdorimi i aplikacionit

Një tjetër nga abstraksionet kryesore të sistemit ns-3 është Aplikacion (aplikacion). Në këtë skenar ne po përdorim dy specializime të klasës bazë Aplikacion ns-3 thirrur Aplikimi UdpEchoServer и Aplikimi UdpEchoClient. Si në rastet e mëparshme, ne përdorim objekte ndihmëse për të konfiguruar dhe menaxhuar objektet bazë. Këtu përdorim UdpEchoServerHelper и UdpEchoClientHelper objekte për ta bërë jetën tonë më të lehtë.

UdpEchoServerHelper

Linjat e mëposhtme të kodit në skriptin tonë të shembullit first.cc përdoren për të konfiguruar një aplikacion të serverit echo UDP në një nga nyjet që krijuam më parë.

UdpEchoServerHelper echoServer (9);

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

Rreshti i parë i kodit në fragmentin e mësipërm krijon UdpEchoServerHelper. Si zakonisht, ky nuk është një aplikacion në vetvete, është një objekt që na ndihmon të krijojmë aplikacione reale. Një nga konventat tona është t'ia kalojmë atributet e kërkuara konstruktorit të objektit ndihmës. Në këtë rast, ndihmësi nuk mund të bëjë asgjë të dobishme nëse nuk i jepet numri i portit në të cilin serveri do të dëgjojë për paketat, ky numër duhet të jetë i njohur edhe për klientin. Në këtë rast, ne ia kalojmë numrin e portit konstruktorit ndihmës. Konstruktori, nga ana tjetër, thjesht e bën SetAttribute me vlerën e kaluar. Më vonë, nëse dëshironi, mund të përdorni SetAttribute për të vendosur një vlerë të ndryshme për atributin Port.

Si shumë objekte të tjera ndihmëse, objekti UdpEchoServerHelper ka një metodë Instaloj. Ekzekutimi i kësaj metode krijon në mënyrë efektive një aplikacion bazë të serverit echo dhe e lidh atë me hostin. Interesante, metoda Instaloj merr NodeContainer si parametër ashtu si të tjerët Instaloj metodat që kemi parë.

Konvertimi i nënkuptuar i C++ që funksionon këtu merr rezultatin e metodës nyja. Merr (1) (i cili kthen një tregues inteligjent në objektin e nyjës - Ptr ) dhe e përdor atë në konstruktorin për objektin anonim NodeContainere cila më pas kalohet në metodë Instaloj. Nëse nuk mund të përcaktoni në kodin C++ se cila nënshkrim metodë kompilohet dhe ekzekutohet, atëherë shikoni ndër konvertimet e nënkuptuara.

Tani e shohim atë echoServer.Instalo gati për të instaluar aplikacionin Aplikimi UdpEchoServer më gjendet në NodeContainertë cilën e përdorim për të menaxhuar nyjet tona, nyja me indeks 1. Metoda Instaloj do të kthejë një kontejner që përmban tregues për të gjitha aplikacionet (në këtë rast një, pasi kaluam një anonim NodeContainer, që përmban një nyje) të krijuar nga ndihmësi.

Aplikacionet duhet të specifikojnë se kur të fillojë gjenerimi i trafikut "fillo" dhe mund të duhet të specifikojë gjithashtu një kohë kur duhet ta ndalojë atë "ndal". Ne ofrojmë të dyja opsionet. Këto kohë caktohen duke përdorur metodat ApplicationContainer fillim и Stop. Këto metoda pranojnë parametrat e llojit kohë. Në këtë rast ne përdorim një sekuencë eksplicite të konvertimeve C++ për të marrë C++ dyfishtë 1.0 dhe konvertojeni atë në një objekt tns-3 Time që përdor objektin Sekonda për ta kthyer në sekonda. Mos harroni se rregullat e konvertimit mund të kontrollohen nga autori i modelit, dhe C ++ ka rregullat e veta, kështu që ju nuk mund të mbështeteni gjithmonë në parametrat që shndërrohen në mënyrën si e prisnit. Dy rreshta

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

do të bëjë që aplikacioni i serverit echo të fillojë (ndizet automatikisht) një sekondë pas fillimit të simulimit dhe të ndalojë (fiket) pas dhjetë sekondash të simulimit. Për shkak të faktit se kemi deklaruar një ngjarje simulimi (ngjarje e ndalimit të aplikacionit), e cila do të ekzekutohet në dhjetë sekonda, do të simulohen të paktën dhjetë sekonda të funksionimit të rrjetit.

UdpEchoClientHelper

Aplikimi Klient humbas konfiguruar në një mënyrë pothuajse të ngjashme me serverin. Ekziston një objekt bazë Aplikimi UdpEchoClient, e cila kontrollohet
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));;

Megjithatë, për klientin echo ne duhet të vendosim pesë atribute të ndryshme. Dy atributet e para vendosen në kohën e krijimit UdpEchoClientHelper. Ne kalojmë parametrat që përdoren (brenda ndihmësit) për të vendosur atributet "Adresa në distancë" и "RemotePort" në përputhje me marrëveshjen tonë për të kaluar parametrat e nevojshëm te konstruktori ndihmës.

Le të kujtojmë se kemi përdorur IPv4InterfaceContainer për të gjurmuar adresat IP që kemi caktuar në pajisjet tona. Ndërfaqja null në kontejnerin e ndërfaqeve do të korrespondojë me adresën IP të nyjes null në kontejnerin e nyjeve. Ndërfaqja e parë në kontejnerin e ndërfaqes korrespondon me adresën IP të nyjës së parë në kontejnerin e nyjeve. Pra, në rreshtin e parë të kodit (sipër), ne krijojmë një ndihmës dhe i themi se adresa në distancë e klientit do të jetë adresa IP e caktuar për hostin ku ndodhet serveri. Ne gjithashtu themi se duhet të organizojmë që paketat të dërgohen në portin nëntë.

Atributi "MaxPackets" i tregon klientit numrin maksimal të paketave që mund të dërgojmë gjatë simulimit. Atributi "Interval" i tregon klientit se sa kohë duhet të presë midis paketave dhe atributi "PacketSize" i tregon klientit se sa e madhe duhet të jetë ngarkesa e paketës. Me këtë kombinim të atributeve, ne i themi klientit të dërgojë një paketë të vetme 1024 byte.

Ashtu si me serverin echo, ne vendosim atributet e klientit echo fillim и Stop, por këtu e nisim klientin një sekondë pasi serveri është ndezur (dy sekonda pas fillimit të simulimit).

4.2.8 Simulator

Në këtë pikë duhet të ekzekutojmë simulimin. Kjo bëhet duke përdorur funksionin global Simulator::Run.

Simulator::Run ();

Kur më parë kemi quajtur metoda,

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

ne faktikisht kemi planifikuar ngjarje në simulator në 1,0 sekonda, 2,0 sekonda dhe dy ngjarje në 10,0 sekonda. Pas thirrjes Simulator::Run, sistemi do të fillojë të shikojë listën e ngjarjeve të planifikuara dhe t'i ekzekutojë ato. Fillimisht do të ndezë një ngjarje pas 1,0 sekondash, e cila do të aktivizojë aplikacionin e serverit echo (kjo ngjarje mund të planifikojë shumë ngjarje të tjera). Më pas do të ndezë një ngjarje të planifikuar në t=2,0 sekonda e cila do të nisë aplikacionin e klientit echo. Përsëri, kjo ngjarje mund të ketë shumë ngjarje të tjera të planifikuara. Zbatimi i ngjarjes së fillimit në klientin echo do të fillojë fazën e transferimit të të dhënave të simulimit duke dërguar një paketë në server.

Akti i dërgimit të një pakete në server do të shkaktojë një zinxhir ngjarjesh që do të planifikohen automatikisht në prapaskenë dhe që do të zbatojnë mekanikën e dërgimit të një pakete echo sipas parametrave të kohës që kemi vendosur në skenar.

Si rezultat, meqenëse po dërgojmë vetëm një pako (mbani mend, atributin MaxPackets ishte vendosur në një), zinxhiri i ngjarjeve të iniciuara nga ky ping i vetëm i klientit do të përfundojë dhe simulimi do të kalojë në modalitetin e gatishmërisë. Pasi të ndodhë kjo, ngjarjet e mbetura të planifikuara do të jenë ngjarjet Stop për serverin dhe klientin. Kur këto ngjarje të ekzekutohen, nuk do të mbetet asnjë ngjarje për përpunim të mëtejshëm dhe Simulator::Run do të kthejë kontrollin. Simulimi është i plotë.

Gjithçka që mbetet është të pastroni veten. Kjo bëhet duke thirrur funksionin global Simulator :: Shkatërroni. Sepse u thirrën funksionet ndihmëse (ose kodi ns-3 i nivelit të ulët), të cilët janë organizuar në mënyrë që grepa janë futur në simulator për të shkatërruar të gjitha objektet që janë krijuar. Nuk kishit nevojë të gjurmoni vetë asnjë nga këto objekte - gjithçka që duhej të bënit ishte të telefononi Simulator :: Shkatërroni dhe dil jashtë. Sistemi NS-3 do ta bëjë këtë punë të vështirë për ju. Linjat e mbetura të skriptit tonë të parë ns-3, first.cc, bëjnë pikërisht këtë:

Simulator::Destroy ();
return 0;
}

Kur do të ndalojë simulatori?

NS-3 është një imitues i ngjarjes diskrete (DE). Në një imitues të tillë, çdo ngjarje shoqërohet me kohën e tij të ekzekutimit, dhe simulimi vazhdon duke përpunuar ngjarje sipas rendit që ato ndodhin ndërsa simulimi përparon. Ngjarjet mund të shkaktojnë planifikimin e ngjarjeve të ardhshme (për shembull, një kohëmatës mund të riplanifikojë veten për të përfunduar numërimin në intervalin tjetër).

Ngjarjet fillestare zakonisht iniciohen nga entiteti, për shembull IPv6 do të planifikojë zbulimin e shërbimeve në rrjet, kërkesat fqinje, etj. Aplikacioni planifikon ngjarjen e parë të dërgimit të paketës, e kështu me radhë. Kur një ngjarje përpunohet, ajo mund të gjenerojë zero, një ose më shumë ngjarje. Ndërsa simulimi përparon, ndodhin ngjarje, ose duke përfunduar ose duke krijuar të reja. Simulimi do të ndalojë automatikisht nëse radha e ngjarjeve është bosh ose zbulohet një ngjarje e veçantë Stop. Ngjarja Stop gjeneruar nga funksioni Simulator::Stop (koha e ndalimit).

Ekziston një rast tipik ku Simulator::Stop është absolutisht i nevojshëm për të ndaluar simulimin: kur ka ngjarje të vetë-qëndrueshme. Ngjarjet e vetë-qëndrueshme (ose përsëritëse) janë ngjarje që riplanifikohen gjithmonë. Si pasojë, ata gjithmonë e mbajnë radhën e ngjarjeve jo bosh. Ka shumë protokolle dhe module që përmbajnë ngjarje të përsëritura, për shembull:

• FlowMonitor - kontroll periodik për paketa të humbura;

• RIPng – transmetim periodik i përditësimeve të tabelës së rrugëtimit;

• etj.

Në raste të tilla Simulator::Stop të nevojshme për të ndaluar simulimin në mënyrë korrekte. Për më tepër, kur ns-3 është në modalitetin emulues, RealtimeSimulator përdoret për të sinkronizuar orën e simulimit me orën e makinës, dhe Simulator::Stop të nevojshme për të ndaluar procesin.

Shumë nga programet e simulimit në tekstin shkollor nuk telefonojnë Simulator::Stop në mënyrë eksplicite, pasi ato përfundojnë automatikisht kur mbarojnë ngjarjet në radhë. Megjithatë, këto programe do të pranojnë gjithashtu thirrjen Simulator::Stop. Për shembull, deklarata e mëposhtme shtesë në programin e parë të shembullit do të planifikonte një ndalesë të qartë në 11 sekonda:

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

Sa më sipër nuk do të ndryshojë në fakt sjelljen e këtij programi, pasi ky simulim i veçantë përfundon natyrisht pas 10 sekondash. Por nëse do të ndryshonit kohën e ndalimit në deklaratën e mësipërme nga 11 sekonda në 1 sekondë, do të vini re se simulimi ndalet para se ndonjë dalje të godasë ekranin (pasi prodhimi ndodh pas rreth 2 sekondash të kohës së simulimit).

Është e rëndësishme të telefononi Simulator::Stop përpara se të telefononi Simulator::Run; përndryshe Simulator::Run mund të mos e kthejë kurrë kontrollin në programin kryesor për të ekzekutuar ndalimin!

4.2.9 Ndërtimi i skenarit tuaj

Ne e kemi bërë të parëndësishme krijimin e skripteve tuaja të thjeshta. E tëra çfarë ju duhet të bëni është të vendosni skriptin tuaj në direktorinë scratch dhe ai do të ndërtohet automatikisht nëse ekzekutoni WAF. Le te perpiqemi. Kthehuni në drejtorinë e nivelit të lartë dhe kopjoni shembuj/tutorial/i pari.cc te katalogu zeroja

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

Tani ndërtoni skenarin tuaj të parë të mostrës duke përdorur meshë:

$ ./waf

Ju duhet të shihni mesazhe që tregojnë se shembulli juaj i parë është krijuar me sukses.

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)

Tani mund të ekzekutoni shembullin (vini re se nëse e ndërtoni programin tuaj në drejtorinë scratch, atëherë duhet ta ekzekutoni nga zeroja):

$ ./waf --run scratch/myfirst

Ju duhet të shihni rezultate të ngjashme:

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

Këtu mund të shihni që sistemi i ndërtimit verifikon që skedari është ndërtuar dhe më pas e ekzekuton atë. Ju shikoni se hyrja e komponentit në klientin echo tregon se ai dërgoi një paketë të vetme 1024-byte në serverin echo 10.1.1.2. Ju gjithashtu shihni komponentin e regjistrimit në serverin echo për të thënë se ka marrë 1024 bajt nga 10.1.1.1. Serveri echo rishikon në heshtje paketën dhe ju mund të shihni në regjistrin e klientit echo që e ka marrë paketën e saj nga serveri.

4.3 ns-3 Kodi burimor

Tani që keni përdorur disa nga ndihmësit ns-3, mund t'i hidhni një sy disa prej kodit burimor që zbaton këtë funksionalitet. Kodi i fundit mund të shihet në serverin tonë të internetit në lidhjen e mëposhtme: https://gitlab.com/nsnam/ns-3-dev.git. Aty do të shihni faqen përmbledhëse të Mercurial për pemën tonë të zhvillimit ns-3. Në krye të faqes do të shihni disa lidhje,

summary | shortlog | changelog | graph | tags | files

Shkoni përpara dhe zgjidhni lidhjen e skedarëve. Kështu do të duket niveli më i lartë i shumicës së depove tona:

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

Shembujt tanë të skripteve janë në drejtori shembuj. Nëse klikoni mbi shembujt, do të shihni një listë me nëndrejtori. Një nga skedarët në nëndrejtori tutorial - së pari.cc. Nëse klikoni mbi së pari.cc do të shihni kodin që sapo mësuat.

Kodi burimor ndodhet kryesisht në drejtori src. Mund ta shikoni kodin burimor duke klikuar mbi emrin e drejtorisë ose duke klikuar në lidhjen e skedarëve në të djathtë të emrit të drejtorisë. Nëse klikoni në direktorinë src, do të merrni një listë të nëndirektorive src. Nëse më pas klikoni në nëndrejtorinë bazë, do të gjeni një listë skedarësh. Skedari i parë që do të shihni (në kohën e shkrimit të këtij udhëzuesi) është abort.h. Nëse klikoni në lidhje abort.h, do të dërgoheni te skedari burimor për abort.h, i cili përmban makro të dobishme për daljen nga skriptet nëse zbulohen kushte jonormale. Kodi burimor për ndihmësit që kemi përdorur në këtë kapitull mund të gjendet në drejtori src/Aplikacione/ndihmës. Mos ngurroni të kaloni nëpër pemën e drejtorive për të kuptuar se ku është dhe për të kuptuar stilin e programeve ns-3.

Burimi: www.habr.com

Shto një koment