Manuali për simulatorin e rrjetit ns-3. Kafsha 5

Manuali për simulatorin e rrjetit ns-3. Kafsha 5
kaptinat 1,2
kafsha 3
kafsha 4

5 Konfigurimi
5.1 Përdorimi i modulit të regjistrimit
5.1.1 Përmbledhje e regjistrimit
5.1.2 Lejimi i regjistrimit
5.1.3 Shtimi i regjistrimit në kodin tuaj
5.2 Përdorimi i argumenteve të linjës së komandës
5.2.1 Shkruaj mbi vlerat e atributit e zakonshme
5.2.2 Kapja e komandave tuaja
5.3 Përdorimi i sistemit të gjurmimit
5.3.1 Gjurmimi ASCII
Parsatimi i gjurmave ASCII
5.3.2 Gjurmimi PCAP

Kapitulli 5

Configuration

5.1 Përdorimi i modulit të regjistrimit

Ne tashmë shikuam në mënyrë të shkurtër modulin e regjistrimit ns-3, duke parë skenarin first.cc. Në këtë kapitull do të hedhim një vështrim më të afërt mbi mundësitë e përdorimit të nënësisë së regjistrimit.

5.1.1 Përmbledhje e regjistrimit

Shumë sisteme të mëdha mbështesin ndonjë mjet për regjistrimin e mesazheve dhe ns-3 nuk është përjashtim. Në disa raste, në «konzolën e operatorit» (e cila zakonisht është stderr në sistemet e bazuara në Unix) regjistrohen vetëm mesazhet e gabimeve. Në sisteme të tjera, mund të shfaqen mesazhe paralajmëruese, si dhe informacione më të detajuara. Në disa raste, mjetet e regjistrimit përdoren për të shfaqur mesazhe ndihmuese të cilat mund të shpejtojnë «shkëputjen» e daljes.

Prerja, e cila përdoret në ns-3, supozon se të gjithë këto nivele informativiteti janë të dobishme dhe ne ofrojmë një qasje selektive, shumë-nivelëshe për regjistrimin e mesazheve. Regjistrimi mund të jetë plotësisht i çaktivizuar, aktivizuar për komponente të veçanta ose në një shkallë globale. Për këtë qëllim, shërbejnë nivelet e informativitetit të personalizuara. Moduli i regjistrimit ns-3 siguron një mënyrë relativisht të thjeshtë për të nxjerrë informacion të dobishëm nga simulimi juaj.

Duhet tĂ« kuptoni se ne ofrojmĂ« njĂ« mekanizĂ«m tĂ« pĂ«rgjithshĂ«m — gjurmimin — pĂ«r tĂ« nxjerrĂ« tĂ« dhĂ«na nga modelet tuaja, tĂ« cilat duhet tĂ« jenĂ« tĂ« preferuara pĂ«r daljen gjatĂ« modelimit (pĂ«r informacione mĂ« tĂ« detajuara rreth sistemit tonĂ« tĂ« gjurmimit, shihni seksionin e manualit 5.3). Regjistrimi duhet tĂ« jetĂ« mĂ«nyra e preferuar pĂ«r tĂ« marrĂ« informacion ndihmĂ«s, paralajmĂ«rimesh, mesazhe gabimesh ose pĂ«r tĂ« nxjerrĂ« shpejt mesazhe nga skenarĂ«t ose modelet tuaja nĂ« çdo moment.

Aktualisht, në sistem janë të përcaktuar shtatë nivele (lloj mesazhesh) regjistri në rritje të informativitetit.

  • LOG_ERROR — regjistrimi i mesazheve tĂ« gabimeve (makro i lidhur: NS_LOG_ERROR);
  • LOG_WARN — regjistrimi i mesazheve paralajmĂ«ruese (makro i lidhur: NS_LOG_WARN);
  • LOG_DEBUG — regjistrimi i mesazheve tĂ« rralla speciale tĂ« depurimit (makro i lidhur: NS_LOG_DEBUG);
  • LOG_INFO — regjistrimi i mesazheve informative pĂ«r ecurinĂ« e programit (makro i lidhur: NS_LOG_INFO);
  • LOG_FUNCTION — regjistrimi i mesazheve qĂ« pĂ«rshkruajnĂ« çdo funksion tĂ« thirrur (dy makro tĂ« lidhura: NS_LOG_FUNCTION, e pĂ«rdorur pĂ«r funksionet anĂ«tare, dhe NS_LOG_FUNCTION_NOARGS, e pĂ«rdorur pĂ«r funksionet statike);
  • LOG_LOGIC — regjistrimi i mesazheve qĂ« pĂ«rshkruajnĂ« rrjedhĂ«n logjike brenda funksionit (makro e lidhur: NS_LOG_LOGIC);
  • LOG_ALL — regjistrimi i gjithçkaje tĂ« pĂ«rmendur mĂ« sipĂ«r (nuk ka makro tĂ« lidhura).
    Për çdo tip (LOG_TYPE) ka gjithashtu një tip LOG_LEVEL_TYPE, i cili, nëse përdoret, lejon regjistrimin përpos nivelit të tij, të gjithë nivelet mbi të. (Si pasojë, LOG_ERROR dhe LOG_LEVEL_ERROR, si 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 me aktivizimin e LOG_LEVEL_INFO do të përfshihen gjithashtu mesazhet e ofruara nga makrot NS_LOG_DEBUG, NS_LOG_WARN dhe NS_LOG_ERROR.

Ne ofrojmë gjithashtu një makro regjistrimi të pakusht përmes të cilit shfaqet gjithmonë, pavarësisht nga niveli i regjistrimit ose përzgjedhja e komponentit.

  • NS_LOG_UNCOND — regjistrimi i mesazheve tĂ« pakusht (pa nivel tĂ« lidhur pĂ«r regjistrim).

Çdo nivel mund tĂ« kĂ«rkohet veçmas ose kumulativisht. Regjistrimi mund tĂ« konfigurohet pĂ«rmes variablĂ«s sĂ« mjedisit sh-NS_LOG ose duke regjistruar thirrjen e funksionit tĂ« sistemit. Siç u tregua mĂ« parĂ«, sistemi i regjistrimit ka dokumentacion Doxygen dhe tani Ă«shtĂ« koha mĂ« e mirĂ« pĂ«r ta shqyrtuar, nĂ«se ende nuk e keni bĂ«rĂ« atĂ«.

Tani që e keni lexuar dokumentacionin shumë në detaje, le të përdorim këto njohuri për të nxjerrë disa informacione interesante nga një skenar shembull scratch/myfirst.cc, i cili ju e keni kompiluar tashmë.

5.1.2 Lejimi i regjistrimit

Le të përdorim variablën mjedisore NS_LOG për të regjistruar disa regjistrime të tjera, por fillimisht, thjesht për t'u orientuar, ekzekutoni skriptin e fundit, ashtu siç e keni bërë më parë,

$ ./waf --run scratch/myfirst

Duhet të shihni dalje të njohur nga programi i parë shembull ns-3

$ Waf: Hyrja në direktorinë `home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Dalja nga direktoria `home/craigdo/repos/ns-3-allinone/ns-3-dev/build' 'build'
përfundoi me sukses (0.413s)
Dërguar 1024 byte në 10.1.1.2
Marrë 1024 byte nga 10.1.1.1
Marrë 1024 byte nga 10.1.1.2

Duket se mesazhet "dërguar" dhe "marrë" që shihni më sipër, në të vërtetë janë mesazhe të regjistruara nga UdpEchoClientApplication dhe UdpEchoServerApplication. Për shembull, mund të kërkojmë që aplikacioni klient të printojë informacion të shtuar, duke vendosur nivelin e regjistrimit përmes variablës së mjedisit NS_LOG.

Nga ky moment, do të supozoj që po përdorni një shell të ngjashëm me sh, e cila përdor sintaksën "VARIABLE = value". Nëse po përdorni një shell të ngjashëm me csh, atëherë do t'ju duhet të konvertoni shembujt e mi në sintaksën "setenv variable value" që kërkohet nga këto shell.

Aktualisht, aplikacioni UDP echo client përgjigjet ndaj kësaj linje kode në scratch/myfirst.cc,

LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO);

Kjo aktivizon nivelin e regjistrimit LOG_LEVEL_INFO. Kur kalojmë një flamur të nivelit të regjistrimit, në të vërtetë aktivizojmë atë nivel dhe të gjitha nivelet më të ulta. Në këtë rast, aktivizuam 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 e ndryshuar skenarin dhe pa e rikompiluar, duke vendosur variablën e mjedisit NS_LOG ashtu si më poshtë:

$ export NS_LOG=UdpEchoClientApplication=level_all

Kështu kemi vendosur vlerën e mëposhtme për variablën NS_LOG në shell-in sh:

UdpEchoClientApplication=level_all

Ana e majtë e caktimit është emri i komponentit të regjistruar që duam të konfigurojmë, ndersa ana e djathtë është flamuri që duam të aplikojmë për këtë. Në këtë rast, do të aktivizojmë të gjitha nivelet e kësaj aplikacioni për regjistrim. Nëse e ekzekutoni skenarin me NS_LOG të vendosur në këtë mënyrë, sistemi i regjistrimit të ns-3 do të pranojë ndryshimet dhe duhet të shihni këtë dalje:

Waf: Hyrja në direktorinë `home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Dalja nga direktoria `home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' përfundoi me sukses (0.404s)
UdpEchoClientApplication:UdpEchoClient()
UdpEchoClientApplication:SetDataSize(1024)
UdpEchoClientApplication:StartApplication()
UdpEchoClientApplication:ScheduleTransmit()
UdpEchoClientApplication:Send()
Dërguar 1024 byte në 10.1.1.2
Marrë 1024 byte nga 10.1.1.1
UdpEchoClientApplication:HandleRead(0x6241e0, 0x624a20)
Marrë 1024 byte nga 10.1.1.2
UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()

Informacioni shtesë për gabimet, e ofruar nga aplikacioni, tani është në niveli NS_LOG_FUNCTION. Ajo tregon çdo rast të thirrjes së funksioneve gjatë ekzekutimit të skriptit. Si rregull, në funksionet-metoda preferohet të përdoret (minimalisht)NS_LOG_FUNCTION (this). Përdorni NS_LOG_FUNCTION_NOARGS ()
vetëm në funksionet statike. Megjithatë, mbani parasysh se në sistemin ns-3 nuk ka kërkesa për të mbështetur cilëndo funksionalitet të regjistrimit. Vendimi se sa informacion regjistrohet mbetet individualisht për zhvilluesin e modelit. Në rastin e aplikacioneve echo, ka shumë të dhëna të disponueshme për regjistrim.

Tani mund të shihni regjistrin e thirrjeve të funksioneve që janë bërë nga aplikacioni. Nëse shikoni me kujdes, do të vini re një dy pikë midis rreshtit UdpEchoClientApplication dhe emrit të metodës, në atë vend ku ndoshta prisnit të shihni operatën e fushës së pamjes C++ (: :). Kjo është bërë me vetëdije.

Në të vërtetë, kjo nuk është emri i klasës, por emri i komponentit të regjistrimit. Kur ka një përputhje midis skedarit burimor dhe klasës, zakonisht ky është emri i klasës, por duhet të kuptoni se në të vërtetë kjo nuk është emri i klasës, dhe aty ka një dy pikë në vend të dy pikave të dyfishta. Kjo është një mënyrë për t'ju ndihmuar në një mënyrë relativisht të hollë të konceptualizoni ndarjen e emrit të komponentit të regjistrimit nga emri i klasës.

MegjithatĂ«, nĂ« disa raste, mund tĂ« jetĂ« e vĂ«shtirĂ« tĂ« identifikoni se cili metodĂ« nĂ« tĂ« vĂ«rtetĂ« gjeneron mesazhin e regjistrit. NĂ«se shikoni tekstin mĂ« sipĂ«r, do tĂ« keni njĂ« pyetje se ku erdhi rreshti “Received 1024 bytes from 10.1.1.2”. Mund ta zgjidhni kĂ«tĂ« çështje duke vendosur nivelin prefix_func nĂ« variablĂ«n mjedisore NS_LOG. Provoni tĂ« bĂ«ni kĂ«tĂ«,

$ export 'NS_LOG=UdpEchoClientApplication=level_all|prefix_func'

Kujtoni se thonjezat janë të nevojshme, pasi shenja vertikale që ne përdorim për të treguar operacionin OSE, gjithashtu është një lidhës i tubave Unix. Tani, nëse e ekzekutoni skriptin, do të shihni se sistemi i regjistrimit siguron që çdo mesazh nga ky regjistër ka një prefiks me emrin e komponentit.

Waf: Po hyjnlën në dosjen `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build`
Waf: Po del nga dosja `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build`
'build' përfundoi me sukses (0.417s)
UdpEchoClientApplication:UdpEchoClient()
UdpEchoClientApplication:SetDataSize(1024)
UdpEchoClientApplication:StartApplication()
UdpEchoClientApplication:ScheduleTransmit()
UdpEchoClientApplication:Send()
UdpEchoClientApplication:Send(): Dërguar 1024 byte te 10.1.1.2
Marrë 1024 byte nga 10.1.1.1
UdpEchoClientApplication:HandleRead(0x6241e0, 0x624a20)
UdpEchoClientApplication:HandleRead(): Marrë 1024 byte nga 10.1.1.2
UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()

Tani mund të shihni se të gjitha mesazhet që vijnë nga aplikacioni UDP echo-client janë identifikuar si të tilla. Mesazhi "Received 1024 bytes from 10.1.1.2" tani është qartë i përcaktuar si që vjen nga aplikacioni echo-client. Mesazhi i mbetur duhet të vijë nga aplikacioni UDP echo-server. Ne mund ta aktivizojmë këtë komponent duke futur një listë komponentesh të ndara me dy pikë në variablën mjedisore NS_LOG.

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

Kujdes: Në shembullin e mësipërm, do t'ju duhet të hiqni karakterin e re të vijës pas dy pikës (:), ai është përdorur për formatimin e dokumentit. Tani, nëse e ekzekutoni skenarin, do të shihni të gjitha mesazhet e regjistrit nga klienti dhe serveri echo-aplikacioneve. Mund të shihni se kjo mund të jetë shumë e dobishme gjatë ndihmës.

Waf: Po hyjnlën në dosjen `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build`
Waf: Po del nga dosja `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build`
'build' përfundoi me sukses (0.406s)
UdpEchoServerApplication:UdpEchoServer()
UdpEchoClientApplication:UdpEchoClient()
UdpEchoClientApplication:SetDataSize(1024)
UdpEchoServerApplication:StartApplication()
UdpEchoClientApplication:StartApplication()
UdpEchoClientApplication:ScheduleTransmit()
UdpEchoClientApplication:Send()
UdpEchoClientApplication:Send(): Dërguar 1024 byte te 10.1.1.2
UdpEchoServerApplication:HandleRead(): Marrë 1024 byte nga 10.1.1.1
UdpEchoServerApplication:HandleRead(): Duke e kthyer paketën
UdpEchoClientApplication:HandleRead(0x624920, 0x625160)
UdpEchoClientApplication:HandleRead(): Marrë 1024 byte nga 10.1.1.2
UdpEchoServerApplication:StopApplication()
UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoServerApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()
UdpEchoServerApplication:~UdpEchoServer()

Gjithashtu ndonjëherë është e dobishme të keni mundësinë të shihni kohën e modelimit në të cilën është krijuar mesazhi i regjistrit. Ju mund ta bëni këtë duke shtuar një bit të tipit OSE prefix_time:

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

Përsëri, do t'ju duhet të hiqni karakterin e ri të vijës. Nëse tani ekzekutoni skenarin, duhet të shihni rezultatin e mëposhtëm:

Waf: Duke në direktorinë `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build`
Waf: Duke lënë direktorinë `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build`
'build' përfundoi me sukses (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(): Dërguar 1024 bytes në 10.1.1.2
2.00369s UdpEchoServerApplication:HandleRead(): Marrë 1024 bytes nga 10.1.1.1
2.00369s UdpEchoServerApplication:HandleRead(): Duke e hedhur paketën
2.00737s UdpEchoClientApplication:HandleRead(0x624290, 0x624ad0)
2.00737s UdpEchoClientApplication:HandleRead(): Marrë 1024 bytes nga 10.1.1.2
10s UdpEchoServerApplication:StopApplication()
10s UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoServerApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()
UdpEchoServerApplication:~UdpEchoServer()

Vini re se konstruktori për UdpEchoServer u thirr gjatë simulimit 0 sekonda. Kjo ndodh në të vërtetë para fillimit të simulimit, por ky kohë shfaqet si zero sekonda. E njëjta gjë është e vërtetë për mesazhin e konstruktorit UdpEchoClient.

Waf: Duke në direktorinë `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build`
Waf: Duke lënë direktorinë `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build`
'build' përfundoi me sukses (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(): Dërguar 1024 bytes në 10.1.1.2
2.00369s UdpEchoServerApplication:HandleRead(): Marrë 1024 bytes nga 10.1.1.1
2.00369s UdpEchoServerApplication:HandleRead(): Duke e hedhur paketën
2.00737s UdpEchoClientApplication:HandleRead(0x624290, 0x624ad0)
2.00737s UdpEchoClientApplication:HandleRead(): Marrë 1024 bytes nga 10.1.1.2
10s UdpEchoServerApplication:StopApplication()
10s UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoServerApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()
UdpEchoServerApplication:~UdpEchoServer()

Le të kujtojmë se skripti scratch/first.cc nisi aplikacionin e serverit echo një sekondë përpara fillimit të simulimit. Tani mund të shihni se metoda StartApplication e serverit thirret në të vërtetë 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ë skript.

Tani mund tĂ« ndiqni pĂ«rparimin e simulimit pĂ«rmes thirrjes ScheduleTransmit nĂ« klient, i cili thĂ«rret dĂ«rgimin e funksionit HandleRead nĂ« aplikacionin e serverit echo. Vini re se koha e kaluar pĂ«r tĂ« dĂ«rguar paketĂ«n nĂ« lidhjen dy-pikĂ«she Ă«shtĂ« 3.69 milisekonda. ËshtĂ« e qartĂ« se serveri echo regjistron njĂ« mesazh se ai i Ă«shtĂ« pĂ«rgjigjur paketĂ«s, dhe pastaj, pas njĂ« vonese tĂ« kanalit, ju shihni se klienti echo merr paketĂ«n e echo nĂ« metodĂ«n e tij HandleRead.

Në këtë simulim shumë gjëra ndodhin në mënyrë të padukshme për ju. Por mund ta ndiqni lehtësisht të gjithë procesin duke aktivizuar të gjitha komponentët e regjistrimeve në sistem. Mundohuni të vendosni në variablin NS_LOG vlerën e mëposhtme,

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

Yllja më sipër është një karakter zëvendësimi për komponentin e regjistrimit. Kjo do të aktivizojë të gjitha regjistrimet në të gjitha komponentët e përdorura në simulim. Nuk do të riprodhoj daljen këtu (në momentin e shkrimit prodhon 1265 rreshta të daljes për një paketë echo), por mund ta redirektoni këtë informacion në një skedar dhe ta shqyrtoni në redaktorin tuaj të preferuar,

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

Personalmente, unë përdor këtë version të tepruar të regjistrimit kur kam një problem dhe nuk kam asnjë ide se ku ka shkuar gabim. Mund ta ndjek lehtësisht ekzekutimin e kodit pa vendosur pika ndalimi dhe duke hapur kodin në debugger. Mund të redaktoj thjesht daljen në redaktorin tim të preferuar dhe të kërkoj atë që pres, duke parë se çfarë po ndodh që nuk e prisja. Kur kam një ide të përgjithshme se çfarë po shkon keq, kaloj në debugger për të hetuar thellësisht çështjen. Ky lloj regjistrimi 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 debugger-in, mund të humbisni plotësisht një kthesë të papritur. Regjistrimi bën që këto kthesa të jenë të dukshme.

5.1.3 Shtimi i regjistrimit në kodin tuaj

Mund të shtoni regjistrime të reja në simulatoret tuaja duke bërë thirrje në komponentin log nga disa makro. Le të bëjmë këtë në skriptin myfirst.cc, i cili ndodhet në direktorinë "të pastër". Kujtojmë se kemi përcaktuar në këtë skript komponentin e regjistrimit:

NS_LOG_COMPONENT_DEFINE ("FirstScriptExample");

Ju e dini që mund të aktivizoni regjistrimin e të gjitha mesazheve të këtij komponenti duke vendosur variablën mjedisore NS_LOG në nivele të ndryshme. Le të vazhdojmë dhe shtojmë disa regjistrime në skript. Makro që përdoret për të shtuar mesazhe regjistrimi në nivel informativ është NS_LOG_INFO. Le të shtojmë një mesazh (menjëherë para se të fillojmë krijimin e nyjeve), që tregon se skripti është në fazën e krijimit të topologjisë ("Krijimi i Topologjisë"). Kjo bëhet në fragmentin e mëposhtëm të kodit,
Hapni scratch/myfirst.cc në redaktorin tuaj të preferuar dhe shtoni rreshtin,
NS_LOG_INFO ("Krijimi i Topologjisë");
shkurt para rreshtave,

NodeContainer nodes;
nodes.Create (2);

Tani kompilo skriptin, duke përdorur waf, dhe pastro variablën NS_LOG, për të çaktivizuar rrjedhën e regjistrimit që aktivizuam më parë:

$ ./waf
$ export NS_LOG=
Tani, nëse e ekzekutoni skriptin,
$ ./waf --run scratch/myfirst

nuk do të shihni mesazhin e ri, pasi komponenti i regjistrimit i lidhur (FirstScriptExample) nuk është aktivizuar. Për të parë mesazhin tuaj, duhet ta aktivizoni komponentin e regjistrimit FirstScriptExample me një nivel jo më të ulët se NS_LOG_INFO. Nëse thjesht dëshironi të shihni këtë nivel të veçantë regjistrimi, mund ta aktivizoni kështu,

$ export NS_LOG=FirstScriptExample=info

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

Waf: Po hyj në drejtori `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Po largohem nga drejtoria `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' përfundoi me sukses (0.404s)
Krijimi i Topologjisë
Dërguar 1024 bytes në 10.1.1.2
Marrë 1024 bytes nga 10.1.1.1
Marrë 1024 bytes nga 10.1.1.2

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

5.2.1 Shkruaj mbi vlerat e atributit e zakonshme

Një mënyrë tjetër për të ndryshuar sjelljen e skripteve ns-3 pa bërë redaktim dhe ndërtim ë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 për të vendosur automatikisht variablat lokale dhe globale në bazë të rezultateve.

Hapi i parë në përdorimin e sistemit të argumenteve të linjës së komandës është shpallja e parser-it të linjës së komandës. Kjo është e thjeshtë për ta 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 vetë. Ai hap derën për variablin global ns-3 dhe sistemin e atributeve. Le të shtojmë dy rreshta kodi në fillim të funksionit kryesor të skriptit. scratch/myfirst.cc. Duke e vazhduar, ne e ndërtojmë skriptin dhe e fillojmë atë, duke kërkuar ndihmë në këtë mënyrë,

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

Ky komand do të kërkojë Waf të ekzekutojë skriptin scratch/myfirst dhe t'i kalojë atij një argument të linjës së komandës --PrintHelp. Thonjëzat janë të nevojshme për të treguar se për cilën program është argumenti. Parser-i i linjës së komandës do ta zbulojë argumentin --PrintHelp dhe do të japë një përgjigje,

Waf: Po hyj në drejtori `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Po largohem nga drejtoria `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' përfundoi me sukses (0.413s)
TcpL4Protocol:TcpStateMachine()
CommandLine:HandleArgument(): Trajto argumentin emri=PrintHelp vlera=
--PrintHelp: Printo këtë mesazh ndihmës.
--PrintGroups: Printo listën e grupeve.
--PrintTypeIds: Printo të gjitha TypeIds.
--PrintGroup=[grupi]: Printo të gjitha TypeIds të grupit.
--PrintAttributes=[typeid]: Printo të gjitha atributet e typeid.
--PrintGlobals: Printo listën e globaleve.

Tani le të shqyrtojmë opsionin --PrintAttributes. Ne tashmë e përmendëm sistemin e atributeve ns-3, kur studionim skriptin first.cc. Ne pamë këto rreshta kodi,

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

dhe thamë se DataRate në të vërtetë është një atribut PointToPointNetDevice. Le të përdorim parser-in e argumenteve të linjës së komandës për të parë atributet. PointToPointNetDevice. Lista e ndihmës tregon se ne duhet të ofrojmë TypeIdKy është emri i klasës, të cilës i përkasin atributet e interesit. Në rastin tonë, kjo do të jetë ns3::PointToPointNetDevice. Të vazhdojmë përpara, ju lutem shkruani

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

Sistemi do të printojë të gjitha atributet e këtij lloji të pajisjes rrjet, dhe do të shihni se ndër atributet në listë janë

--ns3::PointToPointNetDevice::DataRate=[32768bps]:
Shpejtësia e të dhënave të paracaktuar për lidhjet pikë në pikë

Ky është një vlerë e paracaktuar që do të përdoret në sistem gjatë krijimit të objektit PointToPointNetDevice. Ne do ta tejkalojmë këtë vlerë të paracaktuar me parametrin Atributi në PointToPointHelper në të kaluarën. Le të përdorim vlerat e paracaktuara për pajisjet dhe kanalet pikë në pikë. Për këtë, do të heqim thirrjet SetDeviceAttribute dhe SetChannelAttribute nga myfirst.cc, të cilat i kemi në drejtorinë e pastër.

Skripti juaj tani duhet thjesht të shpallë PointToPointHelper dhe të mos kryejë asnjë operacion vendosës, siç tregohet në shembullin më poshtë,

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

Vazhdoni dhe krijoni një skript të ri me Waf (. /waf) dhe le të kthehemi prapa dhe të aktivizojmë disa logime nga aplikacioni server UDP echo dhe të përfshijmë prefiksin e kohës.

$ export 'NS_LOG=UdpEchoServerApplication=level_all|prefix_time'

Nëse e aktivizoni skriptin, duhet të shihni këtë output:

Waf: Duke hyrë në drejtori ` /home/craigdo/repos/ns-3-allinone/ns-3-dev/build' 
Waf: Duke lënë drejtori ` /home/craigdo/repos/ns-3-allinone/ns-3-dev/build' 
'build' përfundoi me sukses (0.405s) 
0s UdpEchoServerApplication:UdpEchoServer() 
1s UdpEchoServerApplication:StartApplication() 
Dërguar 1024 bytes në 10.1.1.2 
2.25732s Marrë 1024 bytes nga 10.1.1.1 
2.25732s Duke kthyer paketë 
Marrë 1024 bytes nga 10.1.1.2 
10s UdpEchoServerApplication:StopApplication() 
UdpEchoServerApplication:DoDispose() 
UdpEchoServerApplication:~UdpEchoServer()

Të kujtojmë se herën e fundit kur shikuam gjatë kohës së simulimit, momenti i marrjes së paketës nga serveri echo ishte në 2.00369 sekonda.

2.00369s UdpEchoServerApplication:HandleRead(): Marrë 1024 bytes nga 10.1.1.1

Tani ai merr paketën në 2.25732 sekonda. Kjo është sepse thjesht e kemi ulur shpejtësinë e transmetimit PointToPointNetDevice nga pesë megabit në sekondë në vlerën e paracaktuar, e cila është 32768 bits në sekondë. Nëse do të kishim vendosur një DataRate të ri me anë të vijës së komandës, mund të shpejtonim përsëri simulimin tonë. Do ta bëjmë këtë në mënyrën e mëposhtme, sipas formulës, të nënkuptuar nga elementi i ndihmës:

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

Si pasqyra në atributin DataRate do të kthehet në pesë megabita për sekondë. A jeni të befasuar nga rezultati? Duket se për të rikthyer sjelljen fillestare të skenarit, na nevojitet gjithashtu të vendosim vonesën e kanalit përkatëse me shpejtësinë e dritës. Mund të kërkojmë që sistemi i komandave të printojë atributet e kanalit, ashtu si bëmë për pajisjen rrjetike:

$ ./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]:
Vonesa e transmetimit përmes kanalit

Më pas mund të vendosim të dy këto vlera si parazgjedhje përmes sistemit të komandave,

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

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

Waf: Duke hyrë në drejtorinë `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Duke lënë drejtorinë `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' përfundoi me sukses (0.417s)
0s UdpEchoServerApplication:UdpEchoServer()
1s UdpEchoServerApplication:StartApplication()
Dërguar 1024 byte për 10.1.1.2
2.00369s Marrë 1024 byte nga 10.1.1.1
2.00369s Duke echo-paketën
Marrë 1024 byte nga 10.1.1.2
10s UdpEchoServerApplication:StopApplication()
UdpEchoServerApplication:DoDispose()
UdpEchoServerApplication:~UdpEchoServer()

Vini re se paketa u mor përsëri nga serveri pas 2,00369 sekundash. Mund ta vendosim në këtë mënyrë çfarëdo nga atributet që përdoren në skenar. Në veçanti, mund të vendosim vlera të ndryshme nga njëlloj për atributet MaxPackets UdpEchoClient.

Si do ta përdornit këtë? Provoni. Mos harroni se duhet ta komentonit atë pjesë ku ne tejkalojmë vlerën e atributit parazgjedhor dhe vendosim qartë MaxPackets në skenar. Pastaj duhet të rindërtoni skenarin. Mund të merrni gjithashtu ndihmë në sistemin e komandave për sintaksën e vendosjes së vlerës së re të atributit parazgjedhës. Pasi të kuptoni këtë, do të jeni në gjendje të menaxhoni numrin e paketimeve që shfaqen në komandën e linjës. Duke qenë njerëz të kujdesshëm, komanda jonë duhet të duket kështu:

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

Pyesja natyrshme që lind këtu është si të mësojmë për ekzistencën e të gjithë këtyre atributeve. Edhe një herë, sistemi i komandave ka një funksion ndihmës për këtë çështje. Nëse kërkojmë ndihmë nga sistemi i komandave, 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 përputhen me emrat e moduleve në direktorinë burimore (ndonëse me shkronjë të madhe). Printimi i të gjitha informacionit njëherësh do të ishte shumë i volitshëm, prandaj është në dispozicion një filtrues shtesë për të printuar informacionin sipas grupeve. Pra, duke u përqendruar përsëri në modulon "pikë-në-pikë":

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

Këtu mund të gjeni emrat e disponueshëm të TypeId për të kërkuar atributet, për shembull, në
--PrintAttributes = ns3::PointToPointChannel, siç është treguar më lart.

NjĂ« mĂ«nyrĂ« tjetĂ«r pĂ«r tĂ« mĂ«suar pĂ«r atributet Ă«shtĂ« pĂ«rmes Doxygen ns‑3. Aty ka njĂ« faqe qĂ« rendit tĂ« gjitha atributet e regjistruara nĂ« simulator.

5.2.2 Kapja e komandave tuaja

Ju gjithashtu mund të shtoni përshtatjet tuaja përmes sistemit të komandave. Kjo është bërë mjaft lehtë me metodën e analizuesit të komandave AddValue.
Le të përdorim këtë mundësi për të caktuar numrin e paketa që duhet të shfaqen, një mënyrë krejt tjetër. Le të shtojmë një variabël lokale me emrin nPackets në funksionin main. Ne do ta vendosim atë në një, që përputhet me sjelljen tonë të mëparshme të parazgjedhur. Për të lejuar analizuesin e komandave të ndryshojë këtë vlerë, na nevojitet të kapim këtë vlerë në analizues. Ne e bëjmë këtë duke shtuar thirrjen AddValue. Shkoni dhe ndryshoni skriptin scratch/myfirst.cc në mënyrë që të filloni me kodin e mëposhtëm,

int
main (int argc, char *argv[])
{
uint32_t nPackets = 1;
CommandLine cmd;
cmd.AddValue("nPackets", "Numri i paketimeve për të echo", nPackets);
cmd.Parse (argc, argv);
...

Shkruani deri në pikën në skript ku ne caktuam atributin MaxPackets dhe ndryshoni atë në mënyrë që të përputhet me variablën nPackets në vend të konstantës 1, siç është treguar më poshtë.

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

Tani, nëse e ekzekutoni skriptin dhe vendosni argumentin --PrintHelp, duhet të shihni një argument të ri të përdoruesit. i renditur në ekranin e ndihmës. Shkruani,

$ .\/waf --run "scratch\/myfirst --PrintHelp"
Waf: Duke në direktorinë `\/home\/craigdo\/repos\/ns-3-allinone\/ns-3-dev\/build'
Waf: Duke lënë direktorinë `\/home\/craigdo\/repos\/ns-3-allinone\/ns-3-dev\/build'
'ndërtimi' përfundoi me sukses (0.403s)
--PrintHelp: Shfaq këtë mesazh ndihme.
--PrintGroups: Shfaq listën e grupeve.
--PrintTypeIds: Shfaq të gjitha TypeIds.
--PrintGroup=[grupi]: Shfaq të gjitha TypeIds të grupit.
--PrintAttributes=[typeid]: Shfaq të gjitha atributet e typeid.
--PrintGlobals: Shfaq listën e globaleve.
Argumentet e Përdoruesit:
--nPackets: Numri i paketave për t'u përsëritur

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

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

Tani duhet të shihni

Waf: Duke hyrë në direktorinë `\/home\/craigdo\/repos\/ns-3-allinone\/ns-3-dev\/build'
Waf: Duke lënë direktorinë `\/home\/craigdo\/repos\/ns-3-allinone\/ns-3-dev\/build'
'ndërtimi' përfundoi me sukses (0.404s)
0s UdpEchoServerApplication:UdpEchoServer()
1s UdpEchoServerApplication:Filloni Aplikacionin()
Dërguar 1024 byte te 10.1.1.2
2.25732s Marrë 1024 byte nga 10.1.1.1
2.25732s Përsëritja e paketës
Marrë 1024 byte nga 10.1.1.2
Dërguar 1024 byte te 10.1.1.2
3.25732s Marrë 1024 byte nga 10.1.1.1
3.25732s Përsëritja e paketës
Marrë 1024 byte nga 10.1.1.2
10s UdpEchoServerApplication:Ndalo Aplikacionin()
UdpEchoServerApplication:DoDispose()
UdpEchoServerApplication:~UdpEchoServer()

Tani keni dërguar dy paketa. Mjaft e thjeshtë, apo jo?
Mund tĂ« shihni se si pĂ«rdorues i ns‑3, mund tĂ« pĂ«rdorni sistemin e argumenteve tĂ« linjĂ«s sĂ« komandĂ«s pĂ«r tĂ« menaxhuar vlerat globale dhe atributet. NĂ«se jeni autor modeli, mund tĂ« shtoni atributet e 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 skenari, mund tĂ« shtoni variabla tĂ« reja nĂ« skenaret tuaja dhe t'i lidhni ato pa probleme me sistemin e linjĂ«s sĂ« komandĂ«s.

5.3 Përdorimi i sistemit të gjurmimit

QĂ«llimi kryesor i modelimit Ă«shtĂ« tĂ« krijoni dalje pĂ«r studim tĂ« mĂ«tejshĂ«m, dhe sistemi i gjurmimit ns‑3 Ă«shtĂ« mekanizmi kryesor pĂ«r kĂ«tĂ«. Duke qenĂ« se ns‑3 Ă«shtĂ« njĂ« program nĂ« C++, mund tĂ« pĂ«rdoren mjetet standarde pĂ«r gjenerimin e daljeve nĂ« programin C++:

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

Madje mund të përdorni modulimin e regjistrimit për të shtuar një strukturë të vogël në zgjidhjen tuaj. Një numër problemesh janë të njohura që lindin nga ky qasje dhe prandaj për t'i zgjidhur ato, ne ofrojmë një nën sistem të përgjithshëm për gjurmimin e ngjarjeve.

QĂ«llimet kryesore tĂ« sistemit tĂ« gjurmimit ns‑3:

  • PĂ«r detyrat bazĂ«, sistemi i gjurmimit duhet t'i lejojĂ« pĂ«rdoruesit tĂ« gjenerojĂ« gjurmime standarde pĂ«r burime tĂ« njohura dhe tĂ« zgjedhĂ« objektet qĂ« gjenerojnĂ« gjurmim;

  • PĂ«rdoruesit e ndĂ«rmjetĂ«m duhet tĂ« kenĂ« mundĂ«sinĂ« tĂ« zgjasin sistemin e gjurmimit pĂ«r tĂ« ndryshuar formatin e daljes sĂ« gjeneruar ose pĂ«r tĂ« futur burime tĂ« reja gjurmimi, pa modifikuar bĂ«rthamĂ«n e simulatorit;

  • PĂ«rdoruesit e avancuar mund tĂ« modifikojnĂ« bĂ«rthamĂ«n e simulatorit pĂ«r tĂ« shtuar burime dhe marrĂ«s tĂ« rinj tĂ« gjurmimit. Sistemi i gjurmimit ns-3 Ă«shtĂ« ndĂ«rtuar mbi parimet e burimeve tĂ« pavarura tĂ« ndjekjes dhe marrĂ«sve, si dhe mbi 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 mbi një mekanizëm të unifikuar për lidhjen e burimeve me marrësit. Burimet e gjurmimit janë objekte që mund të sinjalizojnë ngjarjet që ndodhin në simulim dhe të sigurojnë qasje në të dhënat thelbësore të interesit. Për shembull, një burim gjurmimi mund të tregojë kur një pajisje rrjeti ka marrë një paketë dhe siguron qasje në përmbajtjen e paketës për marrësit e interesuar të gjurmimit.

Burimet e gjurmimit janë të padobishme në vetvete nëse nuk janë "të lidhura" me pjesë të tjera të kodit që në të vërtetë bëjnë diçka të dobishme me informacionin e ofruar nga marrësi. Gjurmuesit janë konsumatorë të ngjarjeve dhe të dhënave të ofruara nga burimet e gjurmimit. Për shembull, mund të krijohet një marrës gjurmimi që do të printojë pjesët e interesit të paketës së marrë (kur lidhet me burimin e gjurmimit të shembullit të mëparshëm).

Një arsyetim i arsyeshëm për këtë ndarje të qartë është që t'u lejojë përdoruesve të lidhin lloje të reja të marrësve me burime ekzistuese të gjurmimit pa qenë nevoja të redaktohet dhe rikonfigurohet bërthama e simulatorit. Kështu, 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 gjurmimi të përcaktuar në bërthamën e simulimit, vetëm duke redaktuar skriptin e tij personal.

NĂ« kĂ«tĂ« udhĂ«zues do tĂ« shqyrtojmĂ« disa burime dhe pranuese tĂ« paracaktuara dhe do tĂ« tregojmĂ« si mund t'i konfigurojmĂ« ato me pĂ«rpjekje minimale nga ana e pĂ«rdoruesit. Shihni UdhĂ«zuesin e ns‑3 ose seksionet me udhĂ«zime pĂ«r informacion mbi konfigurimin e zgjeruar tĂ« gjurmimit, duke pĂ«rfshirĂ« zgjerimin e hapĂ«sirĂ«s emĂ«rore tĂ« gjurmimit dhe krijimin e burimeve tĂ« reja tĂ« gjurmimit.

5.3.1 Gjurmimi ASCII

ns‑3 ofron njĂ« funksionalitet ndihmĂ«s qĂ« siguron njĂ« sistem tĂ« ulĂ«t gjurmimi pĂ«r t'ju ndihmuar me detajet gjatĂ« konfigurimit tĂ« gjurmimeve tĂ« thjeshta tĂ« pakove. NĂ«se e aktivizoni kĂ«tĂ« funksion, do tĂ« shihni daljet nĂ« skedarĂ« ASCII. PĂ«r ata qĂ« janĂ« tĂ« njohur me daljen e ns-2, ky lloj gjurmimi Ă«shtĂ« i ngjashĂ«m out.tr, i cili Ă«shtĂ« gjeneruar nga njĂ« mori skenari.

Le të kalojmë në punë dhe të shtojmë disa rezultate të gjurmimit ASCII në skenarin tonë scratch/myfirst.cc. Saktësisht para thirrjes së Simulator::Run(), shtoni rreshtat e mëposhtëm të kodit:
AsciiTraceHelper ascii;

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

Si nĂ« shumĂ« idiomĂ« tĂ« tjera tĂ« ns‑3, ky kod pĂ«rdor njĂ« objekt ndihmĂ«s pĂ«r tĂ« krijuar gjurmime ASCII. Rreshti i dytĂ« pĂ«rmban dy thirrje tĂ« ngjitur tĂ« metodĂ«s. Metoda "brenda" CreateFileStream() pĂ«rdor idiomĂ«n e objektit anonim pĂ«r tĂ« krijuar njĂ« objekt tĂ« rrjedhĂ«s sĂ« skedarit nĂ« stack (pa emrin e objektit) dhe ia kalon atĂ« metodĂ«s thirrĂ«se. NĂ« tĂ« ardhmen, do tĂ« thellohemi nĂ« kĂ«tĂ« çështje, por gjithçka qĂ« ju nevojitet tĂ« dini nĂ« kĂ«tĂ« etapĂ« Ă«shtĂ« se po krijoni njĂ« objekt qĂ« pĂ«rfaqĂ«son njĂ« skedar me emrin myfirst.tr dhe e kaloni atĂ« nĂ« ns‑3. Ne i besojmĂ« ns‑3 kujdesin pĂ«r objektin e krijuar gjatĂ« gjithĂ« jetĂ«s sĂ« tij, gjatĂ« sĂ« cilĂ«s zgjidhen çështjet qĂ« lidhen me njĂ« kufizim tĂ« panjohur (tĂ« qĂ«llimshĂ«m) tĂ« lidhur me ndĂ«rtuesit e kopjimit tĂ« objekteve tĂ« rrjedhĂ«s C++.

Thirrja e jashtme EnableAsciiAll() i raporton ndihmësit se dëshironi të aktivizoni gjurmimin ASCII në simulimin tuaj për të gjitha lidhjet e pajisjeve pikë-pikë dhe se dëshironi që (pranuësit e specifikuar) të regjistrojnë informacionin mbi lëvizjen e pakove në formatin ASCII.

PĂ«r ata qĂ« janĂ« tĂ« njohur me ns-2, ngjarjet qĂ« ndiqen janĂ« ekuivalente me pikĂ«t e njohura tĂ« gjurmimit qĂ« regjistrojnĂ« ngjarje “+”, “-”, “d” dhe “r”.
Tani mund të ndërtoni skenarin dhe ta ekzekutoni nga linja e komandës:

$ ./waf --run scratch/myfirst

Sa kaq shumĂ« herĂ« mĂ« parĂ«, do tĂ« shihni disa njoftime nga Waf, dhe mĂ« pas "‘build’ finished successfully" (ndĂ«rtimeja pĂ«rfundoi me sukses) me njĂ« numĂ«r njoftimesh nga programi duke punuar.

Gjatë punës, programa do të krijojë një skedar me emrin myfirst.tr. Për shkak të veçorive të funksionimit të Waf, si rregull, skedari krijohet jo në direktorinë lokale, por në direktorinë e nivelit të lartë të repositorisë. Nëse doni të ndryshoni rrugën ku ruhet gjurmimi, atëherë për ta specifikuar atë mund të përdorni parametrin për Waf --cwd. Ne nuk e bëmë këtë, kështu që për të parë skedarin ASCII të gjurmimit myfirst.tr në redaktorin tuaj të preferuar, do të duhet të kalojmë në direktorinë e nivelit të lartë të repositorisë sonë.

Parsatimi i gjurmave ASCII

Atje ka shumë informacione në një formë të ngjeshur, por e para që duhet të vëreni është se skedari përbëhet nga rreshta të ndarë. Kjo do të bëhet e qartë nëse expandoni dritaren e shikimit më gjerë.

Çdo rresht nĂ« skedar korrespondon me njĂ« ngjarje gjurmimi. NĂ« kĂ«tĂ« rast, ne jemi duke gjurmuar ngjarjet nĂ« radhĂ«n e transmetimit, e cila Ă«shtĂ« e pranishme nĂ« çdo pajisje rrjeti pikĂ«-pikĂ« nĂ« simulim. RadhĂ« transmetimi Ă«shtĂ« njĂ« radhĂ«, pĂ«rmes sĂ« cilĂ«s çdo paketĂ« duhet tĂ« kalojĂ« pĂ«r kanalin pikĂ«-pikĂ«. VĂ«reni se çdo rresht nĂ« skedarin e gjurmimit fillon me njĂ« simbol tĂ« vetĂ«m (dhe ka njĂ« hapĂ«sirĂ« pas tij). Ky simbol do tĂ« ketĂ« vlerĂ«n e mĂ«poshtme:

+: u krye një veprim vendosjeje në radhën e pajisjes;
-: u krye një veprim nxjerrjeje të elementit në radhën e pajisjes;
d: paketa u hodh poshtë, zakonisht për shkak se radhë është mbushur;
r: paketa u mor nga pajisja rrjet.

Le të shqyrtojmë më në detaje rreshtin e parë në skedarin e gjurmimit. Do ta ndaj në pjesë (me tërheqje për qartësi) dhe me numrin e rreshtit të majtë:

0 +
1 2
2 /NodeList/0/DeviceList/0/$ns3::PointToPointNetDevice/TxQueue/Enqueue
3 ns3::PppHeader (
4   Protokolli Pikë-Pikë: IP (0x0021))
6   ns3::Ipv4Header (
7     tos 0x0 ttl 64 id 0 protokoll 17 offset 0 flags [none]
8     gjatësi: 1052 10.1.1.1 > 10.1.1.2)
9     ns3::UdpHeader (
10      gjatësi: 1032 49153 > 9)
11      Ngarkesë (masë=1024)

Pjesa e parë e këtij ngjarjeje të zgjeruar të gjurmimit (rreshti 0) është operacioni. Kemi këtu simbolin +, që korrespondon me veprimin e vendosjes në radhë për transmetim. Pjesa e dytë (rreshti 1) është koha e modelimit, e shprehur në sekonda. Mund të përmendni që kërkuam UdpEchoClientApplication filloni dërgesat pas dy sekondash. Këtu shohim konfirmimin se kjo vërtet po ndodh.

Në seksionin e ardhshëm të shembujve të gjurmimit (nga rreshti 2) tregohet se cili burim gjurmimi ka krijuar këtë ngjarje (në të cilin përmendet hapësira e emrave). Mund ta përfytyroni hapësirën e emrave të gjurmimit pak si hapësirën e emrave të sistemit të skedarëve. Rrënja e hapësirës së emrave është NodeList. Kjo përkon me kontenierin, i cili menaxhohet kryesisht nga kodi ns-3. Në të përfshihen të gjitha nyjat që krijohen në skenarin. Ashtu si sistemi i skedarëve mund të ketë drejtoritë në rrënjën e tij, në NodeList ne mund të kemi shumë nyje. Prandaj, rreshti \/NodeList\/0 i referohet nyjës zero në NodeList, e cila zakonisht e kuptojmë si "nyja 0". Në çdo nyje ka një listë pajisjesh që janë instaluar. Kjo listë gjendet në hapësirën e emrave. Mund të shihni se kjo ngjarje gjurmimi vjen nga DeviceList\/0, e cila është pajisja zero e instaluar në nyje.

Nënsekuenca e ardhshme, $ ns3 :: PointToPointNetDevice, tregon se cila pajisje është në pozitat zero: lista e pajisjeve të nyjës zero. Kujtojmë se operacioni +, i cili ndodhej në rreshtin 0, do të thoshte se një element është shtuar në radhën e dërgimit të pajisjes. Kjo pasqyrohet në segmentet e fundit të "rrugës së gjurmimit": TxQueue\/Enqueue.

Pjesët e tjera në gjurmim duhet të jenë mjaft të kuptueshme intuitivisht. Rreshtat 3-4 tregojnë se paketa është inkapsuluar në protokollin pikë-në-pikë. Rreshtat 5-7 tregojnë se paketa ka një titull versioni IP4 dhe është krijuar në adresën IP 10.1.1.1 dhe është e destinuar për 10.1.1.2. Rreshtat 8-9 tregojnë se kjo paketë ka një titull UDP dhe, më në fund, rreshti 10 tregon se ngarkesa është pritshmëritë 1024 byte.

Rreshti tjetër në skedarin e gjurmimit tregon se e njëjta paketë është tërhequr nga radhë dërgimi në të njëjtën nyje.

Rreshti i tretë në skedarin e gjurmimit tregon se paketa është pranuar nga pajisja rrjetore në nyjën me serverin e echo-s. Unë e riprodhoj këtë ngjarje më poshtë.

0 r
1 2.25732
2 \/NodeList\/1\/DeviceList\/0\/$ns3::PointToPointNetDevice\/MacRx
3   ns3::Ipv4Header (\n4     tos 0x0 ttl 64 id 0 protocol 17 offset 0 flags [none]\n5     length: 1052 10.1.1.1 > 10.1.1.2)\n6     ns3::UdpHeader (\n7       length: 1032 49153 > 9)\n8       Payload (size=1024)

Vini re që operacioni i gjurmimit tani është r, dhe koha e simulimit është rritur në 2,25732 sekonda. Nëse keni ndjekur me kujdes udhëzimet e manualit, kjo do të thotë se keni lënë DataRate të pajisjeve rrjet dhe vonesën e kanalit në vlerat e tyre të zakontë. Kjo kohë duhet të jetë e njohur, siç e keni parë tashmë në seksionin e mëparshëm.

Regjistrimi i hapĂ«sirĂ«s sĂ« emrave tĂ« burimit tĂ« gjurmimit (rreshti 2) Ă«shtĂ« modifikuar pĂ«r tĂ« reflektuar se ky ngjarje buron nga nyja 1 (/NodeList/1) Đž паĐșДт ĐżŃ€ĐžĐœŃŃ‚ ĐžŃŃ‚ĐŸŃ‡ĐœĐžĐșĐŸĐŒ Ń‚Ń€Đ°ŃŃĐžŃ€ĐŸĐČĐșĐž (/MacRx). Duhet tĂ« jetĂ« mjaft e lehtĂ« tĂ« ndjekĂ«sh lĂ«vizjen e paketĂ«s pĂ«rmes topologjisĂ« duke parĂ« gjurmĂ«n e mbetur nĂ« skedarin e gjurmimit.

5.3.2 Gjurmimi PCAP

Asistentët e pajisjeve ns-3 gjithashtu mund të përdoren për të krijuar skedarë gjurmimi në formatin .pcap. Akronimi pcap (zakonisht shkruar me shkronja të vogla) përfaqëson kapjen e paketimeve dhe është në thelb një API që përfshin përcaktimin e formatit të skedarit .pcap. Programi më i njohur që mund të lexojë dhe shfaqë këtë format është Wireshark (më parë i quajtur Ethereal). Megjithatë, ka shumë analistë të gjurmimit të trafikut që përdorin këtë format paketi. Ne rekomandojmë përdoruesit të përdorin shumë mjete të disponueshme për të analizuar gjurmët pcap. Në këtë udhëzues do të përqendrohemi në shikimin e gjurmëve pcap duke përdorur tcpdump.

Aktivizimi i gjurmimit pcap kryhet me një linjë kodi.

pointToPoint.EnablePcapAll ("myfirst");

Vendosni këtë linjë kodi pas kodit të gjurmimit ASCII që sapo e shtuam në scratch/myfirst.cc. Vini re se ne kemi kaluar vetëm stringun "myfirst", e jo "myfirst.pcap" ose diçka të tillë. Kjo sepse parametri është një prefiks, dhe jo emri i plotë i skedarit. Gjatë simulimit, asistenti do të krijojë në të vërtetë një skedar gjurmimi për secilën pajisje pikë-pikë. Emrat e skedarëve do të ndërtohen duke përdorur prefiksin, numrin e nyjës, numrin e pajisjes dhe sufixin "pcap».

Për shembullin tonë të skenarit, ne do të përfundojmë duke parë skedarë me emrat "myfirst-0-0.pcap» dhe "myfirst-1-0.pcap", të cilat janë gjurmime pcap për nyjën 0-pajisje 0 dhe nyjën 1-pajisje 0 përkatësisht. Pasi të keni shtuar linjën e kodit për të aktivizuar gjurmimin pcap, mund ta filloni skenarin në mënyrën e zakonshme:

$ ./waf --run scratch/myfirst

NĂ«se shikoni nĂ« direktorinĂ« kryesore tĂ« shpĂ«rndarjes tuaj, duhet tĂ« shihni tre skedarĂ«: skedari i gjurmimit ASCII myfirst.tr, qĂ« ne e shqyrtuam mĂ« parĂ«, skedarĂ«t myfirst-0-0.pcap dhe myfirst-1-0.pcap — skedarĂ«t e rinj pcap qĂ« sapo kemi gjeneruar.

Leximi i daljes me tcpdump

Në këtë moment, 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
leximi nga skedari myfirst-0-0.pcap, lloji i lidhjes PPP (PPP)
2.000000 IP 10.1.1.1.49153 > 10.1.1.2.9: UDP, gjatësi 1024
2.514648 IP 10.1.1.2.9 > 10.1.1.1.49153: UDP, gjatësi 1024
tcpdump -nn -tt -r myfirst-1-0.pcap
leximi nga skedari myfirst-1-0.pcap, lloji i lidhjes PPP (PPP)
2.257324 IP 10.1.1.1.49153 > 10.1.1.2.9: UDP, gjatësi 1024
2.257324 IP 10.1.1.2.9 > 10.1.1.1.49153: UDP, gjatësi 1024

Në dump myfirst-0-0.pcap (dispositivi klient) mund të shihni se paketa echo dërgohet pas 2 sekondash simulimi. Nëse shikon dump-in e dytë (myfirst-1-0.pcap), do të shihni se paketa pranohet në momentin 2,257324 sekonda. Do të shihni në dump-in e dytë se paketa kthehet në momentin 2.257324 sekonda, dhe përfundimisht se paketa u mor nga klienti përsëri në dump-in e parë në momentin 2.514648 sekonda.

Leximi i daljes me Wireshark

NĂ«se nuk jeni tĂ« njohur me Wireshark, ka njĂ« sit nga ku mund tĂ« shkarkoni programe dhe dokumentacion: http://www.wireshark.org/. Wireshark — Ă«shtĂ« njĂ« ndĂ«rfaqe grafike qĂ« mund tĂ« pĂ«rdoret pĂ«r tĂ« shfaqur kĂ«to skedarĂ« e gjurmimit. NĂ«se keni Wireshark, mund tĂ« hapni çfarĂ«do skedari gjurmimi dhe tĂ« shfaqni pĂ«rmbajtjen, sikur tĂ« kishit kapur paketat duke pĂ«rdorur njĂ« analizues paketash.

Burimi: habr.com

Blini hosting tĂ« besueshĂ«m pĂ«r faqe interneti me mbrojtje nga DDoS, serverĂ« VPS VDS đŸ”„ Blini hosting tĂ« besueshĂ«m pĂ«r faqe interneti me mbrojtje nga DDoS, serverĂ« VPS VDS | ProHoster