
4 Rishikimi i konceptit
4.1 Abstraksionet kryesore
4.1.1 Nod (Nod)
4.1.2 Aplikacion (Aplikacion)
4.1.3 Kanal (Kanal)
4.1.4 Pajisje Rrjeti (Pajisje Rrjeti)
4.1.5 Ndihmësit topologjikë
4.2 Skripti i parë ns-3
4.2.1 Kodi themelor
4.2.2 Modulet e ngarkueshme
4.2.3 Hapësira e emrave ns3
4.2.4 Regjistrimi
4.2.5 Funksioni kryesor
4.2.6 Përdorimi i ndihmësve topologjikë
4.2.7 Përdorimi i Aplikacionit
4.2.8 Simulimi
4.2.9 Ndërtimi i skenarit tuaj
4.3 Kodi burimor ns-3
Kapitulli 4
Rishikimi i konceptit
E para që duhet të bëjmë para se të fillojmë të studiojmë ose të shkruajmë kodin ns-3 është të sqarojmë disa koncepte dhe abstraksione themelore në sistem. Shumë prej këtyre mund të duken të qarta për disa, por rekomandojmë të kaloni kohë duke lexuar këtë seksion për të siguruar që të filloni në një bazë solide.
4.1 Abstraksionet kryesore
Në këtë seksion do të shqyrtojmë disa terma që zakonisht përdoren në rrjet, por që kanë një kuptim të veçantë në ns-3.
4.1.1 Nod (Nod)
Në gjuhën internetore, një pajisje kompjuterike që lidhet me rrjetin quhet host ose ndonjëherë sistem përfundimtar. Sepse ns-3 është një simulator rrjeti dhe jo një simulator Interneti, ne qëllimisht nuk përdorim termin host, pasi ai është ngushtësisht i lidhur me Internetin dhe protokollet e tij. Në vend të kësaj, ne përdorim një term më të përgjithshëm, gjithashtu i përdorur nga simulatorë të tjerë, që ka origjinë në teorinë e grafëve — nod (ndod).
Në ns-3, abstraksioni bazë i pajisjes kompjuterike quhet nod. Ky abstraksion paraqitet në klasën C++ Node. Klasa NodeNode (nod) ofron metoda për të menaxhuar përfaqësimet e pajisjeve kompjuterike në simulimet.
Duhet të kuptoni Nyja si një kompjuter, të cilit do t'i shtoni funksionalitet. Do t'i shtoni gjëra si aplikacione, staketat e protokolleve dhe kartat për periferikë me drejtuese që lejojnë kompjuterin të kryejë punë të dobishme. Ne përdorim të njëjtën model themelore në ns-3.
4.1.2 Aplikacion (Aplikacion)
Zakonisht, softueri kompjuterik ndahet në dy klasat e gjera. Softueri sistemor organizon burime të ndryshme kompjuterike si memoria, ciklet e procesorit, disku, rrjeti, etj., në përputhje me një model llogaritës. Softueri sistemor zakonisht nuk i përdor këto burime për të kryer detyra që sjellin një dobi të drejtpërdrejtë për përdoruesin. Përdoruesi zakonisht nis një aplikacion për të arritur një qëllim të caktuar, i cili merr dhe përdor burimet e kontrolluara nga softueri sistemor.
Shpesh, linja e ndarjes midis softuerit sistemor dhe atij aplikativ bëhet kur ndryshon niveli i privilegjeve, që ndodh në grackat e sistemit operativ. Në ns‑3 nuk ka një koncept të vërtetë të sistemit operativ dhe për rrjedhojë nuk ka koncepte të niveleve të privilegjeve ose thirrjeve sistemore. Megjithatë, ne kemi idenë e aplikacionit. Ashtu si në "botën reale", për të kryer detyra, aplikacionet programore funksionojnë në kompjuterë, aplikacionet ns‑3 funksionojnë në nyjat ns‑3 për të menaxhuar simulimet në botën e simuluar.
Në ns‑3, abstraksioni bazë për programin e përdoruesit, i cili gjeneron ndonjë aktivitet për modelim, është aplikacioni. Kjo abstraksion paraqitet në C++ me klasën Application (aplikacion). Klasa Application ofron metoda për menaxhimin në simulime të pamjeve të versioneve tona të aplikacioneve të nivelit të përdoruesit. Pritet që zhvilluesit të specializojnë klasën Application duke u bazuar në programimin orientuar në objekte për të krijuar aplikacione të reja. Në këtë udhëzues, ne do të përdorim specializimet e klasës Application, të quajtura UdpEchoClientApplication dhe UdpEchoServerApplication. Siç pritej, këto aplikacione përbëjnë një grup aplikacionesh klient/servert që përdoren për të gjeneruar dhe simuluar paketa rrjeti.
4.1.3 Kanal (Kanal)
Në botën reale, mund të lidhen një kompjuter me rrjetin. Shpesh, ambientet përmes të cilave kalojnë të dhëna në këto rrjeta quhen kanale. Kur lidheni një kabll Ethernet me një prizë në mur, po lidhni kompjuterin me një kanal komunikimi Ethernet. Në botën e simuluar ns-3, një nyje lidhet me një objekt që paraqet një kanal komunikimi. Këtu, abstraksioni kryesor i nënrrjetit të komunikimit quhet kanal dhe përfaqësohet në C++ me klasën Channel (kanal).
Klasa ChannelChannel ofron metoda për të menaxhuar ndërveprimin e objekteve të nënrrjetit dhe për të lidhur nyjet 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 të thjeshtë si një tel. Një kanal i specializuar gjithashtu mund të modelojë gjëra komplekse si një switch Ethernet të madh ose një hapësirë tridimensionale të mbushur me pengesa në rastin e rrjeteve pa kabllo.
Në këtë udhëzues, do të përdorim versione të specializuara të kanaleve të quajtura CsmaChannelCsmaChannel, PointToPointChannelPointToPointChannel dhe WifiChannelWifiChannel. CsmaChannel, për shembull, modelon një version të nënrrjetit të komunikimit që implementon një ambient komunikimi me shumë qasje dhe kontroll të thirrjes. Kjo na jep funksionalitet të ngjashëm me Ethernet.
4.1.4 Pajisje Rrjeti (Pajisje Rrjeti)
Më parë, ishte ashtu që nëse donit të lidhni një kompjuter me rrjetin, duhej të blinit një kabllo të caktuar rrjeti dhe një pajisje harduerike të quajtur (në terminologjinë e PC-ve) pllaka periferi, e cila duhej të instalohej në kompjuter. Nëse në pllakën periferi ishin realizuar disa funksione rrjetesh, ato quheshin pllaka ndërfaqësimi rrjetesh ose karta rrjetesh. Sot, shumica e kompjuterëve vijnë me pajisje të integruara të ndërfaqësit rrjet, dhe përdoruesit nuk i shohin si pajisje të veçanta.
Një kartë rrjeti nuk do të funksionojë pa një drejtues programi që menaxhon pajisjen e saj. Në Unix (ose Linux), një pjesë e pajisjeve periferi klasifikohet si device. Pajisjet menaxhohen me ndihmën e drejtuesve të pajisjeve (device drivers), ndërsa pajisjet rrjetesh (NIC) menaxhohen duke përdorur drejtuesit e pajisjeve rrjetesh (network device drivers) dhe kanë një emërmbledhje të përbashkët pajisjet rrjetesh (net devices). Në Unix dhe Linux ju i qaseni pajisjeve rrjetërore me emra të tillë si p.sh. eth0.
Në ns-3, abstraksioni i pajisjes rrjetërore përfshin si drejtorin programor, ashtu edhe pajisjen e modeluar. Gjatë simulimit, pajisja rrjetërore "instalohet" në nyje, për t'i lejuar atij të lidhet me nyje të tjera përmes kanaleve. Ashtu si në një kompjuter të vërtetë, nyja mund të lidhet me disa kanale përmes disa pajisjeve. NetDevices.
Abstraksioni rrjetor i pajisjes përfaqësohet në C++ nga klasa NetDevice. Klasa NetDevice siguron metoda për menaxhimin e lidhjeve me objektet Node dhe Channel; dhe mund të specializohet nga zhvilluesit në kuptimin e programimit objekt-orientuar. Në këtë udhëzues ne do të përdorim disa versione të specializuara të NetDevice me emrat CsmaNetDevice, PointToPointNetDevice dhe WifiNetDevice. Po ashtu, siç adaptohet kartela rrjetërore Ethernet për të punuar me rrjetin Ethernet, CsmaNetDevice është e destinuar të punojë me CsmaChannel, PointToPointNetDevice është e destinuar të punojë me PointToPointChannel, ndërsa WifiNetDevice — është e destinuar të punojë me WifiChannel.
4.1.5 Ndihmësit topologjikë
Në një rrjet të vërtetë do të gjejmë kompjuterë të hostuar me kartela rrjetërore të shtuar (ose të integruara). Në ns-3 do të thonim se do të shihni nyje me NetDevices të lidhura. Në një rrjet të madh të modeluar, do t'ju duhet të organizoni lidhjet midis shumë objekteve. Nyja, NetDevice dhe Channel.
Duke marrë parasysh lidhjen e NetDevices me nyjet, NetDevices me kanale, caktimin e adresave IP, etj. në ns-3 janë detyra të zakonshme, për të bërë këtë sa më të thjeshtë, ne ofrojmë asistentë topologjike të njohur. Për shembull, për të krijuar një NetDevice nevojitet të kryhen shumë operacione thelbësore të ns-3, të shtoni një adresë MAC, të vendosni këtë pajisje rrjetërore në Node, të konfiguroni grumbullin e protokolleve të nyjës dhe më pas të lidhni NetDevice me Channel. Më shumë operacione do të jenë të nevojshme për të lidhur disa pajisje me kanale shumëpikëshe dhe më pas të lidhni rrjete të veçanta në një rrjet të bashkuar (Internetworks). Ne ofrojmë objekte ndihmëse të topologjisë që për lehtësinë tuaj bashkojnë këto shumë operacione në një model të lehtë për t'u përdorur.
4.2 Skripti i parë ns-3
Nëse keni instaluar sistemin, siç u rekomandua më sipër, do të keni një version të ns-3 në një direktori me emrin repos në direktorinë tuaj të shtëpisë. Shkoni në direktorinë release
Nëse nuk keni një direktori të tillë, kjo do të thotë se kur po ndërtonit versionin e lëshimit të ns-3 nuk keni specifikuar drejtorinë e daljes, kryeni ndërtimin si:
$ ./waf configure —build-profile=release —out=build/release,
$ ./waf build
aty duhet të shihni një strukturë direktorie që ngjason me këtë:
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.pycShkoni në direktorinë examples/tutorial. Duhet të shihni një skedar të vendosur aty me emrin first.cc. Ky është një skenar që do të krijojë një lidhje të thjeshtë pikë-pikë midis dy nyjave dhe do të Transferojë një paketë mes nyjave. Le të shikojmë këtë skenar rresht pas rreshti, për këtë do të hapim first.cc në redaktorin tuaj të preferuar.
4.2.1 Kodi themelor
Rreshti i parë në skedar është rreshti i modit të redaktorit emacs. Ai i thotë emacs mbi konventat e formatit (stili i kodimit) që ne do të përdorim në kodin tonë.
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */Ky është gjithmonë një çështje mjaft e diskutueshme, prandaj duhet të sqarojmë, që të heqim këtë menjëherë nga rruga. Projekti ns-3, ashtu si shumica e projekteve të mëdha, ka pranuar një stil kodimi që duhet të respektohet nga të gjithë kodet e dhëna. Nëse dëshironi të kontribuoni me kodin tuaj në projekt, në fund do t'ju duhet të respektoni standardin e kodimit ns-3, siç përshkruhet në skedarin doc/codingstd.txt ose të kotë në faqen e internetit të projektit: .
Ne rekomandojmë që të familiarizoheni me pamjen e kodit ns-3 dhe të aplikoni këtë standart sa herë që punoni me kodin tonë. E gjithë ekipi i zhvilluesve dhe kontribuesve është pajtuar me këtë pas një sërë diskutimesh. Rreshti i modit emacs, i dhënë më sipër, e thjeshton formatimin e duhur nëse përdorni editorin emacs.
Simuluesi ns-3 licencohet duke përdorur GNU General Public License. Do të shihni titullin përkatës juridik GNU në çdo skedar të shpërndarjes ns-3. Shpesh mund të shihni një njoftim për të drejtat e autorit për një nga institucionet pjesëmarrëse në projektin ns-3 mbi tekstin GPL dhe autorin, si 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 Modulet e ngarkueshme
Vërtet, kodi fillon me një seri operatorësh përfshirës (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"Për të ndihmuar përdoruesit tanë të skenarëve me nivel të lartë të përballen me numrin e madh të skedarëve të titujve që janë në sistem, ne i grumbullojmë ato sipas përdorimit të tyre në module të mëdha. Ne ofrojmë një skedar titulli që do të ngarkohet në mënyrë rekursive me të gjitha skedarët e titujve që përdoren në këtë modul. Në vend që të kërkoni se cili titull ju nevojitet dhe ndoshta të merrni listën e saktë të varësive, ne ju japim mundësinë të ngarkoni një grup skedarësh me një nivel të lartë detajesh. Ky nuk është qasja më e efektshme, por padyshim që e bën shkruarjen e skenarëve shumë më të lehtë.
Çdo një nga skedarët e përfshirë ns‑3 vendoset në një direktori me emrin ns3 (nën-direktori ndërtimi), për të shmangur konfliktet e emrave të skedarëve gjatë procesit të ndërtimit. Skedari ns3/core-module.h përputhet me modul ns‑3, i cili do të gjeni në direktorinë src/core në lëshimin tuaj të instaluar. Në listimin e kësaj direktorie do të gjeni një numër të madh skedarësh të titujve. Kur bëni ndërtimin, Waf skedarët e titujve publikë vendosen në direktorinë ns3 në nën-direktorinë build/debug
Nëse nuk keni një direktori të tillë, kjo do të thotë se kur po ndërtonit versionin e lëshimit të ns-3 nuk keni specifikuar drejtorinë e daljes, kryeni ndërtimin si:
$ ./waf configure —build-profile=debug —out=build/debug
$ ./waf build
ose
$ ./waf configure —build-profile=optimized —out=build/optimized
$ ./waf build
ose build/optimized, në përputhje me konfigurimin tuaj. Waf do të krijojë gjithashtu automatikisht një skedar moduli për të ngarkuar të gjithë skedarët e titujve publikë. Duke qenë se, sigurisht, e ndiqni këtë udhëzues rreptësisht, tashmë keni bërë
$ ./waf -d debug --enable-examples --enable-tests configurepër të konfiguruar projektin për të kryer ndërtimet e ndihmës, duke përfshirë shembuj dhe teste. Keni bërë gjithashtu
$ ./wafpër të ndërtuar projektin. Pra, tani, kur të shikoni në direktorinë ../..//build/debug/ns3, atje, ndër të tjera, do të gjeni skedarët e titujve të katër moduleve të treguara më sipër. Mund të shikoni përmbajtjen e këtyre skedarëve dhe të zbuloni se ata përfshijnë të gjithë skedarët publikë që përdoren nga modulet përkatëse.
4.2.3 Hapësira e emrave ns3
Rreshti tjetër në skriptin first.cc është shpallja e hapësirës së emrave.
using namespace ns3;Projekti ns‑3 është realizuar në hapësirën e emrave C++, e quajtur ns3. Kjo grupon të gjitha shpalljet e lidhura me ns‑3 brenda saj duke i mbajtur ato jashtë hapësirës globale të emrave, që shpresojmë të ndihmojë në integrimin me kodin tjetër. Përdorimi i operatorit C++ sjell hapësirën e emrave ns‑3 në rajonin deklarativ aktual (global). Ky është një mënyrë e veçantë për të thënë se pas kësaj shpalljeje, nuk do t'ju nevojitet të përdorni operatorin e saktësisë ns3 :: scope para çdo kodi ns‑3 për ta përdorur atë. Nëse nuk jeni të njohur me hapësirat e emrave, ju lutemi referohuni në çdo tekst praktik mbi C++ dhe krahasoni hapësirën e emrave ns3 me përdorimin e hapësirës së emrave std dhe shpalljet. using namespace std; në shembujt e punës me operatorin e daljeve cout dhe rrjedhave.
4.2.4 Regjistrimi
Rreshti i ardhshëm i skriptit është
NS_LOG_COMPONENT_DEFINE ("FirstScriptExample");Ne do ta përdorim këtë deklaratë si një pikë të përshtatshme për të diskutuar sistemin tonë të dokumentimit Doxygen. Nëse shikoni në faqen e internetit të projektit ns‑3, do të gjeni një lidhje 'Dokumentacioni' në panelin e navigimit. Nëse zgjidhni këtë lidhje, do të shkoni në faqen tonë të dokumentacionit. Ka një lidhje për 'Lëshimin e fundit', që do t'ju çojë te dokumentacioni për versionin e fundit stabil të ns‑3. Nëse zgjidhni lidhjen 'Dokumentacioni API', do të kaloni në faqen e dokumentacionit të API ns‑3.
Në anën e majtë të faqes do të gjeni një pamje grafike të strukturës së dokumentacionit. Një vend i mirë për të filluar është 'libri' Modules ns‑3 në strukturën e navigimit ns‑3. Nëse zgjidhni Modules, do të shihni një listë të dokumentacionit të moduleve ns‑3. Siç u diskutua më sipër, koncepti i modulit këtu është në lidhje të drejtpërdrejtë me skedarët e përfshirë në modul. Naltë, nënmoduli i regjistrimit ns‑3 diskutohet në seksionin Përdorimi i modulit të regjistrimit, kështu që do të kthehemi te ai më vonë në këtë udhëzues, por ju mund të mësoni rreth deklaratës së mësipërme duke parë modul Core, dhe pastaj hapni librin Mjetet për debugging, dhe pastaj zgjidhni faqen Logging. Klikoni mbi Logging.
Tani duhet të shqyrtoni dokumentacionin Doxygen për modulin LoggingNë listën e makrokomandave në krye të faqes, do të shihni një regjistrim për NS_LOG_COMPONENT_DEFINE. Para se të kaloni në lidhje, sigurohuni që të shikoni "Përshkrimin e Detajuar" të modulit të regjistrimit për të kuptuar funksionimin e tij në tërësi. Për ta bërë këtë, mund të rrokullisni poshtë ose të zgjidhni "More..." nën diagramin.
Sa herë që keni një ide të përgjithshme se çfarë po ndodh, vazhdoni dhe shqyrtoni dokumentacionin për NS_LOG_COMPONENT_DEFINE specifike. Nuk do ta përsëris dokumentacionin këtu, por duke përmbledhur, kjo linjë shpall një komponent regjistrimi të quajtur FirstScriptExample, i cili lejon të aktivizoni dhe çaktivizoni regjistrimin e mesazheve në konsolë në lidhje me emrin.
4.2.5 Funksioni kryesor
Në linjat e ardhshme të skenarit do të shihni,
int
main (int argc, char *argv[])
{ Ky është thjesht një shpallje e funksionit kryesor të programit tuaj (skenarit). Si në çdo program në C++, duhet të përcaktoni funksionin kryesor, i cili ekzekutohet i pari. Nuk ka asgjë të veçantë këtu. Skripti juaj ns‑3 është thjesht një program C++. Linja e ardhshme vendos rezolutën e kohës në 1 nanosekondë, që është vlera e paracaktuar:
Time::SetResolution (Time::NS);Rezoluta e kohës ose thjesht rezoluta është vlera më e vogël e kohës që mund të përdoret (dallimi më i vogël i perceptueshëm mes dy vlerave të kohës). Mund ta ndryshoni rezolutën vetëm një herë. Mekanizmi që ofron këtë fleksibilitet konsumon memorie, kështu që, sapo të vendosni qartë rezolutën, çlironim memorien, duke parandaluar përditësime të mëtejshme. (Nëse nuk e vendosni rezolutën qartë, atëherë në parazgjedhje do të jetë një nanosekondë, dhe memoria do të çlirohet në fillim të simulimit.)
Dy linqet e ardhshme të skenarit përdoren për të aktivizuar dy komponentë regjistrimi të integruar në aplikacionet EchoClient dhe EchoServer:
LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO); LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO);Nëse keni lexuar dokumentacionin për komponentin Logging, do të vini re se ekzistojnë disa nivele detajesh regjistrimi që mund të aktivizoni në secilin komponent. Këto dy rreshta kodi aktivizojnë regjistrimin e debugging në nivelin INFO për klientët dhe serverët e echo. Në këtë nivel, aplikacioni do të printojë mesazhe gjatë simulimit kur dërgon dhe merr paketa.
Tani ne do të kalojmë drejtpërdrejt në krijimin e topologjisë dhe fillimin e simulimit. Ne do të angazhojmë objekte ndihmëse të topologjisë për ta bërë këtë punë sa më të lehtë të jetë e mundur.
4.2.6 Përdorimi i ndihmësve topologjikë
Dy rreshtat e ardhshëm të kodit në skriptin tonë në të vërtetë do të krijojnë objekte Node ns-3, të cilat do të përfaqësojnë kompjuterët në simulim.
NodeContainer nodes;
nodes.Create (2);Para se të vazhdojmë, le të gjejmë dokumentacionin për klasën NodeContainer. Një tjetër mënyrë për të hyrë në dokumentacionin për këtë klasë është përmes tab-it Classes në faqet Doxygen. Nëse keni hapur tashmë Doxygen, thjesht rrotulloni lart në krye të faqes dhe zgjidhni tab-in Classes. Duhet të shihni një grup të ri tabs, një nga të cilët është lista e klasave. Nën këtë tab do të shihni listën e të gjitha klasave ns-3. Rrotulloni poshtë deri te ns3::NodeContainer. Kur ta gjeni klasën, zgjidhni atë për të hyrë në dokumentacionin për klasën.
Siç kujtojmë, një nga abstraksionet tona kyçe është nodi. Ai përfaqëson një kompjuter, në të cilin do të shtojmë gjëra si staket e protokolleve, aplikacione dhe karta periferike. Ndihmësii i topologjisë NodeContainer siguron një mënyrë të lehtë për të krijuar, menaxhuar dhe aksesuar çdo objekt Nyja, që krijojmë për të nisur simulimin. Rreshti i parë më sipër thjesht shpall NodeContainer, të cilin e quajmë nodes. Rreshti i dytë thërret metodën Create për objektin nodes dhe kërkon nga kontejneri që të krijojë dy nodë. Siç përshkruhet në Doxygen, kontejneri kërkon në sistemin ns-3 krijimin e dy objekteve Nyja dhe ruan treguesit për këto objekte brenda vetes.
Nodet e krijuara në skript, për momentin nuk bëjnë asgjë. Hapi tjetër në ndërtimin e topologjisë është lidhja e nodëve tona në rrjet. Forma më e thjeshtë e rrjetit që ne mbështesim është lidhja pikë-pikë midis dy nodëve. Tani ne do të krijojmë një lidhje të tillë.
PointToPointHelper
Ne krijojmë një lidhje dypikëshe, duke vepruar sipas një modeli të njohur për ne, përdorim një objekt ndihmës topologjik për të kryer punën në nivel të ulët të nevojshme për lidhjen. Le të kujtojmë se dy abstraksionet tona kyçe NetDevice dhe Channel. Në botën reale, këto terma përkojnë në mënyrë të përafërt me kartat periferike dhe kabllot e rrjetit. Si zakonisht, këto dy gjëra janë të lidhura ngushtësisht me njëra-tjetrën, dhe askush nuk mund të llogarisë në ndërrimin, për shembull, të pajisjeve Ethernet në një kanal pa tela. Ndihmësit tanë topologjikë e ndjekin këtë lidhje të ngushtë dhe për këtë arsye në këtë skenar do të përdorni një objekt PointToPointHelper për të konfiguruar dhe lidhur objektet ns-3 PointToPointNetDevice dhe PointToPointChannel. Tre rreshtat e ardhshëm në skenar:
PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));Rreshti i parë,
PointToPointHelper pointToPoint;krijon një instancë të objektit në stek. PointToPointHelper. Nga pikëpamja e nivelit të lartë, rreshti i ardhshëm,
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));i thotë objektit PointToPointHelper të përdorë vlerën "5 Mbps" (pesë megabit në sekondë) si "DataRate».
Nga një këndvështrim më të saktë, rreshti "DataRate" përkon me atë që quajmë atribut PointToPointNetDevice. Nëse shikoni në Doxygen për klasën ns3::PointToPointNetDevice dhe në dokumentacionin e metodës GetTypeId do të gjeni një listë atributesh të përcaktuara për pajisjen. Ndër to do të jetë atributi "DataRate". Shumica e objekteve të dukshme për përdoruesin në ns-3 kanë lista të ngjashme atributesh. Ne përdorim këtë mekanizëm për të thjeshtuar ndërlikimin e simulimit pa e riprogramuar, siç do ta shihni në seksionin e ardhshëm.
Si "DataRate" në PointToPointNetDevice, do të gjeni atributin "Delay" të lidhur me PointToPointChannel. Rreshti përfundimtar,
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));SETUP.EXE: ekzekutues MS-DOS, NE për MS Windows 3.x PointToPointHelper përdor vlerën "2 ms" (dy milisekonda) si vlerën e vonesës përhapëse për kanalin pikë-pikë, të cilin ai më pas krijon.
NetDeviceContainer
Derisa, në skenarin tonë kemi NodeContainer, i cili përmban dy nyje. Kemi PointToPointHelper, i cili është i përgatitur për të krijuar objektet PointToPointNetDevices dhe për t'i lidhur ato përmes objektit PointToPointChannel. Ashtu siç përdorëm objektin ndihmës të topologjisë NodeContainer për të krijuar nyjet, do të kërkojmë që PointToPointHelper të kryejë punën për ne që ka të bëjë me krijimin, konfigurimin dhe vendosjen e pajisjeve tona. Na nevojitet një listë e të gjitha objekteve të krijuara NetDevice, prandaj ne përdorim NetDeviceContainer për ruajtjen e tyre siç e përdorëm NodeContainer për ruajtjen e nyjave që kemi krijuar. Dy rreshtat e ardhshëm të kodit,
NetDeviceContainer devices;
devices = pointToPoint.Install (nodes);përfundojnë konfigurimin e pajisjeve dhe kanalit. Rreshti i parë deklaron kontejnerin e pajisjeve, të përmendur më lart, ndërsa i dyti kryen punën kryesore. Metoda Install të objektit PointToPointHelper merr NodeContainer si një parametër. Brenda NetDeviceContainer për çdo nyjë që ndodhet në NodeContainer krijohet (për lidhjen pikë-pikë duhet të jenë saktësisht dy) PointToPointNetDevice krijohet dhe ruhet në kontejnerin e pajisjeve. PointToPointChannel krijohet, dhe dy PointToPointNetDevices. Pas krijimit të objekteve, atributet e ruajtur në PointToPointHelper, përdoren për të inicializuar atributet përkatëse në objektet e krijuara.
Pas thirrjes pointToPoint.Install (nodes) do të kemi dy nyje, secila me një pajisje rrjeti "pikë-pikë" të instaluar dhe një kanal "pikë-pikë" midis tyre. Të dy pajisjet do të konfigurohen për të transferuar të dhëna me shpejtësi pesë megabit në sekondë me një vonesë transmetimi në kanal prej dy milisekondash.
InternetStackHelper
Tani kemi konfiguruar nyjat dhe pajisjet, por nuk kemi instaluar stek të protokolleve në nyjat tona. Dy rreshtat e ardhshëm të kodit do të kujdesen për këtë.
InternetStackHelper stack;
stack.Install (nodes);InternetStackHelper është një ndihmës topologjik për stekët e internetit, si PointToPointHelper për pajisjet rrjetësore. Metoda Install pranon NodeContainer si një parametër. Në ekzekutim, do të instalohet steku i Internetit (TCP, UDP, IP etj.) në çdo nyjë të kontejnerit.
Ipv4AddressHelper
Më pas, na nevojitet të lidhim pajisjet tona me adresat IP. Ne ofrojmë një ndihmës topologjik për të menaxhuar shpërndarjen e adresave IP. API i dukshëm për përdoruesit është vendosja e adresës IP bazë dhe maskës së rrjetit për t'u përdorur gjatë realizimit të shpërndarjes së adresave (kjo bëhet në një nivel më të ulët brenda ndihmësit). Dy rreshtat e ardhshëm të kodit në shembullin tonë të skriptit first.cc,
Ipv4AddressHelper address;
address.SetBase ("10.1.1.0", "255.255.255.0");deklarojnë një objekt ndihmës adresë dhe i thonë asaj se duhet të fillojë të alokojë adresa IP nga rrjeti 10.1.1.0, duke përdorur maskën e bitëve 255.255.255.0 për ta përcaktuar. Në mënyrë të paracaktuar, adresat e alokuara do të fillojnë nga një dhe do të rriten monotonikisht, prandaj adresa e parë e alokuar nga ky bazë do të jetë 10.1.1.1, pastaj 10.1.1.2, etj. Në realitet, në nivelin e ulët sistemi ns-3 ruan të gjitha adresat IP të alokuara dhe gjeneron një gabim fatkeq nëse aksidentalisht krijoni një situatë ku e njëjta adresë gjenerohet dy herë (për dijeni, ky gabim është i vështirë për t'u debug-uar).
Rreshti i ardhshëm i kodit,
Ipv4InterfaceContainer interfaces = address.Assign (devices);bën alokimin real të adresës. Në ns-3 ne vendosim lidhjen mes adresës IP dhe pajisjes duke përdorur objektin Ipv4Interface. Ashtu siç na nevojitet ndonjëherë një listë e pajisjeve rrjetore të krijuara nga asistenti për përdorime të mëtejshme, ndonjëherë na nevojitet një listë objektesh Ipv4Interface. Ipv4InterfaceContainer siguron këtë funksionalitet.
Ne ndërtuam një rrjet pikë në pikë, me steka të instaluara dhe adresa IP të alokuara. Tani na nevojiten aplikacione në secilin nyje për të gjeneruar trafik.
4.2.7 Përdorimi i Aplikacionit
Një nga abstraksionet kryesore të sistemit ns-3 është Aplikacioni (application). Në këtë skenar ne përdorim dy specializime të klasës bazë Aplikacioni ns-3 të quajtur UdpEchoServerApplication dhe UdpEchoClientApplication. Ashtu si në rastet e mëparshme, ne përdorim objekte ndihmëse për të konfiguruar dhe menaxhuar objektet themelore. Këtu përdorim UdpEchoServerHelper dhe UdpEchoClientHelperobjekte, për ta bërë jetën tonë më të lehtë.
UdpEchoServerHelper
Rreshtat e mëposhtëm të kodit në shembullin tonë të skriptit first.cc, përdoren për të konfiguruar aplikacionin e serverit UDP echo 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, por një objekt që na ndihmon të krijojmë aplikacione reale. Një nga marrëveshjet tona është të kalojmë atributet e nevojshme në konstruktorin e objektit ndihmës. Në këtë rast, ndihmësi nuk mund të bëjë asgjë të dobishme nëse nuk i është dhënë numri i portit në të cilin serveri do të presë paketat, ky numër gjithashtu duhet të dihet nga klienti. Në këtë rast, ne i kalojmë konstruktorit të ndihmës numrin e portit. Konstruktorit, nga ana e tij, thjesht i jep SetAttribute me vlerën e kaluar. Më vonë, nëse dëshironi, me SetAttribute do të jeni në gjendje të vendosni një vlerë tjetër për atributin 'Port'.
Si shumë objekte të tjera ndihmëse, objekti UdpEchoServerHelper ka një metodë Install. Kryerja e kësaj metode, në të vërtetë, përfundon me krijimin e një aplikacioni bazë të echo-server dhe lidhet me nodin. Është interesante se metoda Install merr NodeContainter ka si parametrin po ashtu si metodat e tjera Install që kemi parë.
Konvertimi implicit C++, që funksionon këtu, merr rezultatin e metodës node.Get (1) (e cila kthen një tregues të mençur në objektin nod — Ptr) dhe e përdor atë në konstruktorin për një objekt anonim NodeContainer, i cili më pas kalon në metodën Install. Nëse nuk mund ta përcaktoni në kodin C++, metodën me cilën nënshkrim kompiloheni dhe ekzekutohet, atëherë kërkoni midis konvertimeve implicite.
Tani ne shohim se echoServer.Install do të vendosë aplikacionin UdpEchoServerApplication në nodin e gjetur në NodeContainer, të cilin e përdorim për të menaxhuar nodet tona, nodi me indeks 1. Metoda Install do të kthejë container-in që përmban treguesit për të gjitha aplikacionet (në këtë rast një, pasi ne kaluam një anonim NodeContainer, që përmban një nod) e krijuar nga ndihmësi.
Aplikacionet kërkojnë të përcaktojnë momentin e nisjes për gjenerimin e trafikut 'start' dhe mund të kërkojnë gjithashtu të përcaktojnë kohën kur të ndalen 'stop'.Ne ofrojmë të dy parametrat. Këto kohë përcaktohen me anë të metodave ApplicationContainer Nisni dhe Nd stopping. Këto metoda pranojnë parametra të tipit Koha. Në këtë rast ne përdorim një sekuencë eksplicite konvertimi C++, për të marrë C++ double 1.0 dhe ta kthej në një objekt tns‑3 Time, duke përdorur objektin Seconds për ta konvertuar në sekonda. Mbani mend se rregullat e konvertimit mund të kontrollohen nga autori i modelit, dhe C++ ka rregullat e tij, kështu që nuk mund të besoni gjithmonë se parametrat do të konvertohen ashtu siç prisni. Dy rreshta,
serverApps.Start (Seconds (1.0));
serverApps.Stop (Seconds (10.0));do të shkaktojë që aplikacioni i echo-server të aktivizohet (në mënyrë automatike) pas një sekonde nga fillimi i simulacionit dhe të ndalet (të çaktivizohet) pas dhjetë sekondash simulimi. Duke qenë se ne shpallëm një ngjarje simulimi (ngjarja e ndalimit të aplikacionit), e cila do të ekzekutohet pas dhjetë sekondash, do të simulohet të paktën dhjetë sekonda funksionimi të rrjetit.
UdpEchoClientHelper
Aplikacioni i klientit echo konfigurohet në një mënyrë, pothuajse të ngjashme me serverin. Ekziston një objekt bazë UdpEchoClientApplication, i cili menaxhohet nga
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 e echo, na nevojitet të vendosim pesë atribute të ndryshme. Dy atributet e para vendosen gjatë krijimit UdpEchoClientHelper. Ne kalojmë parametrat, që përdoren (brenda ndihmës) për të vendosur atributet "RemoteAddress" dhe "RemotePort" në përputhje me marrëveshjen tonë, për kalimin e parametrave të nevojshëm në konstruktorin e ndihmës.
Le të kujtojmë se ne kemi përdorur Ipv4InterfaceContainer për të ndjekur adresat IP që i kemi caktuar pajisjeve tona. Interface zero në kontenierin e interface-ve do të përputhet me adresën IP të nodit zero në kontenierin e nodave. Interface i parë në kontenierin e interface-ve përputhet me adresën IP të nodit të parë në kontenierin e nodave. Pra, në rreshtin e parë të kodit (atë të sipërm), ne krijojmë ndihmësin dhe i themi atij se adresa e largët e klientit do të jetë adresa IP e caktuar nodit në të cilin ndodhet serveri. Po ashtu, i japim informacion se duhet të organizohet dërgimi i paketave në portin e nëntë.
Atributi „MaxPackets“ njofton klientin për numrin maksimal të pakove që mund të dërgojmë gjatë modelimit. Atributi „Interval“ njofton klientin se sa gjatë të presë midis pakove, dhe atributi „PacketSize“ njofton klientin për sa e madhe duhet të jetë ngarkesa e paketës. Me këtë kombinim atributesh, i themi klientit të dërgojë një paketë 1024-bajtëshe.
Si në rastin e serverit të echo-s, ne vendosim atributet për klientin e echo-s Nisni dhe Nd stopping, por këtu e nisim klientin një sekondë pas aktivizimit të serverit (një nga dy sekonda pas fillimit të simulimit).
4.2.8 Simulimi
Në këtë fazë, na nevojitet të nisim simulimin. Kjo bëhet përmes funksionit global Simulator::Run.
Simulator::Run ();Kur kemi thirrur më parë metodat,
serverApps.Start (Seconds (1.0));
serverApps.Stop (Seconds (10.0));
...
clientApps.Start (Seconds (2.0));
clientApps.Stop (Seconds (10.0));ne fakt kemi programuar ngjarje në simulator për 1.0 sekondë, 2.0 sekondë dhe dy ngjarje në 10.0 sekondë. Pas thirrjes Simulator::Run, sistemi do të fillojë të shqyrtojë listën e ngjarjeve të programura dhe të realizojë ato. Së pari, ai do të aktivizojë ngjarjen në 1.0 sekondë, e cila aktivizon aplikacionin e serverit të echo-s (kjo ngjarje mund, në kthim, të programojë shumë ngjarje të tjera). Më pas, ai do të aktivizojë ngjarjen e programuar në t = 2.0 sekondë, e cila do të aktivizojë aplikacionin e klientit të echo-s. Po ashtu, kjo ngjarje mund të programojë shumë ngjarje të tjera. Realizimi i ngjarjes së aktivizimit në klientin e echo-s do të nisë fazën e transferimit të të dhënave në modelim duke dërguar një paketë në server.
Aktivizimi i dërgimit të paketës në server do të nxisë një zinxhir ngjarjesh, të cilat do të programohen automatikisht prapa skenave dhe që do të realizojnë mekanikën e dërgimit të paketave të echo-s sipas parametrave të sinkronizimit që kemi vendosur në skenar.
Në fund, pasi dërgojmë vetëm një paketë (për t'i kujtuar, atributi MaxPackets ishte vendosur në një), zinxhiri i ngjarjeve të iniciuar nga ky vetëm kërkesë echo nga klienti do të përfundojë, dhe simulimi do të kalojë në modalitetin pritës. Sa herë që ndodh kjo, ngjarjet e mbetura të programura do të jenë ngjarjet Nd stopping për serverin dhe klientin. Kur këto ngjarje të realizohen, nuk do të mbeten ngjarje për përpunim të mëtejshëm dhe Simulator::Run do të kthejë kontrollin. Modelimi përfundoi.
Tani mbetet vetëm të pastrohet. Kjo bëhet duke thirrur funksionin global Simulator::Destroy. Duke janë thirrur funksionet e asistentëve (ose kodi i nivelit të ulët ns-3), të cilat janë organizuar në mënyrë që të vendosen hook në simulator për shkatërrimin e të gjitha objekteve që janë krijuar. Nuk është e nevojshme të ndjekësh ndonjë nga këto objekte vetë — gjëja e vetme që duhej të bënit ishte të thirrni Simulator::Destroy dhe të dilni. Sistema ns-3 do të kryejë këtë punë të vështirë për ju. Rreshtat e mbetur të skenarit tonë të parë ns-3, first.cc, e bëjnë pikërisht këtë:
Simulator::Destroy ();
return 0;
}Kur do të ndalet simulatori?
ns-3 është një simulator i ngjarjeve diskrete (DE). Në këtë lloj simulatori, çdo ngjarje lidhet me kohën e ekzekutimit të saj, dhe simulimi vazhdon duke procesuara ngjarjet në rendin në të cilin ndodhin gjatë simulimit. Ngjarjet mund të shkaktojnë planifikimin e ngjarjeve të ardhshme (p.sh., një timer mund të planifikojë veten për të përfunduar numërimin në intervalin e ardhshëm).
Ngjarjet fillestare zakonisht inicirohen nga një objekt, për shembull, IPv6 do të planifikojë identifikimin e shërbimeve në rrjet, kërkesat për fqinjët etj. Aplikacioni planifikon ngjarjen e parë të dërgimit të paketës etj. Kur një ngjarje përpunon, ajo mund të gjenerojë zero, një ose disa ngjarje. Ndërsa simulimi përparon, ndodhin ngjarje, duke përfunduar thjesht ose duke gjeneruar të reja. Simulimi do të ndalet automatikisht nëse radhët e ngjarjeve janë bosh ose një ngjarje speciale është zbuluar. Nd stoppingNgjarja Nd stopping ndodh përmes funksionit Simulator::Stop (ndaloni kohën).
Ka një rast tipik kur Simulator::Stop është absolutisht e nevojshme për të ndalur simulimin: kur ka ngjarje vetë-mbështetëse. Ngjarjet vetë-mbështetëse (ose të përsëritura) janë ngjarje që gjithmonë planifikojnë veten. Si pasojë, ato gjithmonë e mbajnë radhën e ngjarjeve jo bosh. Ekzistojnë shumë protokolle dhe module që përmbajnë ngjarje të përsëritura, për shembull:
• FlowMonitor — kontroll periodik për paketat e humbura;
• RIPng — transmetim periodik i përditësimeve të tabelave të ruterëve;
• etj.
Në këto raste Simulator::Stop është e nevojshme për të ndalur siç duhet simulimin. Për më tepër, kur ns-3 është në modalitetin e simulimit, RealtimeSimulator përdoret për të sinkronizuar orët e simulimit me orët e makinë, dhe Simulator::Stop është e nevojshme për të ndalur procesin.
Shumica e programeve të simulimit në udhëzues nuk e thirrin Simulator::Stop qartazi, pasi se ato përfundojnë automatikisht me përfundimin e ngjarjeve në rradha. Megjithatë, këto programe gjithashtu do të pranojnë thirrjen Simulator::Stop. Për shembull, operatori i mëposhtëm në shembullin e parë të programit do të planifikojë një ndalim të qartë në sekondën e 11-të:
+ Simulator::Stop (Sekondat (11.0));
Simulator::Run ();
Simulator::Destroy ();
kthehu 0;
}Ajo që është përmendur më sipër në fakt nuk do ta ndryshojë sjelljen e këtij programi, pasi kjo simulim përfundon natyrshëm pas 10 sekondash. Por nëse do të ndryshonit kohën e ndalimit në operatorin e lartpërmendur nga 11 sekonda në 1 sekondë, do të vëreni se simulimi ndalon para se çdo dalje të vije në ekran (pasi dalja ndodh rreth 2 sekondash pas kohe simulimi).
E rëndësishme është të thirrni Simulator::Stop para se të thirrni Simulator::Run; përndryshe, Simulator::Run mund të mos kthejë asnjëherë kontrollin në programin kryesor për të kryer ndalimin!
4.2.9 Ndërtimi i skenarit tuaj
Ne e bëmë krijimin e skenarëve tuaj të thjeshtë triviale. E vetmja gjë që duhet të bëni është të vendosni skenarin tuaj në katalogun scratch, dhe ai do të grumbullohet automatikisht nëse e lançoni Waf. Le të provojmë. Kthehuni në katalogun në nivelin më të lartë dhe kopjoni examples/tutorial/first.cc në katalog scratch
$ cd ../..
$ cp examples/tutorial/first.cc scratch/myfirst.ccTani grumbulloni shembullin tuaj të parë të skenarit duke përdorur waf:
$ ./wafDuhet të shihni mesazhe që tregojnë se shembulli juaj i parë është krijuar me sukses.
Waf: Po hyjmë në katalogun `/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: Po largohemi nga katalogu `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' përfundoi me sukses (2.357s)Tani mund të ekzekutoni shembullin (kini parasysh që nëse grumbulloni programin tuaj në katalogun scratch, atëherë duhet ta ekzekutoni edhe nga scratch):
$ ./waf --run scratch/myfirstDuhet të shihni një dalje të ngjashme:
Waf: Po hyjmë në katalogun `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Po largohemi nga katalogu `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' përfundoi me sukses (0.418s) Dërguar 1024 bytes në 10.1.1.2
Marrë 1024 bytes nga 10.1.1.1
Marrë 1024 bytes nga 10.1.1.2Këtu shihni se si sistemi i ndërtimit kontrollon nëse skedari është ndërtuar dhe pastaj e nis atë. Ju shihni një regjistrim komponent në klientin e echo që tregon se ai dërgoi një paketë 1024-byte në serverin echo 10.1.1.2. Ju gjithashtu shihni regjistrimin e komponentit në serverin echo që thotë se ai mori 1024 byte nga 10.1.1.1. Serveri echo e përsërit paketën heshtur dhe ju shihni në regjistrin e klientit echo që ai e mori paketën e tij përsëri nga serveri.
4.3 Kodi burimor ns-3
Tani që keni përdorur disa nga ndihmësit ns-3, mund të shikoni disa nga kodet burimore që realizojnë këtë funksionalitet. Kodi më i fundit mund të shikoni në serverin tonë të internetit në lidhjen në vijim: . Aty do të shihni një faqe përmbledhjeje Mercurial për pemën tonë zhvillimore ns-3. Në krye të faqes do të shihni disa lidhje,
përmbledhje | njoftime të shkurtra | regjistri i ndryshimeve | grafiku | etiketat | skedarëtShkoni përpara dhe zgjidhni lidhjen për skedarët. Këtu është si do të duket niveli i sipërm i shumicës së repositorëve tanë:
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 | annotateShembujt tanë të skripteve janë në drejtorinë examples. Nëse klikoni në shembuj, do të shihni një listë të nën-drejtorive. Një nga skedarët në nën-drejtorinë tutorial — first.cc. Nëse klikoni në first.cc do të shihni kodin që sapo keni studiuar.
Kodi burimor është kryesisht në drejtorinë src. Mund të shikoni kodin burimor duke klikuar në emrin e direktorisë ose duke klikuar në lidhjen e skedave në anën e djathtë të emrit të direktorisë. Nëse klikoni në direktorinë src, do të merrni një listë të nën-direktorive src. Nëse më pas klikoni në nën-direktorinë core, do të gjeni një listë skedash. Skeda e parë që do të shihni (në momentin e shkrimit të këtij udhëzimi) — abort.h. Nëse klikoni në lidhjen abort.h, do të dërgoheni në skedarin burimor për abort.h, i cili përmban makros të dobishme për daljen nga skriptet nëse gjenden kushte anormale. Kodi burimor për ndihmësit që kemi përdorur në këtë kapitull mund të gjendet në direktorinë src/Applications/helper. Mos hezitoni të hidhni një sy në strukturën e direktorive për të kuptuar se çfarë është ku dhe për t'u njohur me stilin e programeve ns-3.
Burimi: habr.com
