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

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

5 Cilësimet
5.1 Përdorimi i modulit të regjistrimit
5.1.1 Vështrim i përgjithshëm i regjistrimit
5.1.2 Aktivizo regjistrimin
5.1.3 Shtimi i regjistrimit në kodin tuaj
5.2 Përdorimi i argumenteve të linjës së komandës
5.2.1 Mbështetja e vlerave të atributeve të paracaktuara
5.2.2 Kapja e komandave tuaja
5.3 Përdorimi i sistemit të gjurmimit
5.3.1 Gjurmimi ASCII
Analiza e gjurmëve ASCII
5.3.2 Gjurmë PCAP

Kapitulli 5

rregullim

5.1 Përdorimi i modulit të regjistrimit

Tashmë shikuam shkurtimisht modulin e regjistrimit ns-3 duke parë skriptin së pari.cc. Në këtë kapitull, ne do të hedhim një vështrim më të afërt në përdorimet e mundshme të nënsistemit të logging.

5.1.1 Vështrim i përgjithshëm i regjistrimit

Shumë sisteme të mëdha mbështesin një lloj mjeti për regjistrimin e mesazheve, dhe ns-3 nuk bën përjashtim. Në disa raste, vetëm mesazhet e gabimit shkruhen në "konsolën e operatorit" (e cila zakonisht është stderr në sistemet e bazuara në Unix). Në sisteme të tjera, mesazhet paralajmëruese mund të shfaqen si dhe informacione më të detajuara. Në disa raste, mjetet e regjistrimit përdoren për të nxjerrë mesazhe korrigjimi që mund të turbullojnë shpejt daljen.

SubHRD e përdorur në ns-3 supozon se të gjitha këto nivele të përmbajtjes së informacionit janë të dobishme dhe ne ofrojmë një qasje selektive, të shtresuar për regjistrimin e mesazheve. Regjistrimi mund të çaktivizohet plotësisht, të aktivizohet në bazë të një komponenti ose globalisht. Për këtë qëllim, përdoren nivele të rregullueshme të përmbajtjes së informacionit. Moduli i regjistrimit ns-3 ofron një mënyrë relativisht të thjeshtë për të marrë informacion të dobishëm nga simulimi juaj.

Duhet të kuptoni se ne ofrojmë një mekanizëm për qëllime të përgjithshme - gjurmimin - për nxjerrjen e të dhënave nga modelet tuaja, i cili duhet të jetë produkti i preferuar për simulimet (për më shumë informacion mbi sistemin tonë të gjurmimit, shihni seksionin tutorial 5.3). Regjistrimi duhet të jetë metoda e preferuar për marrjen e informacionit të korrigjimit, paralajmërimeve, mesazheve të gabimit ose për nxjerrjen e shpejtë të mesazheve nga skriptet ose modelet tuaja në çdo kohë.

Aktualisht, sistemi përcakton shtatë nivele (lloje) të mesazheve log në rend në rritje të përmbajtjes së informacionit.

  • LOG_ERROR - Regjistrimi i mesazheve të gabimit (makro i lidhur: NS_LOG_ERROR);
  • LOG_WARN - Regjistro mesazhe paralajmëruese (makro e lidhur: NS_LOG_WARN);
  • LOG_DEBUG - Regjistro mesazhe të veçanta korrigjimi relativisht të rralla (makro e lidhur: NS_LOG_DEBUG);
  • LOG_INFO - regjistrimi i mesazheve informative për ecurinë e programit (makro e lidhur: NS_LOG_INFO);
  • LOG_FUNCTION - Regjistron mesazhet që përshkruajnë çdo funksion të thirrur (dy makro të lidhura: NS_LOG_FUNCTION, e përdorur për funksionet e anëtarëve dhe NS_LOG_FUNCTION_NOARGS, e përdorur për funksionet statike);
  • LOG_LOGIC - Regjistrimi i mesazheve që përshkruajnë rrjedhën logjike brenda një funksioni (makro e lidhur: NS_LOG_LOGIC);
  • LOG_ALL - Regjistron gjithçka të përmendur më sipër (pa makro të lidhur).
    Për secilin lloj (LOG_TYPE) ekziston edhe një LOG_LEVEL_TYPE i cili, nëse përdoret, lejon që të gjitha nivelet mbi të të regjistrohen përveç nivelit të tij. (Si rrjedhojë, LOG_ERROR dhe LOG_LEVEL_ERROR, dhe LOG_ALL dhe LOG_LEVEL_ALL janë funksionalisht ekuivalente.) Për shembull, aktivizimi i LOG_INFO do të lejojë vetëm mesazhet e ofruara nga makroja NS_LOG_INFO, ndërsa aktivizimi LOG_LEVEL_INFO do të përfshijë gjithashtu mesazhet LOG_LEVEL_INFO të ofruara nga MAkro,LOG_INFO _WARN dhe NS_LOG_ERROR.

Ne ofrojmë gjithashtu një makro regjistrimi të pakushtëzuar që shfaqet gjithmonë, pavarësisht nga niveli i regjistrimit ose komponenti i përzgjedhjes.

  • NS_LOG_UNCOND - Regjistrimi i pakushtëzuar i mesazhit shoqërues (nuk ka nivel regjistrimi të lidhur).

Çdo nivel mund të kërkohet individualisht ose kumulativisht. Regjistrimi mund të konfigurohet duke përdorur ndryshoren e mjedisit sh NS_LOG ose duke regjistruar një thirrje të funksionit të sistemit. Siç u tregua më herët, sistemi i prerjeve ka dokumentacion Doxygen dhe tani është një kohë e mirë për ta rishikuar nëse nuk e keni tashmë.

Tani që e keni lexuar dokumentacionin në detaje, le ta përdorim atë njohuri për të marrë disa informacione interesante nga skenari shembull gërvisht/myfirst.cctë cilën e keni përpiluar tashmë.

5.1.2 Aktivizo regjistrimin

Le të përdorim variablin e mjedisit NS_LOG për të ekzekutuar disa regjistra të tjerë, por së pari, vetëm për të marrë kushinetat tuaja, ekzekutoni skriptin e fundit siç bëtë më parë,

$ ./waf --run scratch/myfirst

Ju duhet të shihni daljen e njohur nga programi i parë shembull ns-3

$ 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.413s)
Sent 1024 bytes to 10.1.1.2
Received 1024 bytes from 10.1.1.1
Received 1024 bytes from 10.1.1.2

Rezulton se mesazhet "të dërguara" dhe "të marra" që shihni më lart janë në të vërtetë mesazhe të regjistruara nga Aplikimi UdpEchoClient и Aplikimi UdpEchoServer. Për shembull, ne mund t'i kërkojmë aplikacionit të klientit të printojë informacion shtesë duke vendosur nivelin e tij të regjistrimit përmes ndryshores së mjedisit NS_LOG.

Që tani e tutje, unë do të supozoj se po përdorni një guaskë të ngjashme me sh-në që përdor sintaksën "VARIABLE=value". Nëse jeni duke përdorur një guaskë të ngjashme me csh, atëherë do t'ju duhet të konvertoni shembujt e mi në sintaksën e "vlerës së ndryshueshme setenv" të kërkuar nga ato predha.

Aktualisht, aplikacioni i klientit UDP echo i përgjigjet linjës së mëposhtme të kodit në gërvisht/myfirst.cc,

LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO);

Ai mundëson nivelin e regjistrimit LOG_LEVEL_INFO. Kur kalojmë një flamur të nivelit të regjistrimit, ne në fakt aktivizojmë atë nivel dhe të gjitha nivelet më të ulëta. Në këtë rast, ne kemi aktivizuar NS_LOG_INFO, NS_LOG_DEBUG, NS_LOG_WARN dhe NS_LOG_ERROR. Mund të rrisim nivelin e regjistrimit dhe të marrim më shumë informacion, pa ndryshime skripti dhe ripërpilim, duke vendosur variablin e mjedisit NS_LOG si më poshtë:

$ export NS_LOG=UdpEchoClientApplication=level_all

Pra, ne vendosëm variablin sh shell NS_LOG në vlerën e mëposhtme,

UdpEchoClientApplication=level_all

Ana e majtë e detyrës është emri i komponentit të regjistruar që duam të konfigurojmë, dhe ana e djathtë është flamuri që duam të aplikojmë për të. Në këtë rast, ne do të aktivizojmë të gjitha nivelet e korrigjimit në aplikacion. Nëse e ekzekutoni skriptin me NS_LOG të vendosur në këtë mënyrë, sistemi i regjistrimit ns-3 do të pranojë ndryshimet dhe ju duhet të shihni daljen e mëposhtme:

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.404s)
UdpEchoClientApplication:UdpEchoClient()
UdpEchoClientApplication:SetDataSize(1024)
UdpEchoClientApplication:StartApplication()
UdpEchoClientApplication:ScheduleTransmit()
UdpEchoClientApplication:Send()
Sent 1024 bytes to 10.1.1.2
Received 1024 bytes from 10.1.1.1
UdpEchoClientApplication:HandleRead(0x6241e0, 0x624a20)
Received 1024 bytes from 10.1.1.2
UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()

Informacioni shtesë i korrigjimit të ofruar nga aplikacioni është tani në nivelin NS_LOG_FUNCTION. Ai tregon çdo shembull të një thirrjeje funksioni gjatë ekzekutimit të skriptit. Si rregull i përgjithshëm, në funksionet e metodës preferohet të përdoret (në minimum)NS_LOG_FUNCTION (this). Përdorni NS_LOG_FUNCTION_NOARGS ()
vetëm në funksionet statike. Megjithatë, vini re se sistemi ns-3 nuk kërkohet të mbështesë ndonjë funksionalitet të regjistrimit. Vendimi për sasinë e informacionit të regjistruar i lihet zhvilluesit individual të modelit. Në rastin e aplikacioneve të jehonës, disponohet një sasi e madhe e prodhimit të prerjeve.

Tani mund të shikoni një regjistër të thirrjeve funksionale që janë bërë nga aplikacioni. Nëse shikoni nga afër, do të vini re një dy pika midis vijës Aplikimi UdpEchoClient dhe emrin e metodës, ku mund të prisni të shihni operatorin e fushës së C++ (: :). Kjo është e qëllimshme.

Ky në fakt nuk është emri i klasës, por emri i komponentit të logging. Kur ka një përputhje midis një skedari burimor dhe një klase, zakonisht është emri i klasës, por duhet të kuptoni se në të vërtetë nuk është emri i klasës dhe ka një dy pika të vetme në vend të një dy pika. Kjo është një mënyrë për t'ju ndihmuar të ndani konceptualisht emrin e logging bean nga emri i klasës në një mënyrë relativisht delikate.

Megjithatë, në disa raste mund të jetë e vështirë të përcaktohet se cila metodë në të vërtetë gjeneron mesazhin e regjistrit. Nëse shikoni tekstin e mësipërm, mund të pyesni se ku është rreshti "Received 1024 bytes from 10.1.1.2" Ju mund ta zgjidhni këtë problem duke vendosur nivelin prefiks_func te ndryshorja e mjedisit NS_LOG. Provoni sa vijon:

$ export 'NS_LOG=UdpEchoClientApplication=level_all|prefix_func'

Vini re se thonjëzat janë të nevojshme sepse shiriti vertikal që përdorim për të përfaqësuar operacionin OR është gjithashtu një lidhës i tubit Unix. Tani nëse ekzekutoni skriptin, do të shihni që sistemi i regjistrimit siguron që çdo mesazh në një regjistër të caktuar të jetë prefiksuar me emrin e komponentit.

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.417s)
UdpEchoClientApplication:UdpEchoClient()
UdpEchoClientApplication:SetDataSize(1024)
UdpEchoClientApplication:StartApplication()
UdpEchoClientApplication:ScheduleTransmit()
UdpEchoClientApplication:Send()
UdpEchoClientApplication:Send(): Sent 1024 bytes to 10.1.1.2
Received 1024 bytes from 10.1.1.1
UdpEchoClientApplication:HandleRead(0x6241e0, 0x624a20)
UdpEchoClientApplication:HandleRead(): Received 1024 bytes from 10.1.1.2
UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()

Tani mund të shihni që të gjitha mesazhet që vijnë nga aplikacioni i klientit UDP echo identifikohen si të tilla. mesazh"Received 1024 bytes from 10.1.1.2" tani është identifikuar qartë se vjen nga aplikacioni i klientit echo. Mesazhi i mbetur duhet të vijë nga aplikacioni i serverit echo UDP. Ne mund ta aktivizojmë këtë komponent duke futur një listë të komponentëve të ndarë me dy pika në variablin mjedisor NS_LOG.

$ export 'NS_LOG=UdpEchoClientApplication=level_all|prefix_func:
               UdpEchoServerApplication=level_all|prefix_func'

Paralajmërim: Në shembullin e tekstit të mësipërm, do t'ju duhet të hiqni karakterin e linjës së re pas dy pikave (:), ai përdoret për të formatuar dokumentin. Tani nëse ekzekutoni skriptin, do të shihni të gjitha mesazhet e regjistrit nga aplikacionet e jehonës së klientit dhe serverit. Ju mund të shihni se kjo mund të jetë shumë e dobishme kur korrigjoni.

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.406s)
UdpEchoServerApplication:UdpEchoServer()
UdpEchoClientApplication:UdpEchoClient()
UdpEchoClientApplication:SetDataSize(1024)
UdpEchoServerApplication:StartApplication()
UdpEchoClientApplication:StartApplication()
UdpEchoClientApplication:ScheduleTransmit()
UdpEchoClientApplication:Send()
UdpEchoClientApplication:Send(): Sent 1024 bytes to 10.1.1.2
UdpEchoServerApplication:HandleRead(): Received 1024 bytes from 10.1.1.1
UdpEchoServerApplication:HandleRead(): Echoing packet
UdpEchoClientApplication:HandleRead(0x624920, 0x625160)
UdpEchoClientApplication:HandleRead(): Received 1024 bytes from 10.1.1.2
UdpEchoServerApplication:StopApplication()
UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoServerApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()
UdpEchoServerApplication:~UdpEchoServer()

Nganjëherë është gjithashtu e dobishme të jesh në gjendje të shohësh kohën e simulimit në të cilën është krijuar mesazhi i regjistrit. Ju mund ta bëni këtë duke shtuar bitin OR parashtesa_koha:

$ export 'NS_LOG=UdpEchoClientApplication=level_all|prefix_func|prefix_time: UdpEchoServerApplication=level_all|prefix_func|prefix_time'

Përsëri, do të duhet të hiqni karakterin e mësipërm të linjës së re. Nëse tani e ekzekutoni skriptin, duhet të shihni daljen e mëposhtme:

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)
0s UdpEchoServerApplication:UdpEchoServer()
0s UdpEchoClientApplication:UdpEchoClient()
0s UdpEchoClientApplication:SetDataSize(1024)
1s UdpEchoServerApplication:StartApplication()
2s UdpEchoClientApplication:StartApplication()
2s UdpEchoClientApplication:ScheduleTransmit()
2s UdpEchoClientApplication:Send()
2s UdpEchoClientApplication:Send(): Sent 1024 bytes to 10.1.1.2
2.00369s UdpEchoServerApplication:HandleRead(): Received 1024 bytes from 10.1.1.1
2.00369s UdpEchoServerApplication:HandleRead(): Echoing packet
2.00737s UdpEchoClientApplication:HandleRead(0x624290, 0x624ad0)
2.00737s UdpEchoClientApplication:HandleRead(): Received 1024 bytes from 10.1.1.2
10s UdpEchoServerApplication:StopApplication()
10s UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoServerApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()
UdpEchoServerApplication:~UdpEchoServer()

Ju lutemi vini re se konstruktori për UdpEchoServer u thirr gjatë simulimit 0 sekonda. Kjo në fakt ndodh përpara se të fillojë simulimi, por koha tregohet si zero sekonda. E njëjta gjë vlen edhe për mesazhin e konstruktorit UdpEchoClient.

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)
0s UdpEchoServerApplication:UdpEchoServer()
0s UdpEchoClientApplication:UdpEchoClient()
0s UdpEchoClientApplication:SetDataSize(1024)
1s UdpEchoServerApplication:StartApplication()
2s UdpEchoClientApplication:StartApplication()
2s UdpEchoClientApplication:ScheduleTransmit()
2s UdpEchoClientApplication:Send()
2s UdpEchoClientApplication:Send(): Sent 1024 bytes to 10.1.1.2
2.00369s UdpEchoServerApplication:HandleRead(): Received 1024 bytes from 10.1.1.1
2.00369s UdpEchoServerApplication:HandleRead(): Echoing packet
2.00737s UdpEchoClientApplication:HandleRead(0x624290, 0x624ad0)
2.00737s UdpEchoClientApplication:HandleRead(): Received 1024 bytes from 10.1.1.2
10s UdpEchoServerApplication:StopApplication()
10s UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoServerApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()
UdpEchoServerApplication:~UdpEchoServer()

Kujtojmë se skenari gërvishtje/së pari.cc filloi aplikimin e serverit echo një sekondë para fillimit të simulimit. Tani mund ta shihni këtë metodë StartApplication serveri në fakt thirret në sekondën e parë. Ju gjithashtu mund të vini re se klienti echo fillon në sekondën e dytë të simulimit, siç e kërkuam në skenar.

Tani mund të ndiqni progresin e simulimit në thirrje Program Transmetimi në klientin që thërret HandleRead callback Send në aplikacionin echo server. Vini re se koha e kaluar për të dërguar një paketë mbi një lidhje pikë-për-pikë është 3,69 milisekonda. Ju mund të shihni se serveri echo regjistron një mesazh që i është përgjigjur paketës dhe më pas, pas një vonese të kanalit, shihni që klienti echo merr paketën echo në metodën e tij HandleRead.

Në këtë simulim, shumë gjëra ndodhin pa e vënë re. Por ju mund ta gjurmoni të gjithë procesin shumë lehtë duke aktivizuar të gjithë komponentët e regjistrimit në sistem. Provoni të vendosni variablin NS_LOG në vlerën e mëposhtme,

$ export 'NS_LOG=*=level_all|prefix_func|prefix_time'

Ylli i mësipërm është një karakter wildcard për komponentin logging. Kjo do të përfshijë të gjitha hyrjet në të gjithë komponentët e përdorur në simulim. Nuk do ta riprodhoj daljen këtu (në momentin e shkrimit prodhon 1265 rreshta dalje për një paketë të vetme jehone), por ju mund ta ridrejtoni këtë informacion në një skedar dhe ta shikoni në redaktorin tuaj të preferuar.

$ ./waf --run scratch/myfirst > log.out 2>&1

Unë personalisht e përdor këtë version jashtëzakonisht të përpiktë të prerjeve kur kam një problem dhe nuk e kam idenë se ku shkuan gjërat keq. Unë mund ta ndjek ekzekutimin e kodit mjaft lehtë pa vendosur pika ndërprerjeje dhe pa kaluar nëpër kodin në korrigjues. Unë thjesht mund të redaktoj daljen në redaktorin tim të preferuar dhe të kërkoj atë që pres dhe të shoh diçka të ndodhë që nuk e prisja. Pasi të kem një ide të përgjithshme të asaj që po shkon keq, hidhem në korrigjues për të shqyrtuar problemin. Ky lloj prodhimi mund të jetë veçanërisht i dobishëm kur skripti juaj bën diçka krejtësisht të papritur. Nëse përdorni vetëm korrigjuesin, mund të humbisni krejtësisht një kthesë. Regjistrimi i bën të dukshme kthesat e tilla.

5.1.3 Shtimi i regjistrimit në kodin tuaj

Mund të shtoni hyrje të reja në simulimet tuaja duke bërë thirrje në komponentin e regjistrit nga shumë makro. Le ta bëjmë atë në një skenar i pari im.cc, të cilin e kemi në direktorinë “e pastër”. Kujtoni që ne përcaktuam një komponent të regjistrimit në këtë skenar:

NS_LOG_COMPONENT_DEFINE ("FirstScriptExample");

Jeni të vetëdijshëm se mund të aktivizoni regjistrimin e të gjitha mesazheve nga ky komponent duke vendosur variablin e mjedisit NS_LOG në nivele të ndryshme. Le të shkojmë përpara dhe të shtojmë disa hyrje në skenar. Makroja e përdorur për të shtuar mesazhe të nivelit të informacionit në regjistër është NS_LOG_INFO. Le të shtojmë një mesazh (pak para se të fillojmë të krijojmë nyje) që ju tregon se skripti është në fazën "Krijimi i topologjisë". Kjo bëhet në pjesën e mëposhtme të kodit,
Hapni gërvisht/myfirst.cc në redaktorin tuaj të preferuar dhe shtoni rreshtin,
NS_LOG_INFO ("Creating Topology");
mu përpara rreshtave,

NodeContainer nodes;
nodes.Create (2);

Tani përpiloni skriptin duke përdorur meshë, dhe pastroni variablin NS_LOG për të çaktivizuar rrjedhën e regjistrimit që kemi aktivizuar më parë:

$ ./waf
$ export NS_LOG=
Теперь, если вы запустите скрипт,
$ ./waf --run scratch/myfirst

Ju nuk do ta shihni mesazhin e ri sepse komponenti shoqërues i regjistrimit (FirstScriptExample) nuk është aktivizuar. Për të parë mesazhin tuaj, duhet të aktivizoni komponentin e regjistrimit Shembull FirstScript me një nivel jo më të ulët se NS_LOG_INFO. Nëse thjesht dëshironi të shihni këtë nivel specifik të regjistrimit, mund ta aktivizoni si kjo,

$ export NS_LOG=FirstScriptExample=info

Nëse e ekzekutoni skriptin tani, do të shihni një mesazh të ri "Krijimi i topologjisë".

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.404s)
Creating Topology
Sent 1024 bytes to 10.1.1.2
Received 1024 bytes from 10.1.1.1
Received 1024 bytes from 10.1.1.2

5.2 Përdorimi i argumenteve të linjës së komandës

5.2.1 Mbështetja e vlerave të atributeve të paracaktuara

Një mënyrë tjetër për të ndryshuar sjelljen e skripteve ns-3 pa modifikuar ose ndërtuar është përdorimi i argumenteve të linjës së komandës. Ne ofrojmë një mekanizëm për të analizuar argumentet e linjës së komandës dhe vendosim automatikisht variabla lokale dhe globale bazuar në rezultatet.

Hapi i parë në përdorimin e sistemit të argumenteve të linjës së komandës është deklarimi i një analizuesi të linjës së komandës. Kjo është mjaft e lehtë për t'u bërë (në programin tuaj kryesor), si në kodin e mëposhtëm,

int
main (int argc, char *argv[])
{
...
CommandLine cmd;
cmd.Parse (argc, argv);
...
}

Ky fragment i thjeshtë me dy rreshta është në të vërtetë shumë i dobishëm në vetvete. Ai hap derën për variablin global dhe sistemin e atributeve ns-3. Le të shtojmë dy rreshta kodi në fillim të funksionit të skriptit kryesor gërvisht/myfirst.cc. Duke vazhduar, ne përpilojmë skriptin dhe e ekzekutojmë atë, kur ekzekutojmë bëjmë një kërkesë për ndihmë si më poshtë:

$ ./waf --run "scratch/myfirst --PrintHelp"

Kjo komandë do të pyesë WAF ekzekutoni skenarin gërvisht/i pari dhe kaloni një argument të linjës së komandës —PrintHelp. Thonjëzat kërkohen për të treguar se për cilin program synohet argumenti. Analisti i linjës së komandës do të zbulojë argumentin —PrintHelp dhe do të shfaqë përgjigjen,

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.413s)
TcpL4Protocol:TcpStateMachine()
CommandLine:HandleArgument(): Handle arg name=PrintHelp value=
--PrintHelp: Print this help message.
--PrintGroups: Print the list of groups.
--PrintTypeIds: Print all TypeIds.
--PrintGroup=[group]: Print all TypeIds of group.
--PrintAttributes=[typeid]: Print all attributes of typeid.
--PrintGlobals: Print the list of globals.

Tani le të shohim opsionin —PrintAtributet. Ne kemi përmendur tashmë sistemin e atributeve ns-3 kur studiojmë skriptin e parë.cc. Ne kemi parë linjat e mëposhtme të kodit,

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

dhe ata thanë atë Norma e të Dhënave është në fakt një atribut Pajisja PointToPointNet. Le të përdorim analizuesin e argumentit të linjës së komandës për të parë atributet Pajisja PointToPointNet. Lista e ndihmës thotë se çfarë duhet të ofrojmë TypeId. Ky është emri i klasës së cilës i përkasin atributet e interesit. Në rastin tonë do të jetë ns3 :: pointopointnetDevice. Le të vazhdojmë të ecim përpara, të hyjmë,

$ ./waf --run "scratch/myfirst --PrintAttributes=ns3::PointToPointNetDevice"

Sistemi do të printojë të gjitha atributet e këtij lloji të pajisjes së rrjetit. Do të shihni se ndër atributet në listë janë,

--ns3::PointToPointNetDevice::DataRate=[32768bps]:
The default data rate for point to point links

Kjo është vlera e paracaktuar që do të përdoret nga sistemi gjatë krijimit të objektit Pajisja PointToPointNet. Ne do ta anashkalojmë këtë vlerë të paracaktuar duke përdorur parametrin atribut в PointToPointHelper më të larta. Le të përdorim vlerat e paracaktuara për pajisjet dhe kanalet pikë-për-pikë. Për ta bërë këtë, ne do të fshijmë telefonatat SetDeviceAttribute и SetChannelAttribute nga i pari im.cc, të cilin e kemi në një drejtori të pastër.

Skripti juaj tani thjesht duhet të deklarohet PointToPointHelper dhe mos kryeni asnjë operacion instalimi siç tregohet në shembullin më poshtë,

...
NodeContainer nodes;
nodes.Create (2);
PointToPointHelper pointToPoint;
NetDeviceContainer devices;
devices = pointToPoint.Install (nodes);
...

Shkoni përpara dhe krijoni një skenar të ri me WAF (./waff) dhe le të kthehemi dhe të përfshijmë disa hyrje nga aplikacioni i serverit echo UDP dhe të përfshijmë prefiksin e kohës.

$ export 'NS_LOG=UdpEchoServerApplication=level_all|prefix_time'

Nëse ekzekutoni skriptin, duhet të shihni daljen e mëposhtme:

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.405s)
0s UdpEchoServerApplication:UdpEchoServer()
1s UdpEchoServerApplication:StartApplication()
Sent 1024 bytes to 10.1.1.2
2.25732s Received 1024 bytes from 10.1.1.1
2.25732s Echoing packet
Received 1024 bytes from 10.1.1.2
10s UdpEchoServerApplication:StopApplication()
UdpEchoServerApplication:DoDispose()
UdpEchoServerApplication:~UdpEchoServer()

Kujtojmë që hera e fundit që shikuam kohën e simulimit, në momentin kur paketa u mor nga serveri echo, ishte 2,00369 sekonda.

2.00369s UdpEchoServerApplication:HandleRead(): Received 1024 bytes from 10.1.1.1

Tani ai e merr paketën në 2.25732 sekonda. Kjo ndodh sepse ne thjesht rivendosim shpejtësinë e të dhënave PointToPointNetDevice nga pesë megabit për sekondë në vlerën e paracaktuar, e cila është 32768 bit për sekondë. Nëse do të zëvendësonim një DataRate të re duke përdorur vijën e komandës, ne mund të shpejtojmë përsëri simulimin tonë. Ne do ta bëjmë këtë si më poshtë, sipas formulës së nënkuptuar nga elementi i ndihmës:

$ ./waf --run "scratch/myfirst --ns3::PointToPointNetDevice::DataRate=5Mbps"

Kjo do ta kthejë atributin DataRate në vlerën e tij të paracaktuar prej pesë megabit për sekondë. Jeni i befasuar nga rezultati? Rezulton se për të rikthyer sjelljen origjinale të skenarit, duhet të vendosim gjithashtu vonesën e kanalit që të përputhet me shpejtësinë e dritës. Ne mund t'i kërkojmë sistemit të linjës së komandës të printojë atributet e kanalit, ashtu siç bëmë për pajisjen e rrjetit:

$ ./waf --run "scratch/myfirst --PrintAttributes=ns3::PointToPointChannel"

Do të zbulojmë se atributi i vonesës së kanalit është vendosur si më poshtë:

--ns3::PointToPointChannel::Delay=[0ns]:
Transmission delay through the channel

Më pas, përmes sistemit të linjës së komandës, mund të vendosim të dyja këto vlera të paracaktuara.

$ ./waf --run "scratch/myfirst
--ns3::PointToPointNetDevice::DataRate=5Mbps
--ns3::PointToPointChannel::Delay=2ms"

në këtë rast ne rivendosim kohën që kishim kur vendosëm në mënyrë të qartë DataRate dhe Delay në skript:

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.417s)
0s UdpEchoServerApplication:UdpEchoServer()
1s UdpEchoServerApplication:StartApplication()
Sent 1024 bytes to 10.1.1.2
2.00369s Received 1024 bytes from 10.1.1.1
2.00369s Echoing packet
Received 1024 bytes from 10.1.1.2
10s UdpEchoServerApplication:StopApplication()
UdpEchoServerApplication:DoDispose()
UdpEchoServerApplication:~UdpEchoServer()

Vini re se paketa merret përsëri nga serveri pas 2,00369 sekondash. Në fakt, ne mund të vendosnim ndonjë nga atributet e përdorura në skenar në këtë mënyrë. Në veçanti, ne mund të vendosim atributet MaxPackets në vlera jo-një UdpEchoClient.

Si do ta përdornit? Provojeni. Mos harroni se duhet të komentoni vendin ku ne anashkalojmë vlerën e atributit të paracaktuar dhe vendosim në mënyrë eksplicite MaxPackets në skenar. Pastaj ju duhet të rindërtoni skenarin. Ju gjithashtu mund të përdorni vijën e komandës për të marrë ndihmë sintaksore për vendosjen e një vlere të re të atributit të paracaktuar. Pasi ta kuptoni këtë, mund të kontrolloni numrin e paketave të shfaqura në vijën e komandës. Meqenëse ne jemi njerëz studiozë, linja jonë e komandës duhet të duket diçka si kjo:

$ ./waf --run "scratch/myfirst
--ns3::PointToPointNetDevice::DataRate=5Mbps
--ns3::PointToPointChannel::Delay=2ms
--ns3::UdpEchoClient::MaxPackets=2"

Pyetja e natyrshme që lind në këtë pikë është se si të dimë për ekzistencën e të gjitha këtyre atributeve. Përsëri, sistemi i linjës së komandës ka një funksion ndihmës për këtë çështje. Nëse kërkojmë ndihmë nga rreshti i komandës, duhet të shohim:

$ ./waf --run "scratch/myfirst --PrintHelp"
myfirst [Program Arguments] [General Arguments]
General Arguments:
--PrintGlobals: Print the list of globals.
--PrintGroups: Print the list of groups.
--PrintGroup=[group]: Print all TypeIds of group.
--PrintTypeIds: Print all TypeIds.
--PrintAttributes=[typeid]: Print all attributes of typeid.
--PrintHelp: Print this help message.

Nëse zgjidhni argumentin "PrintGroups", duhet të shihni një listë të të gjitha grupeve të regjistruara TypeId. Emrat e grupeve janë në përputhje me emrat e moduleve në direktorinë burimore (edhe pse me shkronjë të madhe). Printimi i të gjithë informacionit në të njëjtën kohë do të ishte shumë voluminoz, kështu që disponohet një filtër shtesë për të printuar informacionin sipas grupit. Pra, duke u fokusuar përsëri në modulin pikë-për-pikë:

./waf --run "scratch/myfirst --PrintGroup=PointToPoint"
TypeIds in group PointToPoint:
ns3::PointToPointChannel
ns3::PointToPointNetDevice
ns3::PointToPointRemoteChannel
ns3::PppHeader

Këtu mund të gjeni emra të disponueshëm TypeId për kërkimet e atributeve, për shembull në
--PrintAttributes = ns3 :: PointToPointChannelsiç tregohet më sipër.

Një mënyrë tjetër për të mësuar rreth atributeve është përmes Doxygen ns‑3. Ekziston një faqe që liston të gjitha atributet e regjistruara në simulator.

5.2.2 Kapja e komandave tuaja

Ju gjithashtu mund të shtoni grepa tuaj nëpërmjet sistemit të linjës së komandës. Kjo bëhet thjesht duke përdorur metodën e analizës së linjës së komandës AddVlerë.
Le ta përdorim këtë veçori për të specifikuar numrin e paketave që do të shfaqen në një mënyrë krejtësisht të ndryshme. Le të shtojmë një ndryshore lokale të quajtur nPaketa në një funksion kryesor. Ne do ta vendosim atë në një që të përputhet me sjelljen tonë të mëparshme të paracaktuar. Për të lejuar analizuesin e linjës së komandës të ndryshojë këtë vlerë, ne duhet ta kapim këtë vlerë në analizues. Ne e bëjmë këtë duke shtuar një telefonatë AddVlerë. Shkoni dhe ndryshoni skenarin gërvisht/myfirst.cc pra për të filluar me kodin e mëposhtëm,

int
main (int argc, char *argv[])
{
uint32_t nPackets = 1;
CommandLine cmd;
cmd.AddValue("nPackets", "Number of packets to echo", nPackets);
cmd.Parse (argc, argv);
...

Lëvizni poshtë në pikën e skriptit ku kemi vendosur atributin MaxPackets dhe e ndryshojmë atë në mënyrë që të vendoset në variablin nPackets në vend të konstantës 1, siç tregohet më poshtë.

echoClient.SetAttribute ("MaxPackets", UintegerValue (nPackets));

Tani nëse ekzekutoni skriptin dhe jepni argumentin -PrintHelp, duhet të shihni argumentin e ri të përdoruesit. të listuara në ekranin e ndihmës. Hyni,

$ ./waf --run "scratch/myfirst --PrintHelp"
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.403s)
--PrintHelp: Print this help message.
--PrintGroups: Print the list of groups.
--PrintTypeIds: Print all TypeIds.
--PrintGroup=[group]: Print all TypeIds of group.
--PrintAttributes=[typeid]: Print all attributes of typeid.
--PrintGlobals: Print the list of globals.
User Arguments:
--nPackets: Number of packets to echo

Nëse dëshironi të ndryshoni numrin e paketave të transmetuara, mund ta bëni këtë duke vendosur argumentin e linjës së komandës - -nPackets.

$ ./waf --run "scratch/myfirst --nPackets=2"

Tani duhet ta shihni

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.404s)
0s UdpEchoServerApplication:UdpEchoServer()
1s UdpEchoServerApplication:StartApplication()
Sent 1024 bytes to 10.1.1.2
2.25732s Received 1024 bytes from 10.1.1.1
2.25732s Echoing packet
Received 1024 bytes from 10.1.1.2
Sent 1024 bytes to 10.1.1.2
3.25732s Received 1024 bytes from 10.1.1.1
3.25732s Echoing packet
Received 1024 bytes from 10.1.1.2
10s UdpEchoServerApplication:StopApplication()
UdpEchoServerApplication:DoDispose()
UdpEchoServerApplication:~UdpEchoServer()

Tani keni dërguar dy pako. Shumë e thjeshtë, apo jo?
Ju mund të shihni se si një përdorues ns-3, mund të përdorni sistemin e argumentit të linjës së komandës për të manipuluar vlerat dhe atributet globale. Nëse jeni autori i modelit, mund të shtoni atribute të reja në objektet tuaja dhe ato do të jenë automatikisht të disponueshme për konfigurim nga përdoruesit tuaj përmes sistemit të linjës së komandës. Nëse jeni autor i skriptit, mund të shtoni variabla të reja në skriptet tuaja dhe t'i lidhni pa probleme në sistemin tuaj të linjës së komandës.

5.3 Përdorimi i sistemit të gjurmimit

E gjithë pika e modelimit është të gjenerojë rezultate për studime të mëtejshme, dhe sistemi i gjurmës ns-3 është mekanizmi kryesor për këtë. Meqenëse ns-3 është një program C++, mund të përdoren mjete standarde të gjenerimit të prodhimit nga një program C++:

#include <iostream>
...
int main ()
{
...
std::cout << "The value of x is " << x << std::endl;
...
}

Ju madje mund të përdorni një modul logging për të shtuar një strukturë të vogël në zgjidhjen tuaj. Ka shumë probleme të njohura të shkaktuara nga kjo qasje, dhe për këtë arsye ne kemi ofruar një nënsistem të përgjithshëm të gjurmimit të ngjarjeve për të zgjidhur këto probleme.

Qëllimet kryesore të sistemit të gjurmimit ns-3 janë:

  • Për detyrat bazë, sistemi i gjurmimit duhet të lejojë përdoruesin të gjenerojë një gjurmë standarde për burimet e njohura dhe të zgjedhë objektet që gjenerojnë gjurmën;

  • Përdoruesit e ndërmjetëm duhet të jenë në gjendje të zgjerojnë sistemin e gjurmimit për të ndryshuar formatin e prodhimit të gjeneruar ose për të futur burime të reja gjurmësh, pa modifikuar bërthamën e simulatorit;

  • Përdoruesit e avancuar mund të modifikojnë bërthamën e simulatorit për të shtuar burime të reja gjurmësh dhe lavamanë. Sistemi i gjurmimit ns-3 është ndërtuar mbi parimet e burimeve dhe marrësve të pavarur të gjurmimit, si dhe një mekanizëm të unifikuar për lidhjen e burimeve me konsumatorët.

Sistemi i gjurmimit ns-3 është ndërtuar mbi parimet e burimeve dhe marrësve të pavarur të gjurmimit, si dhe një mekanizëm të unifikuar për lidhjen e burimeve me marrësit. Burimet e gjurmës janë objekte që mund të sinjalizojnë ngjarjet që ndodhin në simulim dhe të ofrojnë akses në të dhënat themelore me interes. Për shembull, një burim gjurmimi mund të tregojë kur një pajisje rrjeti ka marrë një paketë dhe të bëjë përmbajtjen e paketës të disponueshme për marrësit e interesuar të gjurmës.

Burimet e gjurmimit më vete janë të padobishme nëse nuk janë të "bashkuara" me pjesë të tjera të kodit që në fakt bëjnë diçka të dobishme me informacionin e dhënë nga lavamani. Gjurmuesit janë konsumatorë të ngjarjeve dhe të dhënave të ofruara nga burimet e gjurmës. Për shembull, mund të krijoni një lavaman gjurmësh që (kur lidhet me burimin e gjurmës së shembullit të mëparshëm) do të printojë pjesët me interes në paketën e marrë.

Arsyeja për këtë ndarje të qartë është që t'i lejojë përdoruesit të lidhin lloje të reja lavaman me burimet ekzistuese të gjurmës pa pasur nevojë të modifikojnë dhe rikompilojnë bërthamën e simulatorit. Pra, në shembullin e mësipërm, përdoruesi mund të përcaktojë një gjurmues të ri në skriptin e tij dhe ta lidhë atë me një burim ekzistues gjurmësh të përcaktuar në bërthamën e simulimit vetëm duke redaktuar skriptin e përdoruesit.

Në këtë tutorial, ne do të kalojmë nëpër disa nga burimet dhe lavamanet e paracaktuara dhe do të tregojmë se si ato mund të konfigurohen me sa më pak përpjekje nga ana e përdoruesit. Shihni seksionet Manuali ns-3 ose si duhet për informacion mbi konfigurimin e avancuar të gjurmës, duke përfshirë zgjerimin e hapësirës së emrave të gjurmës dhe krijimin e burimeve të reja të gjurmës.

5.3.1 Gjurmimi ASCII

ns-3 ofron funksione ndihmëse që ofron një sistem gjurmimi të nivelit të ulët për t'ju ndihmuar me detajet kur vendosni gjurmë të thjeshta paketash. Nëse e aktivizoni këtë veçori, do të shihni daljen në skedarët ASCII. Për ata që janë të njohur me daljen ns-2, ky lloj gjurmimi është i ngjashëm me jashtë.tr, i cili gjenerohet nga shumë skripta.

Le të fillojmë punën dhe të shtojmë disa rezultate gjurmimi ASCII në skriptin tonë scratch/myfirst.cc. Menjëherë përpara thirrjes Simulator :: Run (), shtoni linjat e mëposhtme të kodit:
AsciiTraceHelper ascii;

pointToPoint.EnableAsciiAll (ascii.CreateFileStream ("myfirst.tr"));

Ashtu si shumë idioma të tjera ns-3, ky kod përdor një objekt ndihmës për të krijuar gjurmë ASCII. Rreshti i dytë përmban dy thirrje metodash të mbivendosura. Metoda "Brenda". CreateFileStream() përdor idiomën e objektit anonim për të krijuar një objekt të transmetimit të skedarëve në stek (pa një emër objekti) dhe ia kalon atë metodës së thirrur. Ne do të shkojmë më thellë në këtë në të ardhmen, por gjithçka që duhet të dini në këtë pikë është se po krijoni një objekt që përfaqëson një skedar të quajtur myfirst.tr dhe transferojeni në ns-3. Ne i besojmë ns-3 që të kujdeset për objektin e krijuar gjatë gjithë jetës së tij, gjatë së cilës ai zgjidh problemet e shkaktuara nga një kufizim pak i njohur (i qëllimshëm) i lidhur me konstruktorët e kopjeve të objekteve të transmetimit C++.

Thirrje e jashtme EnableAsciiAll() i thotë asistentit që dëshironi të përfshini gjurmimin ASCII në simulimin tuaj për të gjitha lidhjet e pajisjes pikë-për-pikë dhe se dëshironi që marrësit (të specifikuar) të gjurmës të regjistrojnë informacionin e lëvizjes së paketave në formatin ASCII.

Për ata që janë të njohur me ns-2, ngjarjet e gjurmuara janë ekuivalente me pikat e njohura të gjurmës që regjistrojnë ngjarjet "+", "-", "d" dhe "r".
Tani mund të ndërtoni skriptin dhe ta ekzekutoni atë nga vija e komandës:

$ ./waf --run scratch/myfirst

Si shumë herë më parë, do të shihni disa mesazhe nga Waf, dhe më pas "'ndërtimi' përfundoi me sukses" me disa mesazhe nga programi që po funksionon.

Kur ekzekutohet, programi do të krijojë një skedar me emrin myfirst.tr. Për shkak të natyrës së punës WAF, si parazgjedhje skedari nuk krijohet në drejtorinë lokale, por në drejtorinë e nivelit të lartë të depove. Nëse dëshironi të ndryshoni shtegun ku ruhen gjurmët, atëherë mund të përdorni parametrin Waf për ta specifikuar atë --cwd. Ne nuk e kemi bërë këtë, kështu që për të parë skedarin gjurmues ASCII myfirst.tr në redaktorin tuaj të preferuar, do të na duhet të lundrojmë në drejtorinë e nivelit të lartë të depove tona.

Analiza e gjurmëve ASCII

Ka shumë informacione atje në një formë mjaft të dendur, por gjëja e parë që duhet të vini re është se skedari përbëhet nga rreshta individualë. Kjo do të bëhet qartë e dukshme nëse zgjeroni më gjerë dritaren e shikimit.

Çdo rresht në skedar korrespondon me një ngjarje gjurmuese. Në këtë rast, ne gjurmojmë ngjarjet në radhën e transmetimit të pranishme në çdo pajisje rrjeti pikë-për-pikë në simulim. Radha e transmetimit është radha nëpër të cilën çdo paketë duhet të kalojë për një lidhje pikë-pikë. Vini re se çdo rresht në skedarin e gjurmës fillon me një karakter të vetëm (dhe ka një hapësirë ​​pas tij). Ky simbol do të ketë kuptimin e mëposhtëm:

+: një operacion në radhë ka ndodhur në radhën e pajisjes;
-: në radhën e pajisjes ka ndodhur një operacion i marrjes së elementeve;
d: paketa u hodh, zakonisht sepse radha ishte plot;
r: Paketa u mor nga një pajisje rrjeti.

Le të hedhim një vështrim më të afërt në rreshtin e parë në skedarin e gjurmës. Unë do ta ndaj në pjesë (me dhëmbëzime për qartësi) dhe numrin e rreshtit në të majtë:

0 +
1 2
2 /NodeList/0/DeviceList/0/$ns3::PointToPointNetDevice/TxQueue/Enqueue
3 ns3::PppHeader (
4   Point-to-Point Protocol: IP (0x0021))
6   ns3::Ipv4Header (
7     tos 0x0 ttl 64 id 0 protocol 17 offset 0 flags [none]
8     length: 1052 10.1.1.1 > 10.1.1.2)
9     ns3::UdpHeader (
10      length: 1032 49153 > 9)
11      Payload (size=1024)

Seksioni i parë i kësaj ngjarje gjurmimi të zgjeruar (rreshti 0) është operacioni. Këtu kemi një simbol +, i cili korrespondon me funksionimin e radhës për transmetim. Seksioni i dytë (rreshti 1) është koha e simulimit, e shprehur në sekonda. Ju mund të mbani mend atë që kërkuam Aplikimi UdpEchoClient filloni të dërgoni paketa në dy sekonda. Këtu shohim konfirmimin se kjo po ndodh vërtet.

Seksioni tjetër i shembullit të gjurmës (nga rreshti 2) tregon se cili burim i gjurmës e gjeneroi këtë ngjarje (duke treguar gjurmën e hapësirës së emrit). Ju mund të mendoni për hapësirën e emrave të gjurmës njësoj si një hapësirë ​​e emrave të sistemit të skedarëve. Rrënja e hapësirës së emrave është Lista e nyjeve. Kjo korrespondon me kontejnerin e menaxhuar në kodin kryesor ns-3. Ai përmban të gjitha nyjet që krijohen në skript. Ashtu si një sistem skedari mund të ketë direktori në rrënjë, Lista e nyjeve mund të kemi shumë nyje. Pra, rreshti /NodeList/0 i referohet nyjes null në NodeList, të cilën zakonisht e mendojmë si "nyja 0". Çdo nyje ka një listë të pajisjeve që janë instaluar. Kjo listë ndodhet më pas në hapësirën e emrave. Ju mund të shihni se kjo ngjarje gjurmë vjen nga Lista e pajisjeve/0, e cila është pajisja null e instaluar në nyje.

Nënvargu tjetër, $ ns3 :: PointToPointNetDevice, tregon se cila pajisje është në pozicionin zero: lista e pajisjeve të nyjës zero. Kujtoni se operacioni + i gjetur në rreshtin 0 nënkuptonte që një element u shtua në radhën e transmetimit të pajisjes. Kjo reflektohet në segmentet e fundit të "shtegut të gjurmës": TxQueue/Enqueue.

Seksionet e mbetura në gjurmë duhet të jenë mjaft intuitive. Rreshtat 3-4 tregojnë se paketa është e kapsuluar në një protokoll pikë-për-pikë. Rreshtat 5-7 tregojnë se paketa ka një titull të versionit IP4 dhe e ka origjinën në adresën IP 10.1.1.1 dhe është menduar për 10.1.1.2. Rreshtat 8-9 tregojnë se kjo paketë ka një kokë UDP dhe në fund rreshti 10 tregon se ngarkesa e pritshme është 1024 bajt.

Rreshti tjetër në skedarin e gjurmës tregon se e njëjta paketë u tërhoq nga radha e transmetimit në të njëjtën nyje.

Rreshti i tretë në skedarin e gjurmës tregon se paketa është marrë nga një pajisje rrjeti në hostin e serverit echo. Më poshtë e kam riprodhuar ngjarjen.

0 r
1 2.25732
2 /NodeList/1/DeviceList/0/$ns3::PointToPointNetDevice/MacRx
3   ns3::Ipv4Header (
4     tos 0x0 ttl 64 id 0 protocol 17 offset 0 flags [none]
5     length: 1052 10.1.1.1 > 10.1.1.2)
6     ns3::UdpHeader (
7       length: 1032 49153 > 9)
8       Payload (size=1024)

Vini re se operacioni i gjurmimit tani është r dhe koha e simulimit është rritur në 2,25732 sekonda. Nëse e keni ndjekur me kujdes udhëzuesin, kjo do të thotë se e keni lënë DataRate dhe Vonesa e Lidhjes së pajisjeve të rrjetit në vlerat e tyre të paracaktuara. Kjo kohë duhet të jetë e njohur, siç e patë në pjesën e mëparshme.

Hyrja e hapësirës së emrit të burimit të gjurmës (rreshti 2) është modifikuar për të pasqyruar se kjo ngjarje ka origjinën nga nyja 1 (/Lista e nyjeve/1) dhe paketa merret nga burimi i gjurmës (/MacRx). Duhet të jetë mjaft e lehtë për ju që të ndiqni lëvizjen e paketës përmes topologjisë duke parë gjurmët e mbetura në skedar.

5.3.2 Gjurmë PCAP

Ndihmuesit e pajisjes ns-3 mund të përdoren gjithashtu për të krijuar skedarë gjurmimi në formatin .pcap. Akronimi pcap (zakonisht i shkruar me shkronja të vogla) qëndron për kapjen e paketave dhe në fakt është një API që përfshin përcaktimin e formatit të skedarit .pcap. Programi më popullor që mund të lexojë dhe shfaqë këtë format është Wireshark (i quajtur më parë i papeshë). Megjithatë, ka shumë analizues të gjurmëve të trafikut që përdorin këtë format pakete. Ne inkurajojmë përdoruesit të përdorin mjetet e shumta të disponueshme për të analizuar gjurmët pcap. Në këtë tutorial do të fokusohemi në shikimin e gjurmëve të pcap duke përdorur tcpdump.

Aktivizimi i gjurmimit të pcap bëhet me një rresht kodi.

pointToPoint.EnablePcapAll ("myfirst");

Ngjitni këtë rresht kodi pas kodit të gjurmës ASCII që sapo shtuam gërvisht/myfirst.cc. Vini re se ne kaluam vetëm vargun "myfirst", jo "myfirst.pcap" ose diçka të ngjashme. Kjo është për shkak se parametri është një prefiks, jo një emër i plotë skedari. Gjatë simulimit, asistenti në fakt do të krijojë një skedar gjurmësh për çdo pajisje pikë-për-pikë. Emrat e skedarëve do të ndërtohen duke përdorur parashtesën, numrin e nyjeve, numrin e pajisjes dhe prapashtesën ".pcap'.

Për shembullin e skenarit tonë, do të përfundojmë duke parë skedarë me emrin "myfirst-0-0.pcap"Dhe"myfirst-1-0.pcap", të cilat janë gjurmë pcap për nyjen 0-pajisja 0 dhe nyja 1-pajisja 0 përkatësisht. Pasi të keni shtuar linjën e kodit për të aktivizuar gjurmimin e pcap, mund ta ekzekutoni skriptin në mënyrën e zakonshme:

$ ./waf --run scratch/myfirst

Nëse shikoni në drejtorinë e nivelit të lartë të shpërndarjes suaj, duhet të shihni tre skedarë: një skedar gjurmë ASCII myfirst.tr, të cilat i kemi studiuar më parë, dosjet myfirst-0-0.pcap и myfirst-1-0.pcap - skedarë të rinj pcap që sapo krijuam.

Leximi i daljes me tcpdump

Tani për tani, mënyra më e lehtë për të parë skedarët pcap është të përdorni tcpdump.

$ tcpdump -nn -tt -r myfirst-0-0.pcap
reading from file myfirst-0-0.pcap, link-type PPP (PPP)
2.000000 IP 10.1.1.1.49153 > 10.1.1.2.9: UDP, length 1024
2.514648 IP 10.1.1.2.9 > 10.1.1.1.49153: UDP, length 1024
tcpdump -nn -tt -r myfirst-1-0.pcap
reading from file myfirst-1-0.pcap, link-type PPP (PPP)
2.257324 IP 10.1.1.1.49153 > 10.1.1.2.9: UDP, length 1024
2.257324 IP 10.1.1.2.9 > 10.1.1.1.49153: UDP, length 1024

Në hale myfirst-0-0.pcap (pajisja e klientit) ju mund të shihni se paketa e ekos është dërguar pas 2 sekondash simulimi. Nëse shikoni deponinë e dytë (myfirst-1-0.pcap), do të shihni që paketa është marrë në 2,257324 sekonda. Do të shihni në deponimin e dytë që paketa është kthyer në 2.257324 sekonda, dhe së fundi që paketa është marrë përsëri nga klienti në deponimin e parë në 2.514648 sekonda.

Leximi i daljes me Wireshark

Nëse nuk jeni njohur me Wireshark, ekziston një faqe interneti nga e cila mund të shkarkoni programe dhe dokumentacion: http://www.wireshark.org/. Wireshark është një GUI që mund të përdoret për të shfaqur këto skedarë gjurmë. Nëse keni Wireshark, mund të hapni cilindo nga skedarët e gjurmës dhe të shfaqni përmbajtjen sikur t'i kishit kapur paketat duke përdorur një sniffer paketash.

Burimi: www.habr.com

Shto një koment