
5 Konfigurimi
5.1 Përdorimi i modulit të regjistrimit
5.1.1 Përshtypje mbi regjistrimin
5.1.2 Autorizimi i regjistrimit
5.1.3 Shtimi i regjistrimit në kodin tuaj
5.2 Përdorimi i argumenteve të komandës
5.2.1 Rishkrimi i vlerave të atributit të paracaktuar
5.2.2 Kapja e komandave tuaja
5.3 Përdorimi i sistemit të gjurmimit
5.3.1 ASCII Gjurmo
Analiza e gjurmës ASCII
5.3.2 Gjurmo PCAP
Kapitulli 5
Konfigurimi
5.1 Përdorimi i modulit të regjistrimit
Ne tashmĂ« shqyrtuam shkurtimisht modul nĂ« regjistrimin nsâ3, duke shqyrtuar skriptin first.cc. NĂ« kĂ«tĂ« kapitull, do t'i hedhim njĂ« vĂ«shtrim mĂ« tĂ« thellĂ« mundĂ«sive tĂ« pĂ«rdorimit tĂ« nĂ«nstrukturĂ«s sĂ« regjistrimit.
5.1.1 Përshtypje mbi regjistrimin
Shumë sisteme të mëdha mbështesin ndonjë mjet regjistrimi të mesazheve, dhe ns-3 nuk bën përjashtim. Në disa raste, në "konsolën e operatorit" (e cila zakonisht është stderr në sistemet e bazuara në Unix) shkruhen vetëm mesazhe gabimi. 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 për debug, të cilat mund të "zgjerdhin" shpejt daljen.
Prerja, e përdorur në ns-3, supozon që të gjitha këto nivele të informacionit janë të dobishme, dhe ne ofrojmë një qasje selektive, me shumë nivele për regjistrimin e mesazheve. Regjistrimi mund të çaktivizohet plotësisht, të aktivizohet për komponentë të veçantë ose në një shkallë globale. Për këtë shërbejnë nivelet e personalizuara të informacionit. Moduli i regjistrimit ns-3 ofron një mënyrë relativisht të thjeshtë për të marrë informacion të dobishëm nga simuliimi 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, qĂ« duhet tĂ« jetĂ« metoda e preferuar pĂ«r dalje gjatĂ« modelimit (pĂ«r mĂ« shumĂ« informacion nĂ« lidhje me sistemin tonĂ« tĂ« gjurmimit shihni seksionin 5.3 tĂ« manualit). Regjistrimi duhet tĂ« jetĂ« metoda e preferuar pĂ«r tĂ« marrĂ« informacion pĂ«r gabime, paralajmĂ«rime, mesazhe gabimi ose pĂ«r tĂ« nxjerrĂ« shpejt mesazhe nga skenarĂ«t ose modelet tuaja nĂ« çdo moment.
Aktualisht, sistemi ka përcaktuar shtatë nivele (lloja) mesazhesh regjistri në rritje të informatës.
- LOG_ERROR â regjistrimi i mesazheve pĂ«r gabime (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Ă« veçanta tĂ« debugging-ut relativisht tĂ« rrallĂ« (makro i lidhur: NS_LOG_DEBUG);
- LOG_INFO â regjistrimi i mesazheve informative nĂ« lidhje me progresin 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 i lidhur: NS_LOG_LOGIC);
- LOG_ALL â regjistrimi i tĂ« gjitha tĂ« pĂ«rmendura mĂ« lart (nuk ka makro tĂ« lidhur).
Për çdo tip (LOG_TYPE) gjithashtu ekziston një tip LOG_LEVEL_TYPE, i cili, nëse përdoret, lejon regjistrimin në përputhje me nivelin e tij, si dhe të gjitha nivelet mbi të. (Si pasoje, 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 makro i NS_LOG_INFO, ndërsa aktivizimi i LOG_LEVEL_INFO gjithashtu do të përfshijë mesazhet e ofruara nga makrot NS_LOG_DEBUG, NS_LOG_WARN dhe NS_LOG_ERROR.
Ne gjithashtu ofrojmë një makro regjistrimi pa kushte, e cila shfaqet gjithmonë, pavarësisht nga niveli i regjistrimit ose komponenti i zgjedhjes.
- NS_LOG_UNCOND â regjistrimi pa kushte i mesazhit tĂ« lidhur (pa nivel regjistrimi tĂ« lidhur).
Ădo nivel mund tĂ« kĂ«rkohet veçmas ose kumulativisht. Regjistrimi mund tĂ« konfigurohet duke pĂ«rdorur variablĂ«n mjedisore 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 nuk e keni bĂ«rĂ« akoma.
Tani që keni lexuar dokumentacionin me kujdes, le të përdorim këto njohuri për të marrë disa informacione interesante nga shembulli i skriptit scratch/myfirst.cc, i cili e keni kompjiliruar tashmë.
5.1.2 Autorizimi i regjistrimit
Le të përdorim variablin mjedisor NS_LOG për të drejtuar disa regjistrime të tjera, por së pari, thjesht për orientim, drejtoni skriptin e fundit siç e bëtë më parë,
$ ./waf --run scratch/myfirstDuhet të shihni daljen e njohur të programit të parë shembull ns-3
$ Waf: Duke hyrë në katalogin `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Duke lënë katalogun `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build' 'build'
përfundoi me sukses (0.413s)
Dërguar 1024 byt për 10.1.1.2
Marrë 1024 byt nga 10.1.1.1
Marrë 1024 byt nga 10.1.1.2Duket se mesazhet "të dërguara" dhe "të marra" që shihni më sipër në të vërtetë janë regjistrime mesazhesh nga UdpEchoClientApplication dhe UdpEchoServerApplication. P.shkëmbëta, mund të kërkojmë nga aplikacioni klient të printojë informacion shtesë, duke e vendosur nivelin e regjistrimit përmes variablës së ambientit NS_LOG.
Nga ky moment, do të supozoj që po përdorni një shell të ngjashëm me sh, i cili përdor sintaksën «VARIABLE = value». Nëse po përdorni një shell të ngjashëm me csh, atëherë do të duhet të konvertoni shembujt e mi në sintaksën «setenv variabli vlerë» që kërkohet nga këto shell.
Në këtë moment, aplikacioni UDP echo klient po përgjigjet përmes rreshtit të mëposhtëm të kodit në scratch/myfirst.cc,
LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO);Kjo aktivizon nivelin e regjistrimit LOG_LEVEL_INFO. Kur ne kalojmë flagun e nivelit të regjistrimit, në të vërtetë po aktivizojmë këtë 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 bërë ndryshime në skritin dhe ripërpilimin, përmes vendosjes së variablës së ambientit NS_LOG në këtë mënyrë:
$ export NS_LOG=UdpEchoClientApplication=level_allKështu ne vendosim vlerën e mëposhtme për variablën NS_LOG në shell-in sh,
UdpEchoClientApplication=level_allKrahu i majtë i caktimit është emri i komponentit që regjistrohet, të cilin duam ta konfigurojmë, ndërsa krahu i djathtë është flagu që dëshirojmë të aplikojmë për këtë. Në këtë rast, ne do të aktivizojmë të gjitha nivelet e debugging në aplikacion. Nëse e ekzekutoni skriptin me NS_LOG të vendosur kështu, sistemi i regjistrimit ns-3 do të pranojë ndryshimet dhe duhet të shihni rezultatin e mëposhtëm:
Waf: Duke hyrë në direktorën `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Duke lënë direktorën `/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 te 10.1.1.2
Pranuar 1024 byte nga 10.1.1.1
UdpEchoClientApplication:HandleRead(0x6241e0, 0x624a20)
Pranuar 1024 byte nga 10.1.1.2
UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()Informacioni shtesë i debugging i ofruar nga aplikacioni tani i përgjigjet nivelit NS_LOG_FUNCTION. Ai tregon çdo rast thirrjeje të funksioneve gjatë ekzekutimit të skriptit. Në përgjithësi, në funksionet-metoda preferohet të përdoret (të paktën)NS_LOG_FUNCTION (this). Përdorni NS_LOG_FUNCTION_NOARGS ()
vetëm në funksionet statike. Megjithatë, vini re se në sistemin ns-3 nuk ka kërkesa për të mbështetur ndonjë funksionalitet regjistrimi. Vendimi për sa informacion regjistrohet mbetet individual për zhvilluesin e modelit. Në rastin e aplikacioneve echo, është e disponueshme një sasi e madhe të dhënash për regjistrim.
Tani, mund ta shikoni regjistrin e thirrjeve të funksioneve që janë bërë nga aplikacioni. Nëse e shikoni me kujdes, do të vini re një dypik midis rreshtit UdpEchoClientApplication dhe emrit të metodës, në vendin ku mund të prisnit të shihni operatorin e hapësirës C++ (::). Kjo është bërë në mënyrë të qëllimshme.
Në të vërtetë, kjo nuk është emri i klasës, por emri i komponentit të regjistrimit. Kur ka një përputhje midis skedarit të burimit dhe klasës, zakonisht është emri i klasës, por duhet të kuptoni se në të vërtetë nuk është emri i klasës, dhe aty ka një dypik në vend të dy dypikëve. Ky është një mënyrë për t'ju ndihmuar në një mënyrë mjaft të hollë për të ndarë konceptualisht emrin e komponentit të regjistrimit nga emri i klasës.
Megjithatë, në disa raste është e vështirë të përcaktohet se cilat metodë në të vërtetë gjeneron mesazhin e regjistrit. Nëse e shikoni tekstin më sipër, do të keni pyetje se nga erdhi rreshti «Marrë 1024 byte nga 10.1.1.2». Mund ta zgjidhni këtë problem duke vendosur nivelin prefix_func në variablin e mjedisit NS_LOG. Provoni të bëni sa vijon:
$ export 'NS_LOG=UdpEchoClientApplication=level_all|prefix_func'Kujtoni se citatet janë të nevojshme, pasi vertikala që përdorim për të shënuar operacionin OSE, gjithashtu është një lidhës rrjedhës Unix. Tani, nëse e nisni skenarin, do të shihni se sistemi i regjistrimit siguron që çdo mesazh nga ky regjistër ka një përparësie me emrin e komponentit.
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.417s)
UdpEchoClientApplication:UdpEchoClient()
UdpEchoClientApplication:SetDataSize(1024)
UdpEchoClientApplication:StartApplication()
UdpEchoClientApplication:ScheduleTransmit()
UdpEchoClientApplication:Send()
UdpEchoClientApplication:Send(): Dërguar 1024 bytes në 10.1.1.2
Marrë 1024 bytes nga 10.1.1.1
UdpEchoClientApplication:HandleRead(0x6241e0, 0x624a20)
UdpEchoClientApplication:HandleRead(): Marrë 1024 bytes 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 "Marrë 1024 byte nga 10.1.1.2" tani është përcaktuar qartë si duke ardhur nga aplikacioni echo-client. Mesazhi i mbetur duhet të vijë nga aplikacioni UDP echo-server. Mund të aktivizojmë këtë komponent duke futur një listë komponentesh të ndara me dy pika në variablën e ambientit NS_LOG.
$ export 'NS_LOG=UdpEchoClientApplication=level_all|prefix_func:
UdpEchoServerApplication=level_all|prefix_func'Kujdes: Në shembullin e mësipërm të tekstit, do t'ju duhet të hiqni karakterin e ri të linjës pas dy pikave (:), ai përdoret për formatimin e dokumentit. Tani, nëse e ngarkoni skenarin, do të shihni të gjitha mesazhet e regjistrit nga aplikacionet e klientit dhe serverit të echo. Mund të shihni se kjo mund të jetë shumë e dobishme gjatë debuggimit.
Waf: Duke hyrë në katalog `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Duke lënë katalogun `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'ndërtimi' 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 reflektuar 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ë kesh mundësinë për të parë kohën e modelimit në të cilën u krijua mesazhi i regjistrit. Mund ta bësh këtë duke shtuar një bit OSE prefix_time:
$ export 'NS_LOG=UdpEchoClientApplication=level_all|prefix_func|prefix_time: UdpEchoServerApplication=level_all|prefix_func|prefix_time'Po përsëri, do t'ju duhet të hiqni karakterin e ri të linjës më lart. Nëse tani e ekzekutoni skriptin, duhet të shihni këtë dalje:
Waf: Hy në direktorinë `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Del nga direktoria `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' u përfundua 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(): Dërgimi i paketës
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 ndërtuesi për UdpEchoServer u thirr gjatë simulimit në 0 sekonda. Kjo ndodh në të vërtetë para fillimit të simulimit, por ky kohë shfaqet si zero sekonda. E njëjta gjë vlen për mesazhin e ndërtuesit UdpEchoClient.
Waf: Hy në direktorinë `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Del nga direktoria `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' u përfundua 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(): Dërgimi i paketës
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()Kujtojmë se skripti scratch/first.cc ka nisur aplikacionin e serverit echon një sekondë para fillimit të simulimit. Tani mund të shihni se metoda StartApplication e serverit thjesht thirret në sekondën e parë. Gjithashtu mund të vëreni se klienti echo niset në sekondën e dytë të simulimit, ashtu siç kërkuam në skenarin.
Tani mund të ndiqni procesin e simulimit përmes thirrjes ScheduleTransmit në klient, i cili thërret funksionin Send, duke e kthyer në HandleRead në aplikacionin e serverit echo. Vini re se koha e kaluar për dërgimin e paketës përmes lidhjes dy-pikëshe është 3.69 milisekonda. Mund të shihni se serveri echo regjistron një mesazh që tregon se ka kthyer përgjigje për paketën, dhe pastaj, pas vonesës së kanalit, shihni që klienti echo merr paketën echo në metodën e tij HandleRead.
Në këtë simulim, shumë gjëra ndodhin pa u vënë re nga ju. Por mund ta ndiqni lehtësisht të gjithë procesin duke aktivizuar të gjitha komponentët e regjistrimit në sistem. Provoni të vendosni në variablën NS_LOG vlerën e mëposhtme,
$ export 'NS_LOG=*=level_all|prefix_func|prefix_time'Yllë, yllza është një simbol zëvendësimi i komponentit të regjistrimit. Kjo do të përfshijë të gjithë shënimet në të gjitha komponentët që përdoren në simulim. Nuk do ta riprodhoj daljen këtu (në momentin e shkrimit, ai prodhon 1265 rreshta daljeje për një paketë echo), por mund ta ridrejtosh këtë informacion në një skedar dhe ta shikosh në redaktorin tënd të preferuar.
$ ./waf --run scratch/myfirst > log.out 2>&1Unë personalisht përdor këtë version jashtëzakonisht ekspansiv të regjistrimit kur kam një problem dhe nuk kam asnjë ide se ku shkuan gabim. Mund të ndjek lehtësisht ekzekutimin e kodit pa vendosur pikëndalimi dhe pa bërë hap pas hapi në debugin. Mund ta redaktoj thjesht të dhënat në editorin tim të preferuar, të kërkoj atë që pres dhe të shoh se çfarë po ndodh ndryshe nga sa prisja. Kur kam një ide të përgjithshme se çfarë nuk shkon, shkoj në debugin për një hetim më të thellë të problemit. 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 debugin, mund të humbni plotësisht një kthesë të papritur. Regjistrimi i bën këto kthesa të dukshme.
5.1.3 Shtimi i regjistrimit në kodin tuaj
Mund të shtoni regjistrime të reja në simulatet tuaja duke bërë thirrje në komponentin log nga disa makro. Le të e bëjmë këtë në skenarin myfirst.cc, që e kemi në direktorinë 'të pastër'. Kujtojmë se kemi përcaktuar në këtë skenar komponentin e regjistrimit:
NS_LOG_COMPONENT_DEFINE ("FirstScriptExample");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ë skenar. Makrosi që përdoret për të regjistruar mesazhe të nivelit informativ është NS_LOG_INFO. Le të shtojmë një mesazh (menjëherë para se të fillojmë të krijojmë nyjat), i cili ju tregon se skenari është në fazën e krijimit të topologjisë ("Creating Topology"). 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 ("Creating Topology");
drejt përpara rreshtave,
NodeContainer nodes;
nodes.Create (2);Tani kompiloni skenarin duke përdorur waf, dhe pastrojeni variablën NS_LOG për të çaktivizuar rrjedhën e regjistrimit që aktivizuam më parë:
$ ./waf
$ export NS_LOG=
Tani, nëse e nisni skenarin,
$ ./waf --run scratch/myfirstnuk do të shihni mesazhin e ri, pasi komponenti i lidhur me të (FirstScriptExample) nuk është aktivizuar. Për të parë mesazhin tuaj, duhet të aktivizoni komponentin e regjistrimit FirstScriptExample me një nivel që s'ka më pak se NS_LOG_INFO. Nëse thjesht dëshironi të shihni këtë nivel të veçuar të regjistrimit, mund ta aktivizoni kështu,
$ eksport NS_LOG=FirstScriptExample=infoNĂ«se tani e запŃŃĐșа skriptin, do tĂ« shihni njĂ« mesazh tĂ« ri «Duke krijuar topologji»,
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)
Duke krijuar topologji
Dërguar 1024 byte në 10.1.1.2
Marrë 1024 byte nga 10.1.1.1
Marrë 1024 byte nga 10.1.1.25.2 Përdorimi i argumenteve të komandës
5.2.1 Rishkrimi i vlerave të atributit të paracaktuar
Një mënyrë tjetër për të ndryshuar sjelljen e skriptëve ns-3 pa i redaktuar dhe ndërtuar është përdorimi i argumenteve të linjës së komandës. Ne ofrojmë një mekanizëm për analizimin e argumenteve të linjës së komandës dhe për vendosjen automatike të variablave lokalë dhe globalë bazuar në rezultatet.
Hapi i parë në përdorimin e sistemit të argumenteve të linjës së komandës është shpallja e parserit të linjës së komandës. Kjo bëhet mjaft lehtë (në programin tuaj kryesor), si në kodin në vijim,
int
main (int argc, char *argv[])
{
...
CommandLine cmd;
cmd.Parse (argc, argv);
...
}Ky fragment i thjeshtë me dy rreshta është me të vërtetë shumë i dobishëm vetë. Ai hap dyert për variablin global ns-3 dhe sistemin e atributeve. Le të shtojmë dy rreshta kodi në fillim të funksionit kryesor të skenarit. scratch/myfirst.ccDuke vazhduar, ne kompilohemi skenarin dhe e ekzekutojmë atë. Gjatë ekzekutimit, ne bëjmë një kërkesë ndihmësi në këtë mënyrë:
$ ./waf --run "scratch/myfirst --PrintHelp"Ky komandë do të kërkojë Waf të ekzekutojë skenarin scratch/myfirst dhe t'i kalojë atij një argument të komandës --PrintHelp. Kllapat janë të nevojshme për të treguar se për cilin program është argumenti. Analizatori i komandës do të zbulojë argumentin --PrintHelp dhe do të japë përgjigjen:
Waf: Hy në dosje `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Dalë nga dosja `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' përfundoi me sukses (0.413s)
TcpL4Protocol:TcpStateMachine()
CommandLine:HandleArgument(): Trajto arg emrin=PrintHelp vlera=
--PrintHelp: Printo këtë mesazh ndihme.
--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 studiojmë skenarin first.cc. Ne pamë këto rreshta kodi:
PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));dhe thanin se DataRate në të vërtetë është një atribut PointToPointNetDevice. Le të aplikojmë parser-in e argumenteve të komandës për të parë atributet PointToPointNetDevice. Lista e ndihmës thotë që duhet të ofrojmë TypeId. Ky është emri i klasës së të cilës i përkasin atributet e interesit. Në rastin tonë do të jetë ns3::PointToPointNetDevice. Të vazhdojmë përpara, shkruani,
$ ./waf --run "scratch/myfirst --PrintAttributes=ns3::PointToPointNetDevice"Sistemi do të printojë të gjitha atributet e këtij tipi të pajisjes rrjetë. Do të shihni se mes atributeve në listë është,
--ns3::PointToPointNetDevice::DataRate=[32768bps]:
Shpejtësia e të dhënave nga pikë në pikë për lidhjeKy është vlera e paracaktuar që do të përdoret në sistem gjatë krijimit të objektit PointToPointNetDevice. Ne do ta kalojmë këtë vlerë të paracaktuar me parametrin Attribute në PointToPointHelper më sipër. Le të përdorim vlerat e paracaktuara për pajisjet dhe kanalet nga pika në pikë. Për këtë, hiqni thirrjet SetDeviceAttribute dhe SetChannelAttribute nga myfirst.cc, që kemi në drejtorinë e pastër.
Skripti juaj tani duhet të deklarojë vetëm PointToPointHelper dhe mos kryeni asnjë operacion instalimi, siç është treguar në shembullin më poshtë,
...
NodeContainer nodes;
nodes.Create (2);
PointToPointHelper pointToPoint;
NetDeviceContainer devices;
devices = pointToPoint.Install (nodes);
...Vazhdoni dhe krijoni një skenar me Waf (./waf) dhe le të kthehemi prapa dhe të aktivizojmë disa regjistrime nga aplikacioni UDP echo në server dhe të aktivizojmë prefiksin e kohës.
$ export 'NS_LOG=UdpEchoServerApplication=level_all|prefix_time'Nëse ekzekutoni skenarin, duhet të shihni rezultatet e mëposhtme:
Waf: Hy në katalog `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Dal nga katalogu `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'ndërtimi' u përfundua me sukses (0.405s)
0s UdpEchoServerApplication:UdpEchoServer()
1s UdpEchoServerApplication:StartApplication()
Dërguar 1024 byte në 10.1.1.2
2.25732s Marrë 1024 byte nga 10.1.1.1
2.25732s Echoing paketën
Marrë 1024 byte nga 10.1.1.2
10s UdpEchoServerApplication:StopApplication()
UdpEchoServerApplication:DoDispose()
UdpEchoServerApplication:~UdpEchoServer()Të kujtojmë se herën e fundit, kur e shihnim kohën e simulimit, momenti i marrjes së paketës nga serveri i echo-s ishte në 2.00369 sekonda.
2.00369s UdpEchoServerApplication:HandleRead(): Marrë 1024 byte nga 10.1.1.1Tani ai po merr paketën në 2.25732 sekonda. Kjo ndodh sepse ne thjesht e ulëm shpejtësinë e transmetimit të PointToPointNetDevice nga pesë megabit në sekondë në vlerën e paracaktuar, e cila është 32768 bit në sekondë. Po të kishte qenë e mundur të ndryshonim DataRate përmes komandës në sistem, ne mund ta përshpejtonim sërish modelimin tonë. Do ta bëjmë këtë si më poshtë, sipas formulës siç përshkruhet në elementin ndihmës:
$ ./waf --run "scratch/myfirst --ns3::PointToPointNetDevice::DataRate=5Mbps"Si rezultat, vlera e atributit DataRate do të kthehet përsëri në pesë megabit në sekondë. Jeni të befasuar nga rezultati? Në fakt, për të rikthyer sjelljen origjinale të skenarit, ne gjithashtu duhet të vendosim vonesën e kanalit në përputhje me shpejtësinë e dritës. Mund të kërkojmë nga sistemi i komandave të printojë atributet e kanalit, ashtu siç bëmë për pajisjen 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]:
Vonesa e transmetimit përmes kanalitPastaj 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 ne vendosëm qartë DataRate dhe Delay në skenarin:
Waf: Po hyjmë në drejtorinë `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build`
Waf: Po largohemi nga 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 në 10.1.1.2
2.00369s Marrë 1024 byte nga 10.1.1.1
2.00369s Po echo pakon
Marrë 1024 byte nga 10.1.1.2
10s UdpEchoServerApplication:StopApplication()
UdpEchoServerApplication:DoDispose()
UdpEchoServerApplication:~UdpEchoServer()Kujdesi se paci është marrë sërish nga serveri pas 2.00369 sekondash. Ne mund të vendosnim në të vërtetë në këtë mënyrë çdo nga atributet e përdorura në skenar. Në veçanti, mund të vendosnim vlera të ndryshme nga njësi për atributet MaxPackets UdpEchoClient.
Si do ta përdornit këtë? Provoni. Kini parasysh se duhet të komentonit vendin ku ne riemërojmë vlerën e atributit të paracaktuar dhe e vendosim qartë MaxPackets në skenarin. Pastaj duhet të rindërtoni skriptin. Ju gjithashtu mund të merrni ndihmë për sintaksën për të vendosur një vlerë atributi për default përmes mjeteve të linjës së komandës. Pasi të kuptoni këtë, do të jeni në gjendje të menaxhoni numrin e paketave që shfaqen në linjën e komandës. Pasi jemi njerëz të kujdesshëm, linja jonë e komandës duhet të duket më pak kështu:
$ ./waf --run "scratch/myfirst
--ns3::PointToPointNetDevice::DataRate=5Mbps
--ns3::PointToPointChannel::Delay=2ms
--ns3::UdpEchoClient::MaxPackets=2"Pyetja e natyrshme që ngrihet në këtë pikë është se si të dimë për ekzistencën e të gjithë këtyre atributeve. Sërish, sistemi i linjës së komandës ka një funksion ndihmës për këtë çështje. Nëse kërkojmë ndihmë nga linja e komandës, atëherë duhet të shohim:
$ ./waf --run "scratch/myfirst --PrintHelp"
myfirst [Argumentet e Programit] [Argumentet e Përgjithshme]
Argumentet e Përgjithshme:
--PrintGlobals: Printoni listën e globaleve.
--PrintGroups: Printoni listën e grupeve.
--PrintGroup=[group]: Printoni të gjithë TypeIds e grupit.
--PrintTypeIds: Printoni të gjithë TypeIds.
--PrintAttributes=[typeid]: Printoni të gjithë atributet e typeid.
--PrintHelp: Printoni këtë mesazh ndihmës.Nëse zgjidhni argumentin "PrintGroups", atëherë duhet të shihni një listë të të gjithë grupeve të regjistruara TypeId. Emrat e grupeve përputhen me emrat e moduleve në direktorinë burimore (ndonëse me shkronjë të madhe). Printimi i gjithë informacionit menjëherë do të ishte tepër voluminoz, prandaj është e disponueshme një filtrë shtesë për printimin e informacionit sipas grupeve. Kështu, përsëri duke u përqendruar në modulit «pikë-në-pikë»:
./waf --run "scratch/myfirst --PrintGroup=PointToPoint"
Tipet e identifikimit në grupin PointToPoint:
ns3::PointToPointChannel
ns3::PointToPointNetDevice
ns3::PointToPointRemoteChannel
ns3::PppHeaderKëtu mund të gjeni emrat e dispozitës TypeId për të kërkuar atributet, për shembull, në
--PrintAttributes = ns3 :: PointToPointChannel, siç tregohet më lart.
NjĂ« tjetĂ«r mĂ«nyrĂ« pĂ«r tĂ« mĂ«suar rreth atributĂ«ve Ă«shtĂ« pĂ«rmes Doxygen nsâ3. Atje ka njĂ« faqe qĂ« liston tĂ« gjithĂ« atributet e regjistruar nĂ« simulator.
5.2.2 Kapja e komandave tuaja
Ju gjithashtu mund të shtoni gjakëza tuaj nëpërmjet sistemit të komandave të linjës. Kjo bëhet mjaft thjeshtë me metodën e parserit të komandave AddValue.
Le të shfrytëzojmë këtë mundësi për të specifikuar numrin e pakove që duhet të shfaqen, në një mënyrë krejtësisht tjetër. Le të shtojmë një variabël lokale me emrin nPackets në funksion main. Ne do ta vendosim atë në njësi, për të përputhur sjelljen tonë të mëparshme siç është parazgjedhur. Për të lejuar parser-in e linjës së komandave të ndryshojë këtë vlerë, na nevojitet të kapim këtë vlerë në parser. Ne e bëjmë këtë duke shtuar një thirje 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 paketave për të bërë echo", nPackets);
cmd.Parse (argc, argv);
...Rregulloni deri në pikën në skript ku vendosim atributin MaxPackets dhe ndryshojeni atë që të jetë e konfiguruar për variablën nPackets në vend të konstantës 1, siç tregohet më poshtë.
echoClient.SetAttribute ("MaxPackets", UintegerValue (nPackets));Tani, nĂ«se e ekzekutoni skriptin dhe jepni argumentin âPrintHelp, duhet tĂ« shihni argumentin e ri tĂ« pĂ«rdoruesit tĂ« listuar nĂ« ekranin e ndihmĂ«s. Shkruani,
$ ./waf --run "scratch/myfirst --PrintHelp"
Waf: Po hyj në direktoriumin `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Po largohem nga direktoriumi `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' përfundoi me sukses (0.403s)
--PrintHelp: Printo këtë mesazh ndihmës.
--PrintGroups: Printo listën e grupeve.
--PrintTypeIds: Printo të gjithë TypeIds.
--PrintGroup=[group]: Printo të gjithë TypeIds të grupit.
--PrintAttributes=[typeid]: Printo të gjithë atributet e typeid.
--PrintGlobals: Printo listën e globals.
Argumentet e Përdoruesve:
--nPackets: Numri i paketave për të bërë echoNëse dëshironi të ndryshoni numrin e pakove të dërguara, mund ta bëni këtë, duke vendosur argumentin -nPackets në komandën e linjës.
$ ./waf --run "scratch/myfirst --nPackets=2"Tani duhet të shihni
Waf: Hy në direktoriumin `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build`
Waf: Del nga direktoriumi `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build`
'build' përfundoi me sukses (0.404s)
0s UdpEchoServerApplication:UdpEchoServer()
1s UdpEchoServerApplication:Fillimi i aplikacionit()
Dërguar 1024 byte te 10.1.1.2
2.25732s Pranuar 1024 byte nga 10.1.1.1
2.25732s Pasqyra e paketave
Pranuar 1024 byte nga 10.1.1.2
Dërguar 1024 byte te 10.1.1.2
3.25732s Pranuar 1024 byte nga 10.1.1.1
3.25732s Pasqyra e paketave
Pranuar 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 atribute tĂ« reja nĂ« objektet tuaja dhe ato do tĂ« jenĂ« automatikisht tĂ« disponueshme pĂ«r t'u konfiguruar 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Ă« skriptet tuaja dhe t'i lidhni 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Ă« krijohet njĂ« dalje pĂ«r studime tĂ« mĂ«tejshme, dhe sistemi i gjurmimit nsâ3 Ă«shtĂ« mekanizmi kryesor pĂ«r kĂ«tĂ«. Duke qenĂ« se nsâ3 Ă«shtĂ« njĂ« program C++, mund tĂ« pĂ«rdoren mjetet standarde pĂ«r tĂ« gjeneruar dalje pĂ«r programet nĂ« C++;
#include <iostream>
...
int main ()
{
...
std::cout << "The value of x is " << x << std::endl;
...
}Ju madje mund të përdorni modul të regjistrimit për të shtuar një strukturë të vogël në zgjidhjen tuaj. Njohim shumë probleme që shfaqen nga ky qasje dhe për këtë arsye kemi ofruar një sistem të përbashkët të gjurmimit të ngjarjeve për t'i zgjidhur ato.
QĂ«llimet kryesore tĂ« sistemit tĂ« gjurmimit nsâ3:
Për detyrat bazë, sistemi i gjurmimit duhet të lejojë përdoruesin të gjenerojë një gjurmim standard për burimet e njohura dhe të zgjedhë objektet që gjenerojnë gjurmimin;
Përdoruesit e mesë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 simuluesit për të shtuar burime dhe marrës të rinj të gjurmimit. Sistemi i gjurmimit ns-3 bazohet në parimet e burimeve të pavarura të gjurmimit dhe marrësve, si dhe në një mekanizëm të unifikuar për lidhjen e burimeve me konsumatorët.
Sistemi i gjurmimit ns-3 bazohet në parimet e burimeve dhe marrësve të pavarur të gjurmimit, si dhe në një mekanizëm të unifikuar për lidhjen e burimeve me marrësit. Burimet e gjurmimit janë objekte që mund të sinjalizojnë ngjarje që ndodhin në simulim dhe të ofrojnë qasje në të dhënat themelore të interesit. Për shembull, një burim gjurmimi mund të tregojë kur një pajisje rrjeti merr një paketë dhe ofron qasje në përmbajtjen e paketës për marrësit e interesuar të gjurmimit.
Burimet e gjurmimit vetë janë të palodhur nëse nuk janë "të lidhura" me pjesë të tjera të kodit, që realisht bëjnë diçka të dobishme me informacionin e ofruar nga pranuesi. Gjurmuesit janë konsumatorë të ngjarjeve dhe të dhënave të ofruara nga burimet e gjurmimit. Për shembull, mund të krijoni një pranues gjurmimi që do të (kur lidhet me burimin e gjurmimit të shembullit të mëparshëm) të printojë pjesët interesante të paketës së pranuar.
Një arsye e arsyeshme për këtë ndarje të qartë është të lejojë përdoruesit të lidhin lloje të reja pranuesish me burime ekzistuese të gjurmimit pa pasur nevojë të redaktojnë dhe rikompozojnë thelbin e simuluar. Kështu, në shembullin e mësipërm, përdoruesi mund të përcaktojë një gjurmues të ri në skenarin e tij dhe ta lidhë atë me një burim ekzistues të gjurmimit, të përcaktuar në thelbin e simulimit, duke redaktuar vetëm skenarin e përdoruesit.
Në këtë udhëzues do të shqyrtojmë disa burime dhe marrës të paracaktuar dhe do të tregojmë se si t'i konfigurojmë ato me minimumin e përpjekjeve nga ana e përdoruesit. Shihni Udhëzimin ns-3 ose seksionet me udhëzime për informacion mbi konfigurimin e avancuar të gjurmimeve, përfshirë zgjerimin e hapësirës emëruese të gjurmimit dhe krijimin e burimeve të reja të gjurmimit.
5.3.1 ASCII Gjurmo
ns-3 ofron funksionalitete ndihmëse që sigurojnë një sistem të ulët të gjurmimit, për t'ju ndihmuar me detajet kur konfiguroni gjurmime paketa të thjeshta. Nëse e aktivizoni këtë funksion, do të shihni dalje në skedarët ASCII. Për ata që janë të njohur me daljet e ns-2, ky lloj gjurmimi është i ngjashëm out.tr, i cili është gjeneruar nga shumë skripta.
Le të kalojmë në punë dhe të shtojmë disa rezultate të gjurmimeve ASCII në skriptin tonë scratch/myfirst.cc. Saktësisht para thirrjes Simulator :: Run (), shtoni këto rreshta kodi:
AsciiTraceHelper ascii;
pointToPoint.EnableAsciiAll (ascii.CreateFileStream ("myfirst.tr"));Si nĂ« shumĂ« fraza tĂ« tjera nĂ« nsâ3, ky kod pĂ«rdor njĂ« objekt ndihmĂ«s pĂ«r tĂ« krijuar gjurmĂ«t ASCII. Rreshti i dytĂ« pĂ«rmban dy thirrje tĂ«ć” cleve metodeve. Metoda "brenda" CreateFileStream () pĂ«rdor idiomĂ«n e objektit anonim pĂ«r tĂ« krijuar njĂ« objekt filo ik nga staku (pa emĂ«r objekti) dhe e kalon atĂ« metodĂ«s qĂ« e thirret. NĂ« tĂ« ardhmen ne do tĂ« thellohemi nĂ« kĂ«tĂ« çështje, por gjithçka qĂ« ju nevojitet tĂ« dini nĂ« kĂ«tĂ« fazĂ« Ă«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 menaxhimin e objektit tĂ« krijuar gjatĂ« gjithĂ« jetĂ«s sĂ« tij, nĂ« tĂ« cilĂ«n zgjidhen problemet e shkaktuara nga njĂ« kufizim i panjohur (i qĂ«llimshĂ«m) i lidhur me kopjuesit e objekteve tĂ« fluxit C++.
Thirrja e jashtme EnableAsciiAll() i thotë asistencës së programit që dëshironi të përfshini në simulimin tuaj gjurmimin ASCII për të gjitha lidhjet midis pikave dhe që dëshironi që (pranuesit e caktuar të) regjistrojnë informacionin e lëvizjes së paketave në formatin ASCII.
Për ata që janë të njohur me ns-2, ngjarjet e ndjekura janë ekuivalente me të njohurat pika të gjurmimit që regjistrojnë ngjarje " + ", " - ", " d ", dhe " r ".
Tani mund të mblidhni skriptin dhe ta ekzekutoni nga linja e komandës:
$ ./waf --run scratch/myfirstSiç ka ndodhur edhe herĂ«ve tĂ« tjera, do tĂ« shihni disa mesazhe nga Waf, dhe mĂ« pas ââbuildâ finished successfullyâ (ndĂ«rtimi u pĂ«rfundua me sukses) me disa mesazhe nga programi nĂ« punĂ«.
Gjatë punës, programi do të krijojë një skedar me emrin myfirst.tr. Për shkak të karakteristikave të punës së Waf, me të drejtat, skedari krijohet në direktorinë e sipërme të depozitës dhe jo në drejtorinë lokale. Nëse dëshironi të ndryshoni rrugën ku ruhet gjurmimi, mund ta përcaktoni për Waf me parametrin --cwd. Ne nuk e bëmë këtë, për të parë skedarin ASCII të gjurmimit myfirst.tr në editorin tuaj të preferuar, na duhen të kalojmë në direktorinë e sipërme të depozitës sonë.
Analiza e gjurmës ASCII
Ka shumë informacion në një formë relativisht të dendur, por gjëja e parë që duhet të vini re është se skedari përbëhet nga rreshta të veçantë. Kjo do të bëhet qartë nëse zgjeroni dritaren e shikimit pak më shumë.
Ădo rresht nĂ« skedarin pĂ«rputhet me njĂ« ngjarje gjurmimi. NĂ« kĂ«tĂ« rast, ne po gjurmojmĂ« ngjarjet nĂ« radhĂ«n e transmetimit, e pranishme nĂ« çdo pajisje rrjetit punkt-punkt nĂ« simulim. RadhĂ« transmetimi Ă«shtĂ« radhĂ« pĂ«rmes sĂ« cilĂ«s duhet tĂ« kalojĂ« çdo paketĂ« pĂ«r kanalin punkt-punkt. Vini re 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:
+: ndodhi një operacion radhitjeje në radhën e pajisjes;
-: ndodhi një operacion nxjerrjeje në radhën e pajisjes;
d: paketa u hodh poshtë, zakonisht për shkak se radhë ishte e mbushur;
r: paketa u pranua nga pajisja rrjetit.
Le të shikojmë 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 nga ana e majtë:
0 +
1 2
2 /NodeList/0/DeviceList/0/$ns3::PointToPointNetDevice/TxQueue/Enqueue
3 ns3::PppHeader (
4 Protokolli Punkt-punkt: IP (0x0021))
6 ns3::Ipv4Header (
7 tos 0x0 ttl 64 id 0 protokoll 17 offset 0 flags [none]
8 gjatësia: 1052 10.1.1.1 > 10.1.1.2)
9 ns3::UdpHeader (
10 gjatësia: 1032 49153 > 9)
11 Ngarkesa (matësi=1024)Pjesa e parë e këtij eventi të avancuar të gjurmimit (rreshti 0) është operacioni. Këtu kemi simbolin +, i cili i përgjigjet operacionit të vendosjes në radhë për transmetim. Pjesa e dytë (rreshti 1) është koha e modelimit, e shprehur në sekonda. Mund të kujtoni se kërkuam UdpEchoClientApplication të fillojmë dërgimin e paketeve pas dy sekondash. Këtu shohim konfirmimin se kjo vërtet po ndodh.
Në pjesën tjetër të shembujve të gjurmimit (nga rreshti 2) tregohen burimi i gjurmimit që prodhoi këtë ngjarje (tregohet gjurmimi i hapësirës emërore). Mund ta imagjinoni hapësirën emërore të gjurmimit pak si hapësirën emërore të sistemit të skedarëve. Rrenja e hapësirës emërore është NodeList. Kjo i përgjigjet kontejnerit të menaxhuar kryesisht nga kodi i ns-3. Ajo përmban të gjitha nyjat që krijohen në skripti. Ashtu siç sistemi i skedarëve mund të ketë në rrenjë drejtoritë, në NodeList ne mund të kemi shumë nyje. Kështu, vargu /NodeList/0 iu referohet nyjës zero në NodeList, të cilën ne zakonisht e kuptojmë si "nyja 0". Në secilën nyje ka një listë pajisjesh që janë instaluar. Kjo listë është e vendosur më tej në hapësirën e emrave. Mund të shihni se ky ngjarje gjurmimi vjen nga DeviceList/0, që është pajisja zero e instaluar në nyjë.
Nënvargu i ardhshëm, $ ns3 :: PointToPointNetDevice, tregon se cila pajisje është në pozitat zero: lista e pajisjeve të nyjës zero. Kujtojmë se operacioni +, që ndodhet në vargun 0, do të thotë se një element u shtua në radhën e transmetimit të pajisjeve. Kjo reflektohet në segmentet e fundit të "rrugës së gjurmimit": TxQueue/Enqueue.
Pjesët e tjera në gjurmim duhet të jenë mjaft të kuptueshme në mënyrë intuitive. Vargjet 3-4 tregojnë se paketa është inkapsuluar në protokollin pikë-pikë. Vargjet 5-7 tregojnë se paketa ka një kokë IP4 dhe është krijuar në adresën IP 10.1.1.1 dhe është destinuar për 10.1.1.2. Vargjet 8-9 tregojnë se kjo paketë ka një kokë UDP dhe, në fund, vargu 10 tregon se Ngarkesa e dobishme është 1024 byte të pritur.
Rreshta e ardhshme në skedën e ndjekjes tregon se i njëjti paketë është nxjerrë nga radhat e transmetimit në të njëjtin nod.
Rreshta e tretë në skedën e ndjekjes tregon se paketa është pranuar nga pajisja rrjetike në nodin me serverin e pasqyrës. E kam rikrijuar këtë ngjarje më poshtë.
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 ndjekjes tani është r, dhe koha e simulimit është rritur në 2,25732 sekonda. Nëse e keni ndjekur me kujdes udhëzimet e manualit, kjo do të thotë se keni lënë DataRate e pajisjeve rrjetike dhe vonesën e kanalit në vlerat e tyre të paracaktuara. Kjo kohë duhet të jetë e njohur, siç e keni parë në seksionin e mëparshëm.
Regjistrimi i hapĂ«sirĂ«s emĂ«rtuese tĂ« burimit tĂ« ndjekjes (rreshti 2) Ă«shtĂ« modifikuar pĂ«r tĂ« reflektuar se kjo ngjarje vjen nga nodi 1 (/NodeList/1) Đž паĐșĐ”Ń ĐżŃĐžĐœŃŃ ĐžŃŃĐŸŃĐœĐžĐșĐŸĐŒ ŃŃаŃŃĐžŃĐŸĐČĐșĐž (/MacRx). Duhet t'ju jetĂ« mjaft e lehtĂ« tĂ« ndjekni lĂ«vizjen e paketĂ«s nĂ«pĂ«r topologji, duke shqyrtuar ato qĂ« mbeten nĂ« skedĂ«n e ndjekjes.
5.3.2 Gjurmo PCAP
NdihmĂ«sit e pajisjeve nsâ3 gjithashtu mund tĂ« pĂ«rdoren pĂ«r tĂ« krijuar skeda ndjekjeje nĂ« formatin .pcap. Akronimi pcap (zakonisht shkruhet me shkronja tĂ« vogla) tregon kapjen e paketave dhe nĂ« thelb Ă«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 (mĂ« parĂ« i quajtur Ethereal). MegjithatĂ«, ka shumĂ« analistat e rrugĂ«s qĂ« pĂ«rdorin kĂ«tĂ« format pakete. Ne rekomandojmĂ« pĂ«rdoruesve tĂ« shfrytĂ«zojnĂ« njĂ« shumĂ«llojshmĂ«ri mjetesh tĂ« disponueshme pĂ«r analizimin e rrugĂ«ve pcap. NĂ« kĂ«tĂ« udhĂ«zues, ne do tĂ« fokusohemi nĂ« shikimin e rrugĂ«ve pcap me anĂ« tĂ« tcpdump.
Aktivizimi i rrugës pcap bëhet me një rresht kodi.
pointToPoint.EnablePcapAll ("myfirst");Vendosni këtë rresht kodi pas kodit të rrugës ASCII që sapo shtuam në scratch/myfirst.cc. Vini re se ne kaluam vetëm stringun 'myfirst', dhe jo 'myfirst.pcap' ose diçka të tillë. Kjo është për faktin se parametri është një prefiks dhe jo emri i plotë i skedarit. Gjatë simulimit, ndihmuesi do të krijojë faktikisht një skedë rrugë për çdo pajisje pikë-pikë. Emrat e skedave do të ndërtohen me përdorimin e prefiksit, numrit të nyjës, numrit të pajisjes dhe prapashtesës '.'pcap».
Për shembullin tonë skenari, ne përfundimisht do të shohim skedarë me emrat "myfirst-0-0.pcap» dhe «myfirst-1-0.pcap", të cilat janë gjurmët pcap për nyjën 0-pajisje 0 dhe nyjën 1-pajisje 0 përkatësisht. Pasi të keni shtuar rreshtin e kodit për të përfshirë gjurmën pcap, mund të ekzekutoni skriptin në mënyrë të zakonshme:
$ ./waf --run scratch/myfirstNĂ«se shikoni nĂ« direktorinĂ« kryesore tĂ« shpĂ«rndarjes tuaj, duhet tĂ« shihni tre skedarĂ«: skedari ASCII i gjurmĂ«s myfirst.tr, tĂ« cilin e studiuam mĂ« parĂ«, skedarĂ«t myfirst-0-0.pcap dhe myfirst-1-0.pcap â skedarĂ«t e rinj pcap, tĂ« cilat sapo i gjeneruam.
Leximi i daljes me tcpdump
Derisa, për të parë skedarët pcap, më lehtë do të jetë 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 1024Në dump myfirst-0-0.pcap (pajisja klient) mund të shihni se paketa e jehonës dërgohet pas 2 sekondash simuluese. Nëse shikoni në dump-in e dytë (myfirst-1-0.pcap), do të shihni se paci pranohet në momentin 2,257324 sekonda. Do të shihni në dumpin e dytë se paci kthehet në momentin 2.257324 sekonda, dhe përfundimisht, se paci u mor përmes klientit në dumpin e parë në momentin 2.514648 sekonda.
Leximi i daljes me Wireshark
NĂ«se nuk jeni tĂ« njohur me Wireshark, ka njĂ« faqe interneti nga e cila mund tĂ« shkarkoni programe dhe dokumentacion: . Wireshark â kjo Ă«shtĂ« njĂ« ndĂ«rfaqe grafike pĂ«rdoruesi qĂ« mund tĂ« pĂ«rdoret pĂ«r tĂ« shfaqur kĂ«to skedarĂ« tĂ« gjurmimit. NĂ«se keni Wireshark, mund tĂ« hapni cilindo nga skedarĂ«t e gjurmimit dhe tĂ« shfaqni pĂ«rmbajtjen, sikur tĂ« kishit kapur pacat duke pĂ«rdorur njĂ« analizador pako.
Burimi: habr.com
