Ito ang command na ns-3-tutorial na maaaring patakbuhin sa OnWorks na libreng hosting provider gamit ang isa sa aming maramihang libreng online na workstation gaya ng Ubuntu Online, Fedora Online, Windows online emulator o MAC OS online emulator
PROGRAMA:
NAME
ns-3-tutorial - ns-3 Tutorial
Ito ang ns-3 Sangguni. Ang pangunahing dokumentasyon para sa proyekto ng ns-3 ay makukuha sa lima
mga form:
· ns-3 doxygen: Dokumentasyon ng mga pampublikong API ng simulator
· Pagtuturo (ito dokumento), Manwal, at Modelong Library para sa pinakahuli pakawalan at
pag-unlad puno
· ns-3 wiki
Ang dokumentong ito ay nakasulat sa mulingStracturedText para Sphinx at pinananatili sa
doc/tutorial direktoryo ng source code ng ns-3.
PANIMULA
Ang ns-3 Ang simulator ay isang discrete-event network simulator na pangunahing naka-target para sa pananaliksik
at pang-edukasyon na paggamit. Ang ns-3 proyekto, na nagsimula noong 2006, ay isang open-source na proyekto
pagbubuo ns-3.
Ang layunin ng tutorial na ito ay magpakilala ng bago ns-3 mga user sa system sa isang structured
paraan. Minsan mahirap para sa mga bagong user na kumuha ng mahahalagang impormasyon mula sa detalyado
mga manwal at i-convert ang impormasyong ito sa mga gumaganang simulation. Sa tutorial na ito, kami
bubuo ng ilang halimbawang simulation, pagpapakilala at pagpapaliwanag ng mga pangunahing konsepto at
mga tampok habang nagpapatuloy tayo.
Habang nagbubukas ang tutorial, ipapakilala namin ang buo ns-3 dokumentasyon at magbigay
mga payo sa source code para sa mga interesadong pag-aralan nang mas malalim ang mga gawain ng
system.
Ang ilang mga pangunahing punto ay dapat tandaan sa simula:
· ns-3 ay open-source, at ang proyekto ay nagsusumikap na mapanatili ang isang bukas na kapaligiran para sa
mga mananaliksik na mag-ambag at ibahagi ang kanilang software.
· ns-3 ay hindi isang pabalik-katugmang extension ng ns-2; ito ay isang bagong simulator. Ang dalawa
Ang mga simulator ay parehong nakasulat sa C++ ngunit ns-3 ay isang bagong simulator na hindi sumusuporta sa
ns-2 Mga API. Ilang mga modelo mula sa ns-2 nai-port na mula sa ns-2 sa ns-3. ang
proyekto ay patuloy na mapanatili ns-2 habang ns-3 ay itinatayo, at mag-aaral
mga mekanismo ng paglipat at pagsasama.
Tungkol samin ns-3
ns-3 ay binuo upang magbigay ng isang bukas, extensible network simulation platform, para sa
pananaliksik at edukasyon sa networking. Sa madaling sabi, ns-3 nagbibigay ng mga modelo kung paano ang packet data
gumagana at gumaganap ang mga network, at nagbibigay ng simulation engine para isagawa ng mga user
mga eksperimento sa simulation. Ilan sa mga dahilan para gamitin ns-3 isama upang maisagawa ang mga pag-aaral na
ay mas mahirap o hindi posible na gumanap sa mga tunay na sistema, upang pag-aralan ang pag-uugali ng system
sa isang lubos na kinokontrol, maaaring muling gawin na kapaligiran, at upang matutunan ang tungkol sa kung paano gumagana ang mga network.
Mapapansin ng mga user na nakalagay ang available na modelo ns-3 nakatutok sa pagmomodelo kung paano ang Internet
gumagana ang mga protocol at network, ngunit ns-3 ay hindi limitado sa mga sistema ng Internet; ilang mga gumagamit
ay gumagamit ns-3 upang magmodelo ng mga sistemang hindi nakabatay sa Internet.
Maraming mga simulation tool ang umiiral para sa network simulation studies. Nasa ibaba ang ilan
mga tampok na pagkakaiba ng ns-3 sa kaibahan sa iba pang mga tool.
· ns-3 ay idinisenyo bilang isang hanay ng mga aklatan na maaaring pagsamahin at gayundin sa iba
mga panlabas na library ng software. Habang ang ilang simulation platform ay nagbibigay sa mga user ng isang
solong, pinagsama-samang graphical user interface na kapaligiran kung saan ang lahat ng mga gawain ay isinasagawa
sa labas, ns-3 ay mas modular sa bagay na ito. Maraming mga panlabas na animator at pagsusuri ng data
at mga visualization tool ay maaaring gamitin sa ns-3. Gayunpaman, dapat asahan ng mga user na magtrabaho sa
ang command line at gamit ang C++ at/o Python software development tools.
· ns-3 ay pangunahing ginagamit sa mga sistema ng Linux, kahit na mayroong suporta para sa FreeBSD, Cygwin
(para sa Windows), at ang suporta ng katutubong Windows Visual Studio ay nasa proseso ng pagiging
umunlad.
· ns-3 ay hindi isang opisyal na suportadong software na produkto ng anumang kumpanya. Suporta para sa ns-3
ay ginagawa sa isang pinakamahusay na pagsisikap na batayan sa ns-3-users mailing list.
para ns-2 Users
Para sa mga pamilyar sa ns-2 (isang sikat na tool na nauna ns-3), ang pinaka nakikita sa labas
baguhin kapag lumipat sa ns-3 ay ang pagpili ng scripting language. Mga programa sa ns-2 ay
scripted sa OTcl at ang mga resulta ng mga simulation ay maaaring makita gamit ang Network Animator
nam. Hindi posibleng magpatakbo ng simulation ns-2 pulos mula sa C++ (ibig sabihin, bilang pangunahing()
programa nang walang anumang OTcl). Bukod dito, ang ilang bahagi ng ns-2 ay nakasulat sa C++ at
iba sa OTcl. Sa ns-3, ang simulator ay ganap na nakasulat sa C++, na may opsyonal na Python
mga binding. Ang mga simulation script ay maaaring isulat sa C++ o sa Python. Mga bagong animator
at mga visualizer ay magagamit at nasa ilalim ng kasalukuyang pag-unlad. Since ns-3 bumubuo ng pcap
packet trace file, ang iba pang mga utility ay maaaring gamitin upang pag-aralan ang mga bakas din. Dito sa
tutorial, magtutuon muna tayo sa direktang pag-script sa C++ at pagbibigay-kahulugan sa mga resulta
sa pamamagitan ng mga trace file.
Ngunit may mga pagkakatulad din (pareho, halimbawa, ay batay sa mga bagay na C++, at ilan
code mula sa ns-2 ay nai-port na sa ns-3). Susubukan naming i-highlight ang mga pagkakaiba
sa pagitan ng ns-2 at ns-3 habang nagpapatuloy tayo sa tutorial na ito.
Isang tanong na madalas nating marinig ay "Dapat ko pa bang gamitin ns-2 o lumipat sa ns-3?" Dito sa
opinyon ng may-akda, maliban kung ang gumagamit ay nasa anumang paraan ns-2 (alinman sa batay sa umiiral na
personal na kaginhawaan at kaalaman sa ns-2, o batay sa isang partikular na modelo ng simulation na
ay magagamit lamang sa ns-2), ang isang user ay magiging mas produktibo sa ns-3 para sa mga sumusunod
mga kadahilanan:
· ns-3 ay aktibong pinananatili sa isang aktibo, tumutugon na mailing list ng mga user, habang ns-2 is
bahagya lamang na napanatili at hindi nakakita ng makabuluhang pag-unlad sa pangunahing code tree nito
para sa higit sa isang dekada.
· ns-3 nagbibigay ng mga feature na hindi available sa ns-2, tulad ng pagpapatupad ng code sa pagpapatupad
kapaligiran (nagbibigay-daan sa mga user na magpatakbo ng totoong code ng pagpapatupad sa simulator)
· ns-3 nagbibigay ng mas mababang antas ng base ng abstraction kumpara sa ns-2, na nagbibigay-daan sa pag-align nito
mas mabuti kung paano pinagsama-sama ang mga tunay na sistema. Ang ilang mga limitasyon ay matatagpuan sa ns-2 (Tulad ng
pagsuporta sa maraming uri ng mga interface sa mga node nang tama) ay naayos na ns-3.
ns-2 ay may mas magkakaibang hanay ng mga naiambag na module kaysa sa ginagawa ns-3, dahil sa tagal nito
kasaysayan. gayunpaman, ns-3 ay may mas detalyadong mga modelo sa ilang tanyag na lugar ng pananaliksik
(kabilang ang mga sopistikadong modelo ng LTE at WiFi), at ang suporta nito sa code ng pagpapatupad
umamin ng napakalawak na spectrum ng mga high-fidelity na modelo. Maaaring magulat ang mga gumagamit na malaman iyon
ang buong Linux networking stack ay maaaring i-encapsulated sa isang ns-3 node, gamit ang Direct
Framework ng Code Execution (DCE). ns-2 minsan maaaring i-port ang mga modelo sa ns-3, lalo na
kung sila ay ipinatupad sa C++.
Kung may pagdududa, isang magandang patnubay ay ang pagtingin sa parehong mga simulator (pati na rin sa iba pa
simulators), at sa partikular ang mga modelong magagamit para sa iyong pananaliksik, ngunit tandaan
na ang iyong karanasan ay maaaring maging mas mahusay sa paggamit ng tool na aktibong binuo at
pinananatili (ns-3).
Nag-aambag
ns-3 ay isang research at educational simulator, ng at para sa research community. Ito ay
umasa sa mga patuloy na kontribusyon ng komunidad upang bumuo ng mga bagong modelo, pag-debug o
panatilihin ang mga umiiral na, at ibahagi ang mga resulta. Mayroong ilang mga patakaran na inaasahan namin
hikayatin ang mga tao na mag-ambag sa ns-3 tulad ng mayroon sila para sa ns-2:
· Open source na paglilisensya batay sa GNU GPLv2 compatibility
· wiki
· Nag-ambag kodigo pahina, katulad ng ns-2Ang sikat na Contributed Code ni pahina
· Buksan kulisap mangangaso
Napagtanto namin na kung binabasa mo ang dokumentong ito, ang pag-aambag pabalik sa proyekto ay
marahil hindi ang iyong pangunahing alalahanin sa puntong ito, ngunit gusto naming malaman mo iyon
Ang pag-aambag ay nasa diwa ng proyekto at maging ang pagkilos ng pag-drop sa amin ng isang tala
tungkol sa iyong maagang karanasan sa ns-3 (hal. "ang seksyon ng tutorial na ito ay hindi malinaw..."),
ang mga ulat ng lipas na dokumentasyon, atbp. ay lubos na pinahahalagahan.
Sangguni samahan
Ipinapalagay ng tutorial na maaaring sundan ng mga bagong user ang isang landas gaya ng sumusunod:
· Subukang mag-download at bumuo ng isang kopya;
· Subukang magpatakbo ng ilang sample na programa;
· Tingnan ang simulation output, at subukang ayusin ito.
Bilang resulta, sinubukan naming ayusin ang tutorial kasama ang malawak na pagkakasunud-sunod sa itaas ng
Mga kaganapan.
Kayamanan
Ang web
Mayroong ilang mahahalagang mapagkukunan kung saan alinman ns-3 dapat magkaroon ng kamalayan ang gumagamit. Ang pangunahing web
matatagpuan ang site sa http://www.nsnam.org at nagbibigay ng access sa pangunahing impormasyon tungkol sa
ns-3 sistema. Ang detalyadong dokumentasyon ay makukuha sa pamamagitan ng pangunahing web site sa
http://www.nsnam.org/documentation/. Makakahanap ka rin ng mga dokumentong nauugnay sa system
arkitektura mula sa pahinang ito.
Mayroong isang Wiki na umakma sa pangunahing ns-3 web site na makikita mo sa
http://www.nsnam.org/wiki/. Makakakita ka ng mga FAQ ng user at developer doon, pati na rin
mga gabay sa pag-troubleshoot, code na iniambag ng third-party, mga papel, atbp.
Ang source code ay maaaring matagpuan at i-browse sa http://code.nsnam.org/. Doon mo mahahanap
ang kasalukuyang development tree sa repository na pinangalanan ns-3-dev. Mga nakaraang release at
Ang mga eksperimentong repositoryo ng mga pangunahing developer ay maaari ding matagpuan doon.
papalit-palit
Ang mga kumplikadong sistema ng software ay nangangailangan ng ilang paraan upang pamahalaan ang organisasyon at mga pagbabago sa
pinagbabatayan na code at dokumentasyon. Mayroong maraming mga paraan upang maisagawa ang gawaing ito, at maaari mo
narinig ang ilan sa mga system na kasalukuyang ginagamit para gawin ito. Ang Kasabay
Ang Version System (CVS) ay marahil ang pinakakilala.
Ang ns-3 Ginagamit ng proyekto ang Mercurial bilang sistema ng pamamahala ng source code nito. Bagama't hindi mo ginagawa
kailangang malaman ang marami tungkol sa Mercurial upang makumpleto ang tutorial na ito, inirerekomenda namin
pagiging pamilyar sa Mercurial at paggamit nito upang ma-access ang source code. Ang Mercurial ay may a
web site sa http://www.selenic.com/mercurial/, kung saan maaari kang makakuha ng binary o source
mga release ng Software Configuration Management (SCM) system na ito. Selenic (ang developer
ng Mercurial) ay nagbibigay din ng tutorial sa
http://www.selenic.com/mercurial/wiki/index.cgi/Tutorial/, at isang QuickStart na gabay sa
http://www.selenic.com/mercurial/wiki/index.cgi/QuickStart/.
Makakahanap ka rin ng mahahalagang impormasyon tungkol sa paggamit ng Mercurial at ns-3 sa pangunahing ns-3 web
site.
Waf
Kapag na-download mo na ang source code sa iyong lokal na system, kakailanganin mong i-compile iyon
mapagkukunan upang makabuo ng mga magagamit na programa. Tulad ng sa kaso ng source code management, doon
ay maraming mga tool na magagamit upang maisagawa ang function na ito. Marahil ang pinakakilala sa mga ito
mga kasangkapan ay gumawa. Kasabay ng pagiging pinakakilala, gumawa ay marahil ang pinakamahirap
upang gamitin sa isang napakalaking at lubos na nako-configure na sistema. Dahil dito, maraming alternatibo
ay binuo. Kamakailan ang mga sistemang ito ay binuo gamit ang Python
wika.
Ang build system na Waf ay ginagamit sa ns-3 proyekto. Isa ito sa bagong henerasyon ng
Mga sistema ng build na nakabatay sa Python. Hindi mo kakailanganing maunawaan ang anumang Python para mabuo ang
nabubuhay ns-3 system.
Para sa mga interesado sa madugong mga detalye ng Waf, ang pangunahing web site ay matatagpuan sa
http://code.google.com/p/waf/.
Pag-unlad kapaligiran
Tulad ng nabanggit sa itaas, scripting in ns-3 ay ginagawa sa C++ o Python. Karamihan sa mga ns-3 Ang API ay
magagamit sa Python, ngunit ang mga modelo ay nakasulat sa C++ sa alinmang kaso. Isang nagtatrabaho
Ang kaalaman sa C++ at object-oriented na mga konsepto ay ipinapalagay sa dokumentong ito. Kukunin namin
ilang oras upang suriin ang ilan sa mga mas advanced na konsepto o posibleng hindi pamilyar na wika
mga tampok, idyoma at mga pattern ng disenyo habang lumilitaw ang mga ito. Hindi namin gusto ang tutorial na ito
magdevolve sa isang C++ na tutorial, gayunpaman, kaya inaasahan namin ang isang pangunahing utos ng wika.
Mayroong halos hindi maisip na bilang ng mga mapagkukunan ng impormasyon sa C++ na magagamit sa
web o naka-print.
Kung bago ka sa C++, maaaring gusto mong humanap ng aklat o web site na nakabatay sa tutorial o cookbook
at gawin sa pamamagitan ng hindi bababa sa mga pangunahing tampok ng wika bago magpatuloy. Para sa
halimbawa, ito sangguni.
Ang ns-3 gumagamit ang system ng ilang bahagi ng "toolchain" ng GNU para sa pag-unlad. A
Ang software toolchain ay ang hanay ng mga tool sa programming na magagamit sa ibinigay na kapaligiran. Para sa
isang mabilis na pagsusuri ng kung ano ang kasama sa GNU toolchain tingnan,
http://en.wikipedia.org/wiki/GNU_toolchain. ns-3 gumagamit ng gcc, GNU binutils, at gdb.
Gayunpaman, hindi kami gumagamit ng GNU build system tools, ni make o autotools. Gumagamit kami ng Waf
para sa mga function na ito.
Karaniwan ang isang ns-3 ang may-akda ay gagana sa Linux o isang kapaligirang tulad ng Linux. Para sa mga
tumatakbo sa ilalim ng Windows, mayroong mga umiiral na kapaligiran na gayahin ang kapaligiran ng Linux
iba't ibang grado. Ang ns-3 proyekto ay sa nakaraan (ngunit hindi sa kasalukuyan) suportado
pag-unlad sa kapaligiran ng Cygwin para sa mga user na ito. Tingnan mo http://www.cygwin.com/ para
mga detalye sa pag-download, at bisitahin ang ns-3 wiki para sa karagdagang impormasyon tungkol sa Cygwin at
ns-3. Ang MinGW ay kasalukuyang hindi opisyal na suportado. Ang isa pang alternatibo sa Cygwin ay ang
mag-install ng virtual machine environment tulad ng VMware server at mag-install ng Linux virtual
machine.
Saksakan Programming
Ipapalagay namin ang isang pangunahing pasilidad na may Berkeley Sockets API sa mga halimbawang ginamit dito
pagtuturo. Kung bago ka sa mga socket, inirerekomenda namin ang pagsusuri sa API at ilang karaniwang paggamit
kaso. Para sa isang mahusay na pangkalahatang-ideya ng programming TCP/IP sockets inirerekomenda namin TCP / IP Sockets in
C, Donahoo at Calvert.
Mayroong nauugnay na web site na may kasamang pinagmulan para sa mga halimbawa sa aklat, na
maaari mong mahanap sa: http://cs.baylor.edu/~donahoo/practical/CSockets/.
Kung naiintindihan mo ang unang apat na kabanata ng aklat (o para sa mga walang access
sa isang kopya ng aklat, ang mga echo client at server na ipinapakita sa website sa itaas) gagawin mo
maging nasa mabuting kalagayan upang maunawaan ang tutorial. Mayroong katulad na libro sa Multicast
Mga socket, Maramihang Mga socket, Makofske at Almeroth. na sumasaklaw sa materyal na maaaring kailanganin mo
maunawaan kung titingnan mo ang mga halimbawa ng multicast sa pamamahagi.
PAGKAKITA NAGSIMULA
Ang seksyong ito ay naglalayong dalhin ang isang gumagamit sa isang gumaganang estado na nagsisimula sa isang makina na
maaaring hindi kailanman nagkaroon ns-3 naka-install. Sinasaklaw nito ang mga sinusuportahang platform, mga kinakailangan, mga paraan upang
kumuha ns-3, mga paraan upang bumuo ns-3, at mga paraan para i-verify ang iyong build at patakbuhin ang mga simpleng program.
Pangkalahatang-ideya
ns-3 ay binuo bilang isang sistema ng mga software library na nagtutulungan. Ang mga programa ng gumagamit ay maaaring
nakasulat na nag-uugnay sa (o nag-import mula) sa mga aklatang ito. Ang mga programa ng gumagamit ay nakasulat sa
alinman sa C++ o Python programming language.
ns-3 ay ibinahagi bilang source code, ibig sabihin na ang target na sistema ay kailangang magkaroon ng a
software development kapaligiran upang bumuo ng mga aklatan muna, pagkatapos ay bumuo ng user
programa. ns-3 sa prinsipyo ay maaaring ipamahagi bilang mga pre-built na aklatan para sa mga napili
system, at sa hinaharap maaari itong ipamahagi sa ganoong paraan, ngunit sa kasalukuyan, maraming mga gumagamit
talagang gawin ang kanilang trabaho sa pamamagitan ng pag-edit ns-3 mismo, kaya ang pagkakaroon ng source code sa paligid upang muling itayo
ang mga aklatan ay kapaki-pakinabang. Kung ang isang tao ay nais na isagawa ang trabaho ng paggawa ng pre-built
mga aklatan at mga pakete para sa mga operating system, mangyaring makipag-ugnayan sa ns-developers mailing
listahan.
Sa sumusunod, titingnan natin ang dalawang paraan ng pag-download at pagbuo ns-3. Ang una ay
upang mag-download at bumuo ng opisyal na release mula sa pangunahing web site. Ang pangalawa ay ang pagkuha
at bumuo ng mga kopya ng pagpapaunlad ng ns-3. Tatalakayin natin ang parehong mga halimbawa mula noong mga tool
kasangkot ay bahagyang naiiba.
Nagda-download ns-3
Ang ns-3 system sa kabuuan ay isang medyo kumplikadong sistema at may ilang mga dependencies sa
iba pang mga bahagi. Kasama ang mga system na malamang na haharapin mo araw-araw (ang
GNU toolchain, Mercurial, isang text editor) kakailanganin mong tiyakin na ang isang bilang ng
may mga karagdagang library sa iyong system bago magpatuloy. ns-3 nagbibigay ng wiki
page na kinabibilangan ng mga page na may maraming kapaki-pakinabang na pahiwatig at tip. Ang isang ganoong pahina ay ang
pahina ng "Pag-install", http://www.nsnam.org/wiki/Installation.
Ang seksyong "Mga Kinakailangan" ng pahina ng wiki na ito ay nagpapaliwanag kung aling mga pakete ang kinakailangan
suportang karaniwan ns-3 mga opsyon, at nagbibigay din ng mga utos na ginamit upang i-install ang mga ito para sa
karaniwang mga variant ng Linux. Ang mga gumagamit ng Cygwin ay kailangang gumamit ng Cygwin installer (kung ikaw ay isang
Cygwin user, ginamit mo ito upang i-install ang Cygwin).
Baka gusto mong gamitin ang pagkakataong ito upang tuklasin ang ns-3 wiki kasi meron talaga
isang kayamanan ng impormasyon doon.
Mula sa puntong ito pasulong, ipagpalagay namin na ang mambabasa ay nagtatrabaho sa Linux o a
Linux emulation environment (Linux, Cygwin, atbp.) at may naka-install na GNU toolchain at
na-verify kasama ng mga paunang kinakailangan na binanggit sa itaas. Ipagpalagay din natin iyon
mayroon kang Mercurial at Waf na naka-install at tumatakbo sa target na sistema.
Ang ns-3 Ang code ay magagamit sa Mercurial repository sa server http://code.nsnam.org.
Maaari ka ring mag-download ng tarball release sa http://www.nsnam.org/release/, o maaari kang magtrabaho
na may mga repositoryo gamit ang Mercurial. Inirerekomenda namin ang paggamit ng Mercurial maliban kung may magandang
dahilan para hindi. Tingnan ang dulo ng seksyong ito para sa mga tagubilin kung paano kumuha ng tarball
pakawalan.
Ang pinakasimpleng paraan upang makapagsimula sa paggamit ng mga Mercurial repository ay ang paggamit ng ns-3-allinone
kapaligiran. Ito ay isang set ng mga script na namamahala sa pag-download at pagbuo ng
iba't ibang subsystem ng ns-3 para sa iyo. Inirerekomenda namin na simulan mo ang iyong ns-3 magtrabaho dito
kapaligiran.
Ang isang kasanayan ay ang lumikha ng isang direktoryo na tinatawag lugar ng trabaho sa isang home directory kung saan
maaaring panatilihin ng isa ang mga lokal na imbakan ng Mercurial. Magagawa ang anumang pangalan ng direktoryo, ngunit ipagpalagay namin
na lugar ng trabaho ay ginagamit dito (tandaan: Repos maaari ding gamitin sa ilang dokumentasyon bilang isang
halimbawa pangalan ng direktoryo).
Nagda-download ns-3 paggamit a tarball
Ang tarball ay isang partikular na format ng software archive kung saan maraming file ang naka-bundle
magkasama at ang archive ay posibleng naka-compress. ns-3 Ang mga software release ay ibinibigay sa pamamagitan ng a
nada-download na tarball. Ang proseso para sa pag-download ns-3 sa pamamagitan ng tarball ay simple; ikaw lang
kailangang pumili ng release, i-download ito at i-decompress ito.
Ipagpalagay natin na ikaw, bilang isang user, ay gustong bumuo ns-3 sa isang lokal na direktoryo na tinatawag
lugar ng trabaho. Kung ampunin mo ang lugar ng trabaho diskarte sa direktoryo, maaari kang makakuha ng kopya ng isang release
sa pamamagitan ng pag-type ng sumusunod sa iyong Linux shell (palitan ang naaangkop na mga numero ng bersyon,
syempre):
$ cd
$ mkdir workspace
$ cd workspace
$ wget http://www.nsnam.org/release/ns-allinone-3.22.tar.bz2
$ tar xjf ns-allinone-3.22.tar.bz2
Kung lumipat ka sa direktoryo ns-allinone-3.22 dapat mong makita ang isang bilang ng mga file:
$ls
bake constants.py ns-3.22 README
build.py netanim-3.105 pybindgen-0.16.0.886 util.py
Handa ka na ngayong bumuo ng base ns-3 pamamahagi.
Nagda-download ns-3 paggamit maghurno
Ang bake ay isang tool para sa distributed integration at building, na binuo para sa ns-3 proyekto.
Maaaring gamitin ang bake upang kunin ang mga bersyon ng pagpapaunlad ng ns-3 software, at upang i-download at
bumuo ng mga extension sa base ns-3 pamamahagi, gaya ng Direct Code Execution
kapaligiran, Network Simulation Cradle, kakayahang lumikha ng mga bagong Python binding, at iba pa.
Sa kamakailang ns-3 release, ang Bake ay kasama sa release tarball. Ang pagsasaayos
Ang file na kasama sa inilabas na bersyon ay magbibigay-daan sa isa na mag-download ng anumang software noon
kasalukuyang sa oras ng paglabas. Iyon ay, halimbawa, ang bersyon ng Bake na iyon
ipinamahagi kasama ang ns-3.21 maaaring gamitin ang release para kumuha ng mga bahagi para doon ns-3 pakawalan
o mas maaga, ngunit hindi magagamit upang kunin ang mga bahagi para sa mga susunod na release (maliban kung ang
bakeconf.xml na-update ang file).
Maaari mo ring makuha ang pinakabagong kopya ng lutuin sa hurno sa pamamagitan ng pag-type ng sumusunod sa iyong Linux
shell (ipagpalagay na na-install mo ang Mercurial):
$ cd
$ mkdir workspace
$ cd workspace
$ hg clone http://code.nsnam.org/bake
Habang isinasagawa ang utos ng hg (Mercurial), dapat mong makita ang isang bagay tulad ng sumusunod
ipinakita,
...
direktoryo ng patutunguhan: maghurno
humihiling ng lahat ng pagbabago
pagdaragdag ng mga pagbabago
pagdaragdag ng mga manifest
pagdaragdag ng mga pagbabago sa file
nagdagdag ng 339 na mga pagbabago na may 796 na mga pagbabago sa 63 na mga file
pag-update sa default na sangay
Na-update ang 45 file, pinagsama ang 0 file, inalis ang 0 file, hindi nalutas ang 0 file
Matapos makumpleto ang clone command, dapat kang magkaroon ng isang direktoryo na tinatawag lutuin sa hurno, ang mga nilalaman
na kung saan ay dapat magmukhang katulad ng sumusunod:
$ls
maghurno bakeconf.xml doc generate-binary.py TODO
pagsubok ng mga halimbawa ng bake.py
Pansinin na nag-download ka lang ng ilang script ng Python at isang Python module na tinatawag
lutuin sa hurno. Ang susunod na hakbang ay ang paggamit ng mga script na iyon para i-download at buuin ang ns-3
pamamahagi ng iyong pinili.
Mayroong ilang mga target ng configuration na magagamit:
1. ns-3.22: ang module na naaayon sa release; ito ay magda-download ng mga sangkap na katulad
sa release tarball.
2. ns-3-dev: isang katulad na module ngunit gumagamit ng development code tree
3. ns-allinone-3.22: ang module na may kasamang iba pang opsyonal na feature gaya ng click
pagruruta, openflow para sa ns-3, at ang Network Simulation Cradle
4. ns-3-allinone: katulad ng inilabas na bersyon ng allinone module, ngunit para sa
code ng pag-unlad.
Ang kasalukuyang development snapshot (hindi na-release) ng ns-3 maaaring matagpuan sa
http://code.nsnam.org/ns-3-dev/. Sinusubukan ng mga developer na panatilihin ang mga repository na ito
pare-pareho, gumaganang estado ngunit sila ay nasa isang development area na may hindi pa nailalabas na code
kasalukuyan, kaya maaaring gusto mong isaalang-alang ang pananatili sa isang opisyal na pagpapalabas kung hindi mo kailangan
bagong ipinakilala na mga tampok.
Mahahanap mo ang pinakabagong bersyon ng code sa pamamagitan ng pag-inspeksyon sa listahan ng repositoryo
o sa pamamagitan ng pagpunta sa "ns-3 Nagpapalabas" web page at pag-click sa pinakabagong link ng release.
Magpapatuloy kami sa halimbawa ng tutorial na ito sa ns-3.22.
Gagamitin na natin ngayon ang bake tool para hilahin pababa ang iba't ibang piraso ng ns-3 ikaw ay magiging
gamit. Una, magsasabi tayo ng isang salita tungkol sa pagpapatakbo ng bake.
gumagana ang bake sa pamamagitan ng pag-download ng mga source package sa isang source directory, at pag-install
mga aklatan sa isang direktoryo ng build. bake ay maaaring tumakbo sa pamamagitan ng pagtukoy sa binary, ngunit kung isa
pinipiling magpatakbo ng bake mula sa labas ng direktoryo kung saan ito na-download, ito ay ipinapayong
upang ilagay ang bake sa iyong landas, tulad ng mga sumusunod (Linux bash shell halimbawa). Una, magbago
sa direktoryo ng 'bake', at pagkatapos ay itakda ang mga sumusunod na variable ng kapaligiran
$ export BAKE_HOME=`pwd`
$ export PATH=$PATH:$BAKE_HOME:$BAKE_HOME/build/bin
$ i-export ang PYTHONPATH=$PYTHONPATH:$BAKE_HOME:$BAKE_HOME/build/lib
Ilalagay nito ang bake.py program sa landas ng shell, at papayagan ang iba pang mga program na
maghanap ng mga executable at library na ginawa ng bake. Bagama't hindi ginagawa ng ilang kaso ng paggamit ng bake
nangangailangan ng pagtatakda ng PATH at PYTHONPATH tulad ng nasa itaas, mga buong build ng ns-3-allinone (na may
mga opsyonal na pakete) ay karaniwang ginagawa.
Pumunta sa direktoryo ng workspace at i-type ang sumusunod sa iyong shell:
$ ./bake.py configure -e ns-3.22
Susunod, hihilingin namin sa bake na suriin kung mayroon kaming sapat na mga tool upang mag-download ng iba't ibang bahagi.
Uri:
$ ./bake.py check
Dapat mong makita ang isang bagay tulad ng sumusunod,
> Python - OK
> GNU C++ compiler - OK
> Mercurial - OK
> CVS - OK
> GIT - OK
> Bazaar - OK
> Tar tool - OK
> Unzip tool - OK
> Unrar tool - nawawala
> 7z data compression utility - OK
> XZ data compression utility - OK
> Gawin - OK
> cMake - OK
> patch tool - OK
> autoreconf tool - OK
> Path na hinanap para sa mga tool: /usr/lib64/qt-3.3/bin /usr/lib64/ccache
/ usr / local / bin / bin / usr / bin / usr / local / sbin / usr / sbin / sbin
/home/tomh/bin bin
Sa partikular, ang mga tool sa pag-download tulad ng Mercurial, CVS, GIT, at Bazaar ang aming punong-guro
alalahanin sa puntong ito, dahil pinapayagan nila kaming kunin ang code. Mangyaring i-install ang nawawala
mga tool sa yugtong ito, sa karaniwang paraan para sa iyong system (kung kaya mo), o makipag-ugnayan
iyong system administrator kung kinakailangan upang mai-install ang mga tool na ito.
Susunod, subukang i-download ang software:
$ ./bake.py download
dapat magbunga ng isang bagay tulad ng:
>> Naghahanap ng system dependency pygoocanvas - OK
>> Naghahanap ng system dependency python-dev - OK
>> Naghahanap ng system dependency pygraphviz - OK
>> Dina-download ang pybindgen-0.16.0.886 - OK
>> Naghahanap ng system dependency g++ - OK
>> Naghahanap ng system dependency qt4 - OK
>> Dina-download ang netanim-3.105 - OK
>> Dina-download ang ns-3.22 - OK
Iminumungkahi ng nasa itaas na tatlong pinagmumulan ang na-download. Suriin ang pinagmulan direktoryo
ngayon at i-type ls; dapat makita ng isa:
$ls
netanim-3.105 ns-3.22 pybindgen-0.16.0.886
Handa ka na ngayong bumuo ng ns-3 pamamahagi.
gusali ns-3
gusali sa build.py
Kapag nagtatrabaho mula sa isang inilabas na tarball, sa unang pagkakataon na itayo mo ang ns-3 project na kaya mo
bumuo gamit ang isang convenience program na makikita sa lahat sa isa direktoryo. Ang programang ito ay tinatawag na
build.py. Iko-configure ng program na ito ang proyekto para sa iyo sa pinakakaraniwan
kapaki-pakinabang na paraan. Gayunpaman, pakitandaan na mas advanced na configuration at gumagana sa ns-3 habilin
karaniwang may kinalaman sa paggamit ng katutubong ns-3 build system, Waf, na ipapakilala mamaya dito
pagtuturo.
Kung nag-download ka gamit ang isang tarball dapat mayroon kang isang direktoryo na tinatawag na isang katulad
ns-allinone-3.22 sa ilalim ng iyong ~/workspace direktoryo. I-type ang sumusunod:
$ ./build.py --enable-examples --enable-tests
Dahil nagtatrabaho kami sa mga halimbawa at pagsubok sa tutorial na ito, at dahil hindi
binuo bilang default sa ns-3, ang mga argumento para sa build.py ay nagsasabi dito na buuin ang mga ito para sa amin. Ang
Nagde-default din ang program sa pagbuo ng lahat ng magagamit na mga module. Mamaya, maaari kang bumuo ns-3
nang walang mga halimbawa at pagsubok, o alisin ang mga module na hindi kailangan para sa iyong trabaho,
kung nais mo.
Makakakita ka ng maraming karaniwang mga mensahe ng output ng compiler na ipinapakita habang binubuo ang build script
ang iba't ibang piraso na iyong na-download. Sa kalaunan, dapat mong makita ang sumusunod:
Waf: Umalis sa direktoryo `/path/to/workspace/ns-allinone-3.22/ns-3.22/build'
Matagumpay na natapos ang 'build' (6m25.032s)
Mga module na binuo:
antenna aodv application
config-store ng mga gusali ng tulay
core csma csma-layout
dsdv dsr enerhiya
fd-net-device flow-monitor internet
lr-wpan lte mesh
mobility mpi netanim (walang Python)
network nix-vector-routing olsr
point-to-point point-to-point-layout propagation
sixlowpan spectrum stats
tap-bridge test (walang Python) topology-read
uan virtual-net-device wave
wifi wimax
Mga module na hindi binuo (tingnan ang ns-3 tutorial para sa paliwanag):
brite click openflow
visualizer
Umalis sa direktoryo `./ns-3.22'
Tungkol sa bahagi tungkol sa mga module na hindi binuo:
Mga module na hindi binuo (tingnan ang ns-3 tutorial para sa paliwanag):
brite click openflow
visualizer
Nangangahulugan lamang ito na ang ilan ns-3 Ang mga module na may mga dependency sa labas ng mga aklatan ay maaaring hindi
naitayo na, o partikular na hiniling ng configuration na huwag gawin ang mga ito. ginagawa nito
hindi nangangahulugan na ang simulator ay hindi matagumpay na nakagawa o na ito ay magbibigay ng mali
mga resulta para sa mga module na nakalista bilang binuo.
gusali sa lutuin sa hurno
Kung ginamit mo ang bake sa itaas upang kumuha ng source code mula sa mga repositoryo ng proyekto, maaari kang magpatuloy
gamitin ito sa pagbuo ns-3. Uri
$ ./bake.py build
at dapat mong makita ang isang bagay tulad ng:
>> Building pybindgen-0.16.0.886 - OK
>> Building netanim-3.105 - OK
>> Gusali ns-3.22 - OK
Pahiwatig: ikaw maaari Rin gumanap kapwa mga hakbang, download at magtayo by pagtatawag 'bake.py i-deploy'.
Kung may nangyaring pagkabigo, mangyaring tingnan kung ano ang sinasabi ng sumusunod na utos
ikaw; maaari itong magbigay ng pahiwatig tungkol sa isang nawawalang dependency:
$ ./bake.py palabas
Ililista nito ang iba't ibang mga dependency ng mga pakete na sinusubukan mong buuin.
gusali sa Waf
Hanggang sa puntong ito, ginamit namin ang alinman sa build.py script, o ang lutuin sa hurno kasangkapan, upang makuha
nagsimula sa pagtatayo ns-3. Ang mga tool na ito ay kapaki-pakinabang para sa pagbuo ns-3 at pagsuporta
mga aklatan, at tumatawag sila sa ns-3 direktoryo upang tawagan ang Waf build tool upang gawin ang
aktwal na gusali. Karamihan sa mga user ay mabilis na lumipat sa paggamit ng Waf nang direkta upang i-configure at
magtayo ns-3. Kaya, upang magpatuloy, mangyaring baguhin ang iyong gumaganang direktoryo sa ns-3 direktoryo
na una mong binuo.
Hindi ito mahigpit na kinakailangan sa puntong ito, ngunit magiging mahalaga ang bahagyang paglihis
at tingnan kung paano gumawa ng mga pagbabago sa pagsasaayos ng proyekto. Marahil ang pinaka
Ang kapaki-pakinabang na pagbabago sa pagsasaayos na maaari mong gawin ay ang pagbuo ng na-optimize na bersyon ng
code. Bilang default, na-configure mo ang iyong proyekto upang buuin ang bersyon ng debug. Sabihin natin
ang proyekto upang makagawa ng isang na-optimize na build. Upang ipaliwanag kay Waf na dapat itong gawin na-optimize
mga build na kinabibilangan ng mga halimbawa at pagsubok, kakailanganin mong isagawa ang sumusunod
utos:
$ ./waf malinis
$ ./waf --build-profile=optimized --enable-examples --enable-tests configure
Pinapalabas nito ang Waf sa lokal na direktoryo (na ibinibigay bilang kaginhawahan para sa iyo).
Ang unang utos upang linisin ang nakaraang build ay hindi karaniwang mahigpit na kinakailangan ngunit
ay mabuting pagsasanay (ngunit tingnan Magtayo Profile, sa ibaba); aalisin nito ang dating binuo
mga aklatan at object file na matatagpuan sa direktoryo magtayo/. Kapag na-reconfigure ang proyekto
at ang build system ay sumusuri para sa iba't ibang mga dependency, dapat mong makita ang hitsura ng output
katulad ng sumusunod:
Ang pagtatakda sa itaas sa : .
Nagtatakda sa : build
Sinusuri ang 'gcc' (c compiler): /usr/bin/gcc
Sinusuri ang bersyon ng cc : 4.2.1
Sinusuri ang 'g++' (c++ compiler): /usr/bin/g++
Kasama sa checking boost ang : 1_46_1
Sinusuri ang boost libs : ok
Sinusuri ang boost linkage : ok
Sinusuri ang lokasyon ng pag-click : hindi nahanap
Sinusuri ang program pkg-config : /sw/bin/pkg-config
Sinusuri ang 'gtk+-2.0' >= 2.12 : oo
Sinusuri ang 'libxml-2.0' >= 2.7 : oo
Sinusuri ang uri uint128_t : hindi nahanap
Sinusuri ang uri __uint128_t : oo
Sinusuri ang pagpapatupad ng mataas na katumpakan : 128-bit integer (default)
Sinusuri ang header stdint.h : oo
Sinusuri ang header inttypes.h : oo
Sinusuri ang header sys/inttypes.h : hindi nahanap
Sinusuri ang header sys/types.h : oo
Sinusuri ang header sys/stat.h : oo
Sinusuri ang header dirent.h : oo
Sinusuri para sa header stdlib.h : oo
Sinusuri ang signal ng header.h : oo
Sinusuri ang header na pthread.h : oo
Sinusuri ang header stdint.h : oo
Sinusuri ang header inttypes.h : oo
Sinusuri ang header sys/inttypes.h : hindi nahanap
Sinusuri para sa library rt : hindi nahanap
Sinusuri ang header netpacket/packet.h : hindi nahanap
Sinusuri ang header sys/ioctl.h : oo
Sinusuri ang header net/if.h : hindi nahanap
Sinusuri ang header net/ethernet.h : oo
Sinusuri ang header linux/if_tun.h : hindi nahanap
Sinusuri ang header netpacket/packet.h : hindi nahanap
Sinusuri ang lokasyon ng NSC : hindi nahanap
Sinusuri ang 'mpic++' : oo
Sinusuri ang 'sqlite3' : oo
Sinusuri ang header linux/if_tun.h : hindi nahanap
Sinusuri ang sudo ng programa : /usr/bin/sudo
Sinusuri ang program valgrind : /sw/bin/valgrind
Sinusuri ang 'gsl' : oo
Sinusuri ang flag ng compilation -Wno-error=deprecated-d... support : ok
Sinusuri ang flag ng compilation -Wno-error=deprecated-d... support : ok
Sinusuri ang compilation flag -fstrict-aliasing... support : ok
Sinusuri ang compilation flag -fstrict-aliasing... support : ok
Sinusuri ang flag ng compilation -Wstrict-aliasing... support : ok
Sinusuri ang flag ng compilation -Wstrict-aliasing... support : ok
Sinusuri ang program doxygen : /usr/local/bin/doxygen
---- Buod ng opsyonal na mga tampok ng NS-3:
Bumuo ng profile : debug
Bumuo ng direktoryo: build
Python Bindings : pinagana
Pagsasama ng BRITE : hindi pinagana (hindi pinagana ang BRITE (tingnan ang opsyon --with-brite))
NS-3 Click Integration : hindi pinagana (hindi pinagana ang nsclick (tingnan ang opsyon --with-nsclick))
GtkConfigStore : pinagana
XmlIo : pinagana
Threading Primitives : pinagana
Real Time Simulator : pinagana (hindi available ang librt)
Emulated Net Device : pinagana ( isama ang hindi nakita)
File descriptor NetDevice : pinagana
I-tap ang FdNetDevice : hindi pinagana (kailangan ng linux/if_tun.h)
Emulation FdNetDevice : hindi pinagana (kailangan ng netpacket/packet.h)
PlanetLab FdNetDevice : hindi pinagana (Hindi nakita ang operating system ng PlanetLab (tingnan ang opsyon --force-planetlab))
Network Simulation Cradle : hindi pinagana (hindi nahanap ang NSC (tingnan ang opsyon --with-nsc))
MPI Support : pinagana
NS-3 OpenFlow Integration : hindi pinagana (Hindi nahanap ang mga kinakailangang boost library, nawawala: system, signal, filesystem)
SQlite stats data output : pinagana
I-tap ang Bridge : hindi pinagana ( isama ang hindi nakita)
PyViz visualizer : pinagana
Gamitin ang sudo upang itakda ang suid bit : hindi pinagana (opsyon --enable-sudo hindi napili)
Bumuo ng mga pagsubok : pinagana
Bumuo ng mga halimbawa : pinagana
GNU Scientific Library (GSL) : pinagana
matagumpay na natapos ang 'configure' (1.944s)
Tandaan ang huling bahagi ng output sa itaas. Ang ilan ns-3 ang mga opsyon ay hindi pinagana bilang default o
nangangailangan ng suporta mula sa pinagbabatayan na sistema upang gumana nang maayos. Halimbawa, upang paganahin
XmlTo, ang library libxml-2.0 ay dapat matagpuan sa system. Kung hindi ang library na ito
natagpuan, ang kaukulang ns-3 hindi paganahin ang tampok at magiging isang mensahe
ipinapakita. Tandaan pa na mayroong isang tampok upang magamit ang programa sudo upang itakda ang suid
bit ng ilang mga programa. Hindi ito pinagana bilang default at kaya naiulat ang feature na ito
bilang "hindi pinagana."
Ngayon sige at bumalik sa debug build na kinabibilangan ng mga halimbawa at pagsubok.
$ ./waf malinis
$ ./waf --build-profile=debug --enable-examples --enable-tests configure
Naka-configure na ngayon ang build system at maaari mong buuin ang mga bersyon ng debug ng ns-3
mga programa sa pamamagitan lamang ng pag-type
$ ./waf
Okay, sorry, ginawa kitang buuin ns-3 bahagi ng system nang dalawang beses, ngunit ngayon alam mo na kung paano
baguhin ang configuration at bumuo ng na-optimize na code.
Sinusuportahan din ng build.py script na tinalakay sa itaas ang --enable-halimbawa at enable-tests
mga argumento, ngunit sa pangkalahatan, ay hindi direktang sumusuporta sa iba pang mga opsyon sa waf; halimbawa, ito
ayaw gumana:
$ ./build.py --disable-python
ay magreresulta sa
build.py: error: walang ganoong opsyon: --disable-python
Gayunpaman, ang espesyal na operator -- ay maaaring gamitin upang ipasa ang mga karagdagang opsyon sa waf, kaya
sa halip na nasa itaas, gagana ang sumusunod:
$ ./build.py --- --disable-python
dahil bumubuo ito ng pinagbabatayan na utos ./waff i-configure ang --disable-python.
Narito ang ilan pang panimulang tip tungkol kay Waf.
I-configure ang kumpara sa Magtayo
Ang ilang mga utos ng Waf ay makabuluhan lamang sa yugto ng pag-configure at ang ilang mga utos ay
wasto sa yugto ng pagbuo. Halimbawa, kung gusto mong gamitin ang mga feature ng emulation ng
ns-3, baka gusto mong paganahin ang pagtatakda ng suid bit gamit ang sudo gaya ng inilarawan sa itaas. Ito
lumalabas na isang configuration-time na command, at para ma-reconfigure mo gamit ang
sumusunod na utos na kasama rin ang mga halimbawa at pagsubok.
$ ./waf configure --enable-sudo --enable-examples --enable-tests
Kung gagawin mo ito, tatakbo si Waf ng sudo upang baguhin ang mga programa ng tagalikha ng socket ng
emulation code na tatakbo bilang root.
Mayroong maraming iba pang mga pagpipilian sa pag-configure at build-time na magagamit sa Waf. Upang tuklasin ang mga ito
mga pagpipilian, uri:
$ ./waf --help
Gagamitin namin ang ilan sa mga utos na nauugnay sa pagsubok sa susunod na seksyon.
Magtayo Profile
Nakita na namin kung paano mo mako-configure ang Waf para sa mag-alis ng mga insekto or optimized nagtatayo:
$ ./waf --build-profile=debug
Mayroon ding intermediate build profile, pakawalan. -d ay isang kasingkahulugan para sa
--build-profile.
Bilang default, inilalagay ni Waf ang mga build artifact sa magtayo direktoryo. Maaari mong tukuyin ang a
iba't ibang direktoryo ng output kasama ang --labas opsyon, hal
$ ./waf configure --out=foo
Ang pagsasama nito sa mga build profile ay nagbibigay-daan sa iyong lumipat sa pagitan ng iba't ibang opsyon sa pag-compile
sa malinis na paraan:
$ ./waf configure --build-profile=debug --out=build/debug
$ ./waf build
...
$ ./waf configure --build-profile=optimized --out=build/optimized
$ ./waf build
...
Nagbibigay-daan ito sa iyo na magtrabaho sa maraming build sa halip na palaging i-overwrite ang huli
magtayo. Kapag lumipat ka, iko-compile lang ni Waf kung ano ang kailangan nito, sa halip na i-recompile
lahat ng bagay.
Kapag lumipat ka ng mga profile ng build na tulad nito, kailangan mong maging maingat upang magbigay ng pareho
mga parameter ng pagsasaayos sa bawat oras. Maaaring maginhawa upang tukuyin ang ilang kapaligiran
mga variable upang matulungan kang maiwasan ang mga pagkakamali:
$ export NS3CONFIG="--enable-examples --enable-tests"
$ export NS3DEBUG="--build-profile=debug --out=build/debug"
$ export NS3OPT=="--build-profile=optimized --out=build/optimized"
$ ./waf i-configure ang $NS3CONFIG $NS3DEBUG
$ ./waf build
...
$ ./waf i-configure ang $NS3CONFIG $NS3OPT
$ ./waf build
Mga Compiler
Sa mga halimbawa sa itaas, ginagamit ni Waf ang GCC C++ compiler, g ++, para sa gusali ns-3. Gayunpaman,
posibleng baguhin ang C++ compiler na ginamit ni Waf sa pamamagitan ng pagtukoy sa CXX kapaligiran
variable. Halimbawa, para magamit ang Clang C++ compiler, clang++,
$ CXX="clang++" ./waf configure
$ ./waf build
Maaari ding i-set up ng isa si Waf para gawin ang distributed compilation distcc sa parehong paraan:
$ CXX="distcc g++" ./waf configure
$ ./waf build
Higit pang impormasyon sa distcc at ang ipinamahagi na compilation ay matatagpuan dito proyekto pahina sa ilalim
Seksyon ng dokumentasyon.
I-install
Maaaring gamitin ang Waf para mag-install ng mga library sa iba't ibang lugar sa system. Ang default
lokasyon kung saan itinatayo ang mga aklatan at mga executable ay nasa magtayo direktoryo, at dahil
Alam ni Waf ang lokasyon ng mga aklatan at mga executable na ito, hindi na kailangang i-install
ang mga aklatan sa ibang lugar.
Kung pinili ng mga user na mag-install ng mga bagay sa labas ng build directory, maaaring mag-isyu ang mga user ng
./waff install utos. Bilang default, ang prefix para sa pag-install ay / usr / lokal, Kaya ./waff
install ay mag-i-install ng mga programa sa / usr / local / bin, mga aklatan sa / usr / local / lib, at
mga header sa /usr/local/include. Ang mga pribilehiyo ng superuser ay karaniwang kailangan upang mai-install
ang default na prefix, kaya ang karaniwang utos ay sudo ./waff install. Kapag tumatakbo
mga program na may Waf, mas gugustuhin muna ni Waf na gumamit ng mga shared library sa build directory,
pagkatapos ay maghahanap ng mga aklatan sa path ng library na na-configure sa lokal na kapaligiran. Kaya
kapag nag-i-install ng mga aklatan sa system, magandang kasanayan na suriin kung ang nilalayon
ang mga aklatan ay ginagamit.
Maaaring piliin ng mga user na mag-install sa ibang prefix sa pamamagitan ng pagpasa sa --prefix pagpipilian sa
i-configure ang oras, tulad ng:
./waf configure --prefix=/opt/local
Kung sa ibang pagkakataon pagkatapos ng build ay nag-isyu ang user ng ./waff install utos, ang unlapi /opt/local
gagamitin.
Ang ./waff linisin utos ay dapat gamitin bago muling i-configure ang proyekto kung gagawin ni Waf
ginagamit upang mag-install ng mga bagay sa ibang prefix.
Sa buod, hindi kinakailangang tumawag ./waff install upang gamitin ang ns-3. Karamihan sa mga gumagamit ay hindi
kailangan ang utos na ito dahil kukunin ni Waf ang kasalukuyang mga aklatan mula sa magtayo direktoryo,
ngunit maaaring makita ng ilang mga gumagamit na ito ay kapaki-pakinabang kung ang kanilang kaso ng paggamit ay nagsasangkot ng pagtatrabaho sa mga programa sa labas
ng ns-3 direktoryo.
Isa Waf
Mayroon lamang isang Waf script, sa pinakamataas na antas ng ns-3 pinagmumulan ng puno. Habang nagtatrabaho ka, ikaw
maaaring makita ang iyong sarili na gumugugol ng maraming oras scratch/, o malalim src/..., at kailangang
tawag ni Waf. Maaari mo lamang tandaan kung nasaan ka, at tawagan si Waf tulad nito:
$ ../../../waf ...
ngunit iyon ay nakakapagod, at madaling kapitan ng pagkakamali, at may mas mahusay na mga solusyon.
Kung mayroon kang buo ns-3 repository ang maliit na hiyas na ito ay isang simula:
$ cd $(hg ugat) && ./waf ...
Kahit na mas mabuti ay tukuyin ito bilang isang function ng shell:
$ function waff { cd $(hg root) && ./waf $* ; }
$ waff build
Kung mayroon ka lang tarball, makakatulong ang isang environment variable:
$ export NS3DIR="$PWD"
$ function waff { cd $NS3DIR && ./waf $* ; }
$ cd scratch
$ waff build
Maaaring nakatutukso sa isang direktoryo ng module na magdagdag ng walang kabuluhan waf script kasama ang mga linya ng
exec ../../waf. Mangyaring huwag. Ito ay nakalilito sa mga bagong dating, at kapag ginawa ito nang hindi maganda
humahantong sa banayad na mga error sa pagbuo. Ang mga solusyon sa itaas ay ang paraan upang pumunta.
Pagsubok ns-3
Maaari mong patakbuhin ang mga unit test ng ns-3 pamamahagi sa pamamagitan ng pagpapatakbo ng ./test.py -c ubod
script:
$ ./test.py -c core
Ang mga pagsubok na ito ay pinapatakbo nang magkatulad ni Waf. Dapat mong makita sa huli ang isang ulat na nagsasabi na
92 sa 92 na pagsubok ang pumasa (92 ang pumasa, 0 ang nabigo, 0 ang nag-crash, 0 ang valgrind error)
Ito ang mahalagang mensahe.
Makikita mo rin ang buod na output mula kay Waf at ang test runner na nagsasagawa ng bawat pagsubok,
na talagang magiging ganito ang hitsura:
Waf: Pagpasok ng direktoryo `/path/to/workspace/ns-3-allinone/ns-3-dev/build'
Waf: Umalis sa direktoryo `/path/to/workspace/ns-3-allinone/ns-3-dev/build'
Matagumpay na natapos ang 'build' (1.799s)
Mga module na binuo:
tulay ng aodv application
i-click ang config-store core
csma csma-layout dsdv
emu enerhiya daloy-monitor
internet lte mesh
mobility mpi netanim
network nix-vector-routing ns3tcp
ns3wifi olsr openflow
point-to-point point-to-point-layout propagation
spectrum stats tap-bridge
mga tool sa pagsubok ng template
topology-read uan virtual-net-device
visualizer wifi wimax
PASS: TestSuite ns3-wifi-interference
PASS: TestSuite histogram
...
PASS: TestSuite object
PASS: TestSuite random-number-generators
92 sa 92 na pagsubok ang pumasa (92 ang pumasa, 0 ang nabigo, 0 ang nag-crash, 0 ang valgrind error)
Ang command na ito ay karaniwang pinapatakbo ng mga user upang mabilis na ma-verify na ang isang ns-3 may pamamahagi
binuo ng tama. (Tandaan ang pagkakasunud-sunod ng NAKARAAN: ... maaaring mag-iba ang mga linya, na okay lang. Ano ang
mahalaga na ang linya ng buod sa dulo ay nag-uulat na ang lahat ng mga pagsubok ay naipasa; walang nabigo o
Nag-crash.)
Tumatakbo a Iskrip
Karaniwan kaming nagpapatakbo ng mga script sa ilalim ng kontrol ng Waf. Ito ay nagbibigay-daan sa build system upang matiyak
na ang mga shared library path ay naitakda nang tama at ang mga library ay available sa
oras ng pagtakbo. Upang magpatakbo ng isang programa, gamitin lamang ang --takbo opsyon sa Waf. Patakbuhin natin ang ns-3
katumbas ng ubiquitous hello world program sa pamamagitan ng pag-type ng sumusunod:
$ ./waf --run hello-simulator
Sinusuri muna ni Waf upang matiyak na ang program ay binuo nang tama at nagpapatupad ng isang build kung
kailangan. Pagkatapos ay ipapatupad ni Waf ang programa, na gumagawa ng sumusunod na output.
Hello Simulator
Binabati kita! Isa ka na ngayong ns-3 user!
Ano do I do if I huwag makita ang output?
Kung makakita ka ng mga mensahe ng Waf na nagsasaad na matagumpay na nakumpleto ang pagbuo, ngunit hindi
tingnan ang "Hello Simulator" na output, malamang na inilipat mo ang iyong build mode sa
optimized nasa gusali sa Waf seksyon, ngunit napalampas ang pagbabago pabalik sa mag-alis ng mga insekto mode.
Ang lahat ng console output na ginamit sa tutorial na ito ay gumagamit ng isang espesyal ns-3 logging component na
ay kapaki-pakinabang para sa pag-print ng mga mensahe ng user sa console. Ang output mula sa bahaging ito ay
awtomatikong hindi pinagana kapag nag-compile ka ng na-optimize na code -- ito ay "na-optimize." kung ikaw
hindi nakikita ang "Hello Simulator" na output, i-type ang sumusunod:
$ ./waf configure --build-profile=debug --enable-examples --enable-tests
para sabihin kay Waf na buuin ang mga bersyon ng debug ng ns-3 mga programa na kinabibilangan ng mga halimbawa
at mga pagsubok. Dapat mo pa ring buuin ang aktwal na bersyon ng pag-debug ng code sa pamamagitan ng pag-type
$ ./waf
Ngayon, kung patakbuhin mo ang hello-simulator program, dapat mong makita ang inaasahang output.
Programa Mga argumento
Upang magpakain ng mga argumento ng command line sa isang ns-3 gamitin ng programa ang pattern na ito:
$ ./waf --run --command-template="%s "
Palitan ang pangalan ng iyong programa para sa , at ang mga argumento para sa . ang
--command-template Ang argumento kay Waf ay karaniwang isang recipe para sa pagbuo ng aktwal
command line na dapat gamitin ni Waf para isagawa ang program. Sinusuri ni Waf kung ang build ay
kumpleto, itinatakda ang mga path ng shared library, pagkatapos ay i-invoke ang executable gamit ang ibinigay
template ng command line, na inilalagay ang pangalan ng program para sa %s placeholder. (Aminin ko ito
medyo awkward, pero ganun talaga. Maligayang pagdating ang mga patch!)
Ang isa pang partikular na kapaki-pakinabang na halimbawa ay ang magpatakbo ng isang test suite nang mag-isa. Ipagpalagay natin na a
mytest umiiral ang test suite (wala ito). Sa itaas, ginamit namin ang ./test.py script upang magpatakbo ng isang buo
maraming pagsubok na magkatulad, sa pamamagitan ng paulit-ulit na paggamit ng tunay na programa sa pagsubok, test-runner.
Upang mag-invoke test-runner direkta para sa isang pagsubok:
$ ./waf --run test-runner --command-template="%s --suite=mytest --verbose"
Ipinapasa nito ang mga argumento sa test-runner programa. Since mytest ay wala, isang
bubuo ng mensahe ng error. Upang i-print ang magagamit test-runner na pagpipilian:
$ ./waf --run test-runner --command-template="%s --help"
Pag-debug
Tumakbo ns-3 mga programa sa ilalim ng kontrol ng isa pang utility, tulad ng isang debugger (hal gdb)
o tagasuri ng memorya (hal valgrind), gumamit ka ng katulad --command-template="..." form.
Halimbawa, upang patakbuhin ang iyong ns-3 programa hello-simulator kasama ang mga argumento sa ilalim ng
gdb debugger:
$ ./waf --run=hello-simulator --command-template="gdb %s --args "
Pansinin na ang ns-3 Ang pangalan ng programa ay kasama sa --takbo argumento, at ang control utility
(dito gdb) ay ang unang token sa --commmand-template argumento. Ang --args nagsasabi gdb
na ang natitira sa command line ay kabilang sa "inferior" na programa. (Ilan gdb's
hindi maintindihan ang --args tampok. Sa kasong ito, alisin ang mga argumento ng programa mula sa
--command-template, at gamitin ang gdb utos itakda mga pagtatalo.)
Maaari naming pagsamahin ang recipe na ito at ang nauna para magpatakbo ng pagsubok sa ilalim ng debugger:
$ ./waf --run test-runner --command-template="gdb %s --args --suite=mytest --verbose"
Nagtatrabaho Directory
Kailangang tumakbo ni Waf mula sa lokasyon nito sa tuktok ng ns-3 puno. Ito ang nagiging trabaho
direktoryo kung saan isusulat ang mga output file. Ngunit paano kung gusto mong panatilihin ang mga iyon
ang ns-3 pinagmumulan ng puno? Gamitin ang --cwd argumento:
$ ./waf --cwd=...
Maaaring mas maginhawang magsimula sa iyong gumaganang direktoryo kung saan mo nais ang output
mga file, kung saan ang isang maliit na hindi direksyon ay maaaring makatulong:
$ function waff {
CWD="$PWD"
cd $NS3DIR >/dev/null
./waf --cwd="$CWD" $*
cd - >/dev/null
}
Ang embellishment na ito ng nakaraang bersyon ay nagse-save sa kasalukuyang gumaganang direktoryo, cdkay
ang Waf na direktoryo, pagkatapos ay inutusan si Waf na baguhin ang gumaganang direktoryo likod sa mga naligtas
kasalukuyang gumaganang direktoryo bago patakbuhin ang programa.
KONSEPTUWAL PANGKALAHATANG-IDEYA
Ang unang bagay na kailangan nating gawin bago aktwal na magsimulang tumingin o magsulat ns-3 ang code ay sa
ipaliwanag ang ilang pangunahing konsepto at abstraction sa system. Karamihan sa mga ito ay maaaring lumitaw
malinaw na halata sa ilan, ngunit inirerekomenda namin ang paglalaan ng oras upang basahin ito
seksyon para lamang matiyak na nagsisimula ka sa isang matatag na pundasyon.
Key Mga Abstraction
Sa seksyong ito, susuriin namin ang ilang termino na karaniwang ginagamit sa networking, ngunit may a
tiyak na kahulugan sa ns-3.
Node
Sa Internet jargon, isang computing device na kumokonekta sa isang network ay tinatawag na a marami or
minsan an dulo sistema. dahil sa ns-3 ay isang network simulator, hindi partikular na isang
internet simulator, sinasadya naming hindi gamitin ang terminong host dahil malapit ito
nauugnay sa Internet at sa mga protocol nito. Sa halip, gumagamit din kami ng mas generic na termino
ginagamit ng ibang mga simulator na nagmula sa Graph Theory --- ang buko.
In ns-3 ang basic computing device abstraction ay tinatawag na node. Ang abstraction na ito ay
kinakatawan sa C++ ng klase Node. ang Node Ang klase ay nagbibigay ng mga pamamaraan para sa pamamahala ng
representasyon ng mga computing device sa mga simulation.
Dapat mong isipin ang isang Node bilang isang computer kung saan magdaragdag ka ng functionality. Dagdag ng isa
mga bagay tulad ng mga application, protocol stack at peripheral card na may kaugnayan sa mga ito
mga driver upang paganahin ang computer na gumawa ng kapaki-pakinabang na gawain. Ginagamit namin ang parehong pangunahing modelo sa ns-3.
application
Karaniwan, nahahati ang software ng computer sa dalawang malawak na klase. Sistema software nag-aayos
iba't ibang mapagkukunan ng computer tulad ng memorya, mga siklo ng processor, disk, network, atbp.,
ayon sa ilang modelo ng computing. Karaniwang hindi ginagamit ng system software ang mga mapagkukunang iyon
upang kumpletuhin ang mga gawain na direktang makikinabang sa isang user. Ang isang user ay karaniwang nagpapatakbo ng isang application
na nakakakuha at gumagamit ng mga mapagkukunang kontrolado ng software ng system upang magawa ang ilan
layunin.
Kadalasan, ang linya ng paghihiwalay sa pagitan ng system at application software ay ginagawa sa
pagbabago sa antas ng pribilehiyo na nangyayari sa mga bitag ng operating system. Sa ns-3 walang tunay
konsepto ng operating system at lalo na walang konsepto ng mga antas ng pribilehiyo o mga tawag sa system.
Gayunpaman, mayroon kaming ideya ng isang aplikasyon. Tulad ng pagtakbo ng mga software application
mga computer upang magsagawa ng mga gawain sa "tunay na mundo," ns-3 tumatakbo ang mga application ns-3 Node sa
humimok ng mga simulation sa simulate na mundo.
In ns-3 ang pangunahing abstraction para sa isang user program na bumubuo ng ilang aktibidad upang maging
kunwa ay ang application. Ang abstraction na ito ay kinakatawan sa C++ ng klase
application. ang application Ang klase ay nagbibigay ng mga pamamaraan para sa pamamahala ng mga representasyon ng
ang aming bersyon ng mga application sa antas ng user sa mga simulation. Ang mga developer ay inaasahan na
dalubhasa ang application klase sa object-oriented programming kahulugan upang lumikha ng bago
mga aplikasyon. Sa tutorial na ito, gagamitin namin ang mga espesyalisasyon ng klase application tinatawag
UdpEchoClientApplication at UdpEchoServerApplication. Gaya ng inaasahan mo, ang mga ito
ang mga application ay bumubuo ng isang client/server application set na ginamit upang bumuo at echo simulated
mga packet ng network
channel
Sa totoong mundo, maaaring kumonekta ng isang computer sa isang network. Kadalasan ang media kung saan
Ang mga daloy ng data sa mga network na ito ay tinatawag channel. Kapag ikinonekta mo ang iyong Ethernet cable sa
ang plug sa dingding, ikinokonekta mo ang iyong computer sa isang komunikasyong Ethernet
channel. Sa kunwa mundo ng ns-3, nag-uugnay ang isa a Node sa isang bagay na kumakatawan sa a
channel ng komunikasyon. Dito ang pangunahing abstraction ng subnetwork ng komunikasyon ay tinatawag na
channel at kinakatawan sa C++ ng klase channel.
Ang channel Ang klase ay nagbibigay ng mga pamamaraan para sa pamamahala ng mga bagay sa subnetwork ng komunikasyon at
pagkonekta ng mga node sa kanila. Channel maaari ding maging dalubhasa ng mga developer sa object
oriented programming kahulugan. A channel ang pagdadalubhasa ay maaaring magmodelo ng isang bagay na kasing simple ng a
alambre. Ang dalubhasa channel maaari ding magmodelo ng mga bagay na kasing kumplikado ng isang malaking Ethernet
switch, o three-dimensional na espasyo na puno ng mga sagabal sa kaso ng mga wireless network.
Gagamit kami ng mga espesyal na bersyon ng channel tinatawag CsmaChannel, PointToPointChannel
at WifiChannel sa tutorial na ito. Ang CsmaChannel, halimbawa, nagmomodelo ng bersyon ng a
subnetwork ng komunikasyon na nagpapatupad ng a tagapagdala kahulugan maramihang daan Komunikasyon
daluyan. Nagbibigay ito sa amin ng Ethernet-like functionality.
lambat Device
Dati ang kaso na kung gusto mong ikonekta ang isang computer sa isang network, kailangan mo
bumili ng partikular na uri ng network cable at isang hardware device na tinatawag (sa terminolohiya ng PC) a
paligid kard na kailangang i-install sa iyong computer. Kung ang peripheral card
ipinatupad ang ilang function ng networking, tinawag silang Network Interface Cards, o Mga NIC.
Sa ngayon, karamihan sa mga computer ay may naka-built in na network interface hardware at hindi nakikita ng mga user
ang mga bloke ng gusali na ito.
Ang isang NIC ay hindi gagana nang walang software driver upang kontrolin ang hardware. Sa Unix (o
Linux), isang piraso ng peripheral hardware ay inuri bilang a aparato. Ang mga device ay kinokontrol
paggamit aparato driver, at mga network device (NIC) ay kinokontrol gamit network aparato
driver sama-sama na kilala bilang neto mga aparatong. Sa Unix at Linux ay tinutukoy mo ang mga net na ito
mga device sa pamamagitan ng mga pangalan tulad ng eth0.
In ns-3 ang neto aparato sinasaklaw ng abstraction ang parehong driver ng software at ang kunwa
hardware. Ang isang net device ay "naka-install" sa a Node upang paganahin ang Node sa
makipag-usap sa iba Node sa simulation sa pamamagitan ng Channel. Tulad ng sa isang tunay na computer,
a Node maaaring konektado sa higit sa isa channel sa pamamagitan ng maramihang Mga NetDevice.
Ang abstraction ng net device ay kinakatawan sa C++ ng klase NetDevice. ang NetDevice
class ay nagbibigay ng mga pamamaraan para sa pamamahala ng mga koneksyon sa Node at channel mga bagay; At siguro
dalubhasa ng mga developer sa object-oriented programming sense. Gagamitin natin ang
ilang espesyal na bersyon ng NetDevice tinatawag CsmaNetDevice, PointToPointNetDevice,
at WifiNetDevice sa tutorial na ito. Tulad ng isang Ethernet NIC ay idinisenyo upang gumana sa isang
Ethernet network, ang CsmaNetDevice ay dinisenyo upang gumana sa isang CsmaChannel; ang
PointToPointNetDevice ay dinisenyo upang gumana sa isang PointToPointChannel at WifiNetNevice
ay dinisenyo upang gumana sa isang WifiChannel.
topology Mga tumutulong
Sa isang tunay na network, makakahanap ka ng mga host computer na may idinagdag (o built-in) na mga NIC. Sa ns-3 we
sasabihin na mahahanap mo Node may kalakip Mga NetDevice. Sa isang malaking kunwa network
kakailanganin mong ayusin ang maraming koneksyon sa pagitan Node, Mga NetDevice at Channel.
Mula nang kumonekta Mga NetDevice sa Node, Mga NetDevice sa Channel, pagtatalaga ng mga IP address,
atbp., ay mga karaniwang gawain sa ns-3, nagbibigay kami ng tinatawag namin topology mga katulong upang gawin ito
kasingdali hangga't maaari. Halimbawa, maaaring tumagal ng maraming naiiba ns-3 mga pangunahing operasyon sa
lumikha ng NetDevice, magdagdag ng MAC address, i-install ang net device na iyon sa isang Node, i-configure ang
protocol stack ng node, at pagkatapos ay ikonekta ang NetDevice sa isang channel. Mas marami pang operasyon
kakailanganing magkonekta ng maraming device sa mga multipoint na channel at pagkatapos ay kumonekta
mga indibidwal na network na magkasama sa internetworks. Nagbibigay kami ng mga bagay na tumutulong sa topology
pagsamahin ang maraming natatanging mga operasyon sa isang madaling gamitin na modelo para sa iyong kaginhawahan.
A una ns-3 Iskrip
Kung na-download mo ang system tulad ng iminungkahi sa itaas, magkakaroon ka ng release ng ns-3 sa isang
tinawag na direktoryo Repos sa ilalim ng iyong home directory. Magpalit sa direktoryo ng paglabas na iyon, at
dapat kang makahanap ng istraktura ng direktoryo tulad ng sumusunod:
AUTHORS halimbawa scratch utils waf.bat*
bindings LICENSE src utils.py waf-tools
bumuo ng ns3 test.py* utils.pyc wscript
CHANGES.html README testpy-output VERSION wutils.py
doc RELEASE_NOTES testpy.supp waf* wutils.pyc
Magpalit sa mga halimbawa/tutorial direktoryo. Dapat mong makita ang isang file na pinangalanan una.cc na matatagpuan
doon. Ito ay isang script na lilikha ng isang simpleng point-to-point na link sa pagitan ng dalawang node
at echo ang isang solong packet sa pagitan ng mga node. Tingnan natin ang linya ng script ni
linya, kaya sige at buksan mo una.cc sa iyong paboritong editor.
Boilerplate
Ang unang linya sa file ay isang emacs mode line. Sinasabi nito sa mga emac ang tungkol sa pag-format
mga kumbensyon (estilo ng coding) na ginagamit namin sa aming source code.
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Ito ay palaging isang medyo kontrobersyal na paksa, kaya maaari rin nating alisin ito sa paraan
kaagad Ang ns-3 proyekto, tulad ng karamihan sa malalaking proyekto, ay nagpatibay ng istilo ng coding sa
na dapat sundin ng lahat ng naiambag na code. Kung gusto mong i-ambag ang iyong code sa
proyekto, sa kalaunan ay kailangan mong sumunod sa ns-3 coding standard gaya ng inilarawan sa
mga file doc/codingstd.txt o ipinapakita sa web page ng proyekto dito.
Inirerekomenda namin na masanay ka lang sa hitsura at pakiramdam ng ns-3 code at magpatibay
ang pamantayang ito sa tuwing nagtatrabaho ka sa aming code. Lahat ng development team at
ginawa ito ng mga kontribyutor na may iba't ibang dami ng pag-ungol. Ang linya ng emacs mode sa itaas
ginagawang mas madaling makuha ang pag-format nang tama kung gagamitin mo ang emacs editor.
Ang ns-3 Ang simulator ay lisensyado gamit ang GNU General Public License. Makikita mo ang
naaangkop na GNU legalese sa ulo ng bawat file sa ns-3 pamamahagi. Madalas ikaw
makakakita ng abiso sa copyright para sa isa sa mga institusyong kasangkot sa ns-3 proyekto sa itaas
ang teksto ng GPL at isang may-akda na nakalista sa ibaba.
/*
* Ang program na ito ay libreng software; maaari mo itong muling ipamahagi at/o baguhin
* ito sa ilalim ng mga tuntunin ng GNU General Public License bersyon 2 bilang
* inilathala ng Free Software Foundation;
*
* Ang programang ito ay ipinamahagi sa pag-asa na ito ay magiging kapaki-pakinabang,
* ngunit WALANG ANUMANG WARRANTY; nang walang kahit na ipinahiwatig na warranty ng
* MERCHANTABILITY o FITNESS PARA SA ISANG PARTIKULAR NA LAYUNIN. Tingnan ang
* GNU General Public License para sa higit pang mga detalye.
*
* Dapat ay nakatanggap ka ng kopya ng GNU General Public License
* kasama ng programang ito; kung hindi, sumulat sa Libreng Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
Module May kasamang
Ang tamang code ay nagsisimula sa isang bilang ng mga kasamang pahayag.
#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/internet-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/applications-module.h"
Upang matulungan ang aming mga high-level na user ng script na harapin ang malaking bilang ng mga kasamang file na naroroon
ang sistema, kasama namin ang pangkat ayon sa medyo malalaking module. Nagbibigay kami ng isang solong
isama ang file na muling maglo-load ng lahat ng kasamang file na ginagamit sa bawat module.
Sa halip na hanapin kung ano mismo ang header na kailangan mo, at posibleng kailangan mong makakuha ng a
tama ang bilang ng mga dependency, binibigyan ka namin ng kakayahang mag-load ng isang pangkat ng mga file nang malaki
granularity. Hindi ito ang pinakamabisang paraan ngunit tiyak na gumagawa ito ng pagsulat
mas madali ang mga script.
Bawat isa sa mga ns-3 isama ang mga file ay inilagay sa isang direktoryo na tinatawag na ns3 (sa ilalim ng build
directory) sa panahon ng proseso ng pagbuo upang makatulong na maiwasan ang pagsasama ng mga banggaan ng pangalan ng file. Ang
ns3/core-module.h file ay tumutugma sa ns-3 module na makikita mo sa direktoryo
src/core sa iyong na-download na pamamahagi ng release. Kung ililista mo ang direktoryong ito ay gagawin mo
maghanap ng malaking bilang ng mga file ng header. Kapag gumawa ka ng build, maglalagay si Waf ng pampublikong header
mga file sa isang ns3 direktoryo sa ilalim ng naaangkop build/debug or bumuo/na-optimize direktoryo
depende sa iyong configuration. Awtomatikong bubuo din ang Waf ng isang module kasama
file upang i-load ang lahat ng mga pampublikong file ng header.
Dahil ikaw ay, siyempre, sumusunod sa tutorial na ito sa relihiyon, magagawa mo na
a
$ ./waf -d debug --enable-examples --enable-tests configure
upang i-configure ang proyekto upang magsagawa ng mga debug build na may kasamang mga halimbawa at pagsubok.
Magagawa mo rin ang isang
$ ./waf
upang maitayo ang proyekto. Kaya ngayon kung titingnan mo sa direktoryo ../../build/debug/ns3 gagawin mo
hanapin ang apat na module na may kasamang mga file na ipinapakita sa itaas. Maaari mong tingnan ang mga nilalaman ng
ang mga file na ito at nalaman na kasama nila ang lahat ng pampublikong kasama ang mga file sa kanilang
kani-kanilang mga modyul.
Ns3 Namespace
Ang susunod na linya sa una.cc Ang script ay isang deklarasyon ng namespace.
gamit ang namespace ns3;
Ang ns-3 proyekto ay ipinatupad sa isang C++ namespace na tinatawag ns3. Itong grupo lahat
ns-3-mga kaugnay na deklarasyon sa isang saklaw sa labas ng pandaigdigang namespace, na inaasahan naming makakatulong
na may pagsasama sa ibang code. Ang C++ paggamit ipinakikilala ng pahayag ang ns-3 namespace
sa kasalukuyang (global) na rehiyong deklaratibo. Ito ay isang magarbong paraan ng pagsasabi na pagkatapos
ang deklarasyon na ito, hindi mo na kailangang mag-type ns3:: scope resolution operator bago ang lahat ng
ang ns-3 code para magamit ito. Kung hindi ka pamilyar sa mga namespace, mangyaring kumonsulta
halos anumang C++ na tutorial at ihambing ang ns3 namespace at paggamit dito na may mga pagkakataon ng
std namespace at ang paggamit namespace std; mga pahayag na madalas mong makikita sa mga talakayan
of cout at mga batis.
Pagtotroso
Ang susunod na linya ng script ay ang mga sumusunod,
NS_LOG_COMPONENT_DEFINE ("FirstScriptExample");
Gagamitin namin ang pahayag na ito bilang isang maginhawang lugar para pag-usapan ang aming dokumentasyon ng Doxygen
sistema. Kung titingnan mo ang web site ng proyekto, ns-3 proyekto, makakahanap ka ng link sa
"Dokumentasyon" sa navigation bar. Kung pipiliin mo ang link na ito, dadalhin ka sa aming
pahina ng dokumentasyon. May link sa "Latest Release" na magdadala sa iyo sa
dokumentasyon para sa pinakabagong stable na release ng ns-3. Kung pipiliin mo ang "API
Documentation" link, dadalhin ka sa ns-3 Pahina ng dokumentasyon ng API.
Sa kaliwang bahagi, makikita mo ang isang graphical na representasyon ng istraktura ng
dokumentasyon. Ang isang magandang lugar upang magsimula ay ang NS-3 Module "aklat" sa ns-3 nabigasyon
puno. Kung magpapalawak ka Module makikita mo ang isang listahan ng ns-3 dokumentasyon ng modyul. Ang
Ang konsepto ng module dito ay direktang nauugnay sa module kasama ang mga file na tinalakay sa itaas. Ang
ns-3 logging subsystem ay tinalakay sa C + + Mga konstruksyon Ginamit by lahat Module seksyon, kaya
sige at palawakin ang node ng dokumentasyong iyon. Ngayon, palawakin ang Pag-debug libro at pagkatapos
piliin ang Pagtotroso pahina.
Dapat ay tinitingnan mo na ngayon ang dokumentasyon ng Doxygen para sa module ng Pag-log. Nasa
Listahan ng # tukuyin's sa tuktok ng pahina makikita mo ang entry para sa
NS_LOG_COMPONENT_DEFINE. Bago tumalon, malamang na mainam na hanapin ang
"Detalyadong Paglalarawan" ng module ng pag-log upang madama ang pangkalahatang operasyon. Ikaw
maaaring mag-scroll pababa o piliin ang link na "Higit pa..." sa ilalim ng diagram ng pakikipagtulungan na gagawin
na ito.
Kapag mayroon kang pangkalahatang ideya kung ano ang nangyayari, magpatuloy at tingnan ang partikular
NS_LOG_COMPONENT_DEFINE dokumentasyon. Hindi ko duplicate ang dokumentasyon dito, ngunit sa
buod, ang linyang ito ay nagdedeklara ng isang bahagi ng pag-log na tinatawag FirstScriptExample na nagpapahintulot
mong paganahin at huwag paganahin ang console message logging sa pamamagitan ng pagtukoy sa pangalan.
Pangunahin tungkulin
Ang mga susunod na linya ng script na makikita mo ay,
int
pangunahing (int argc, char *argv[])
{
Ito ay deklarasyon lamang ng pangunahing pag-andar ng iyong programa (script). Tulad ng sa
anumang C++ program, kailangan mong tukuyin ang isang pangunahing function na magiging unang function run.
Wala talagang espesyal dito. Iyong ns-3 Ang script ay isang C++ program lamang.
Itinatakda ng susunod na linya ang resolution ng oras sa isang nanosecond, na mangyayari na ang default
halaga:
Oras::SetResolution (Oras::NS);
Ang resolution ay ang pinakamaliit na halaga ng oras na maaaring katawanin (pati na rin ang pinakamaliit
kinakatawan na pagkakaiba sa pagitan ng dalawang halaga ng oras). Maaari mong baguhin ang resolution nang eksakto
minsan. Ang mekanismo na nagpapagana sa kakayahang umangkop na ito ay medyo gutom sa memorya, kaya minsan ang
ang resolution ay tahasang itinakda namin ang memorya, na pumipigil sa mga karagdagang update.
(Kung hindi mo tahasang itinakda ang resolution, magiging default ito sa isang nanosecond, at ang
ang memorya ay ilalabas kapag nagsimula ang simulation.)
Ang susunod na dalawang linya ng script ay ginagamit upang paganahin ang dalawang bahagi ng pag-log na binuo
sa mga aplikasyon ng Echo Client at Echo Server:
LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO);
LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO);
Kung nabasa mo ang dokumentasyon ng bahagi ng Pag-log, makikita mo iyon doon
ay isang bilang ng mga antas ng pag-log verbosity/detalye na maaari mong paganahin sa bawat bahagi.
Ang dalawang linya ng code na ito ay nagbibigay-daan sa pag-log ng debug sa antas ng INFO para sa mga echo client at
mga server. Magreresulta ito sa pagpi-print ng application ng mga mensahe habang ipinapadala ang mga packet
at natanggap sa panahon ng simulation.
Ngayon ay direktang pupunta tayo sa negosyo ng paglikha ng topology at pagpapatakbo ng simulation.
Ginagamit namin ang topology helper object para gawing mas madali ang trabahong ito hangga't maaari.
topology Mga tumutulong
NodeContainer
Ang susunod na dalawang linya ng code sa aming script ay talagang lilikha ng ns-3 Node bagay na
kakatawan sa mga computer sa simulation.
NodeContainer node;
nodes.Lumikha (2);
Hanapin natin ang dokumentasyon para sa NodeContainer klase bago tayo magpatuloy. Ibang paraan
upang makapasok sa dokumentasyon para sa isang partikular na klase ay sa pamamagitan ng Klase tab sa Doxygen
mga pahina. Kung mayroon ka pa ring Doxygen na madaling gamitin, mag-scroll lang hanggang sa itaas ng page at
piliin ang Klase tab. Dapat mong makita ang isang bagong hanay ng mga tab na lilitaw, ang isa ay Klase
listahan. Sa ilalim ng tab na iyon makikita mo ang isang listahan ng lahat ng ns-3 mga klase. Mag-scroll pababa,
Naghahanap ng ns3::NodeContainer. Kapag nahanap mo na ang klase, magpatuloy at piliin ito na pupuntahan
ang dokumentasyon para sa klase.
Maaari mong maalala na ang isa sa aming mga pangunahing abstraction ay ang Node. Ito ay kumakatawan sa isang computer
kung saan kami ay magdaragdag ng mga bagay tulad ng mga protocol stack, application at peripheral
mga card. Ang NodeContainer Ang topology helper ay nagbibigay ng isang maginhawang paraan upang lumikha, pamahalaan at
i-access ang alinman Node mga bagay na nilikha namin upang magpatakbo ng isang simulation. Ang unang linya sa itaas
nagdedeklara lang ng NodeContainer na tinatawag namin nodes. Ang pangalawang linya ay tinatawag na Lumikha
pamamaraan sa nodes object at hinihiling sa lalagyan na lumikha ng dalawang node. Gaya ng inilarawan sa
ang Doxygen, ang lalagyan ay tumatawag pababa sa ns-3 wastong sistema upang lumikha ng dalawa Node
mga bagay at nag-iimbak ng mga pointer sa mga bagay na iyon sa loob.
Ang mga node habang nakatayo sila sa script ay walang ginagawa. Ang susunod na hakbang sa pagbuo ng a
Ang topology ay upang ikonekta ang aming mga node nang magkasama sa isang network. Ang pinakasimpleng anyo ng network namin
Ang suporta ay isang solong point-to-point na link sa pagitan ng dalawang node. Bubuo kami ng isa sa mga iyon
mga link dito.
PointToPointHelper
Gumagawa kami ng isang point to point link, at, sa isang pattern na magiging medyo
pamilyar sa iyo, gumagamit kami ng isang topology helper object upang gawin ang mababang antas ng trabaho na kinakailangan upang ilagay
magkasama ang link. Alalahanin na ang dalawa sa aming mga pangunahing abstraction ay ang NetDevice at ang
channel. Sa totoong mundo, ang mga terminong ito ay halos tumutugma sa mga peripheral card at
mga kable ng network. Kadalasan ang dalawang bagay na ito ay malapit na magkakaugnay at ang isa ay hindi maaaring
asahan na magpapalitan, halimbawa, mga Ethernet device at wireless na channel. Ang aming Topology
Sinusunod ng mga katulong ang intimate coupling na ito at samakatuwid ay gagamit ka ng single
PointToPointHelper upang i-configure at kumonekta ns-3 PointToPointNetDevice at
PointToPointChannel mga bagay sa script na ito.
Ang susunod na tatlong linya sa script ay,
PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
Ang unang linya,
PointToPointHelper pointToPoint;
instantiates a PointToPointHelper bagay sa stack. Mula sa isang mataas na antas na pananaw ang
susunod na linya,
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
nagsasabi sa PointToPointHelper object na gamitin ang halagang "5Mbps" (limang megabits bawat segundo) bilang
ang "DataRate" kapag lumikha ito ng a PointToPointNetDevice bagay.
Mula sa isang mas detalyadong pananaw, ang string na "DataRate" ay tumutugma sa tinatawag nating an
katangian ng PointToPointNetDevice. Kung titingnan mo ang Doxygen para sa klase
ns3::PointToPointNetDevice at hanapin ang dokumentasyon para sa GetTypeId paraan, gagawin mo
maghanap ng listahan ng katangian tinukoy para sa device. Kabilang sa mga ito ay ang "DataRate"
katangian. Karamihan sa nakikita ng gumagamit ns-3 ang mga bagay ay may mga katulad na listahan ng katangian. Ginagamit namin ito
mekanismo upang madaling i-configure ang mga simulation nang hindi nagre-recompile gaya ng makikita mo sa a
sumusunod na seksyon.
Katulad ng "DataRate" sa PointToPointNetDevice makakahanap ka ng isang "pagkaantala" katangian
nauugnay sa PointToPointChannel. Ang huling linya,
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
nagsasabi sa PointToPointHelper para gamitin ang value na "2ms" (dalawang millisecond) bilang value ng
pagkaantala ng paghahatid ng bawat punto sa puntong channel na kasunod nitong nililikha.
NetDeviceContainer
Sa puntong ito sa script, mayroon kaming isang NodeContainer na naglalaman ng dalawang node. Mayroon kaming isang
PointToPointHelper na primed at handa nang gawin PointToPointNetDevices at kawad
PointToPointChannel mga bagay sa pagitan nila. Tulad ng ginamit namin ang NodeContainer topology
katulong object upang lumikha ng Node para sa aming simulation, itatanong namin ang PointToPointHelper
upang gawin ang gawaing kasangkot sa paggawa, pag-configure at pag-install ng aming mga device para sa amin. Kami
ay kailangang magkaroon ng isang listahan ng lahat ng mga bagay sa NetDevice na nilikha, kaya gumagamit kami ng a
NetDeviceContainer upang hawakan ang mga ito tulad ng paggamit namin ng NodeContainer upang hawakan ang mga node namin
nilikha. Ang sumusunod na dalawang linya ng code,
Mga aparatong NetDeviceContainer;
mga device = pointToPoint.Install (nodes);
matatapos ang pag-configure ng mga device at channel. Idineklara ng unang linya ang device
lalagyan na nabanggit sa itaas at ang pangalawa ay gumagawa ng mabigat na pagbubuhat. Ang I-install paraan ng
ang PointToPointHelper tumatagal a NodeContainer bilang parameter. Sa loob, a
NetDeviceContainer ay nilikha. Para sa bawat node sa NodeContainer (Dapat may eksaktong
dalawa para sa isang point-to-point na link) a PointToPointNetDevice ay ginawa at nai-save sa device
lalagyan. A PointToPointChannel ay nilikha at ang dalawa PointToPointNetDevices ay
kalakip. Kapag ang mga bagay ay nilikha ng PointToPointHelper, ang katangian dati
itinakda sa katulong ay ginagamit upang simulan ang kaukulang katangian sa nilikha
mga bagay.
Matapos maisakatuparan ang pointToPoint.I-install (mga node) call magkakaroon tayo ng dalawang node, bawat isa ay may
naka-install na point-to-point net device at isang solong point-to-point na channel sa pagitan ng mga ito.
Ang parehong mga aparato ay iko-configure upang magpadala ng data sa limang megabit bawat segundo sa ibabaw ng
channel na mayroong dalawang millisecond na pagkaantala sa paghahatid.
InternetStackHelper
Mayroon na kaming mga node at device na naka-configure, ngunit wala kaming naka-install na anumang protocol stack
sa aming mga node. Ang susunod na dalawang linya ng code ang bahala diyan.
InternetStackHelper stack;
stack.Install (nodes);
Ang InternetStackHelper ay isang topology helper na sa internet stacks kung ano ang
PointToPointHelper ay sa point-to-point net device. Ang I-install pamamaraan ay tumatagal ng a
NodeContainer bilang parameter. Kapag naisakatuparan ito, mag-i-install ito ng Internet Stack
(TCP, UDP, IP, atbp.) sa bawat isa sa mga node sa lalagyan ng node.
IPv4AddressHelper
Susunod na kailangan naming iugnay ang mga device sa aming mga node sa mga IP address. Nagbibigay kami ng a
topology helper upang pamahalaan ang paglalaan ng mga IP address. Ang tanging API na nakikita ng user ay ang
itakda ang base IP address at network mask na gagamitin kapag ginagawa ang aktwal na address
alokasyon (na ginagawa sa mas mababang antas sa loob ng katulong).
Ang susunod na dalawang linya ng code sa aming halimbawang script, una.cc,
Ipv4AddressHelper address;
address.SetBase ("10.1.1.0", "255.255.255.0");
magdeklara ng address helper object at sabihin dito na dapat itong magsimulang maglaan ng mga IP address
mula sa network 10.1.1.0 gamit ang mask na 255.255.255.0 upang tukuyin ang mga ilalaan na bit. Sa pamamagitan ng
default ang mga address na inilalaan ay magsisimula sa isa at tataas nang monotonically, kaya ang una
ang address na inilalaan mula sa base na ito ay magiging 10.1.1.1, na sinusundan ng 10.1.1.2, atbp. Ang mababa
antas ns-3 talagang naaalala ng system ang lahat ng mga IP address na inilaan at bubuo ng a
nakamamatay na error kung hindi mo sinasadyang mabuo ang parehong address nang dalawang beses (na isang
napakahirap i-debug ang error, sa pamamagitan ng paraan).
Ang susunod na linya ng code,
Mga interface ng Ipv4InterfaceContainer = address.Magtalaga (mga device);
gumaganap ng aktwal na pagtatalaga ng address. Sa ns-3 ginagawa namin ang kaugnayan sa pagitan ng isang IP
address at isang device gamit ang isang IPv4Interface bagay. Tulad ng kung minsan kailangan natin ng isang listahan ng
net device na ginawa ng isang helper para sa hinaharap na sanggunian kung minsan kailangan namin ng isang listahan ng
IPv4Interface mga bagay Ang IPv4InterfaceContainer nagbibigay ng functionality na ito.
Ngayon ay mayroon na tayong point-to-point na network na binuo, na may mga stack na naka-install at mga IP address
itinalaga. Ang kailangan natin sa puntong ito ay mga application upang makabuo ng trapiko.
aplikasyon
Isa pang isa sa mga pangunahing abstraction ng ns-3 system ay ang application. Sa ganitong
script gumagamit kami ng dalawang espesyalisasyon ng core ns-3 klase application tinatawag
UdpEchoServerApplication at UdpEchoClientApplication. Tulad ng nangyari sa ating nakaraan
mga paliwanag, gumagamit kami ng mga bagay na katulong upang makatulong na i-configure at pamahalaan ang mga pinagbabatayan na bagay.
Dito, ginagamit namin UdpEchoServerHelper at UdpEchoClientHelper bagay upang gawing mas madali ang ating buhay.
UdpEchoServerHelper
Ang mga sumusunod na linya ng code sa aming halimbawang script, una.cc, ay ginagamit upang mag-set up ng UDP echo
application ng server sa isa sa mga node na dati naming ginawa.
UdpEchoServerHelper echoServer (9);
ApplicationContainer serverApps = echoServer.Install (nodes.Get (1));
serverApps.Start (Second (1.0));
serverApps.Stop (Secons (10.0));
Idineklara ng unang linya ng code sa snippet sa itaas ang UdpEchoServerHelper. Gaya ng dati,
hindi ito ang application mismo, ito ay isang bagay na ginamit upang tulungan kaming lumikha ng aktwal
mga aplikasyon. Isa sa ating mga kombensiyon ay ang paglalagay kailangan katangian sa katulong
tagabuo. Sa kasong ito, walang magagawa ang katulong maliban kung ito ay ibinigay
isang port number na alam din ng kliyente. Imbes na pumili lang ng isa at umasa
gumagana ang lahat, kailangan namin ang numero ng port bilang isang parameter sa constructor. Ang
constructor, sa turn, ay ginagawa lamang a SetAttribute kasama ang naipasa na halaga. Kung gusto mo, ikaw
maaaring itakda ang "Port" katangian sa ibang halaga sa ibang pagkakataon gamit SetAttribute.
Katulad ng maraming iba pang mga bagay na katulong, ang UdpEchoServerHelper bagay ay may isang I-install
paraan. Ito ay ang pagpapatupad ng paraang ito na talagang nagiging sanhi ng pinagbabatayan na echo
server application na i-instantiate at ikabit sa isang node. Kawili-wili, ang I-install
pamamaraan ay tumatagal ng a NodeContainer bilang isang parameter tulad ng iba I-install mga pamamaraan na mayroon tayo
nakita. Ito talaga ang ipinasa sa pamamaraan kahit na hindi ito nakikita
kasong ito. Mayroong isang C++ pahiwatig Conversion sa trabaho dito na kumukuha ng resulta ng
nodes.Kunin (1) (na nagbabalik ng matalinong pointer sa isang node object --- Ptr) at ginagamit iyon
sa isang constructor para sa isang hindi pinangalanan NodeContainer na ipapasa sa I-install. Kung ikaw ay
kailanman naliligaw upang makahanap ng isang partikular na paraan ng lagda sa C++ code na nag-iipon at tumatakbo
ayos lang, hanapin ang mga ganitong uri ng implicit na conversion.
Nakikita natin ngayon iyan echoServer.I-install ay mag-i-install ng a UdpEchoServerApplication sa
node na matatagpuan sa index number one ng NodeContainer dati naming pinangangasiwaan ang aming mga node. I-install
ay magbabalik ng isang lalagyan na naglalaman ng mga pointer sa lahat ng mga application (isa sa kasong ito
simula nung nakapasa tayo a NodeContainer naglalaman ng isang node) na nilikha ng katulong.
Ang mga application ay nangangailangan ng oras upang "magsimula" sa pagbuo ng trapiko at maaaring tumagal ng isang opsyonal na oras upang
"itigil". Nagbibigay kami pareho. Ang mga oras na ito ay itinakda gamit ang ApplicationContainer pamamaraan
simula at Itigil. Ang mga pamamaraang ito ay tumatagal oras mga parameter. Sa kasong ito, ginagamit namin ang isang malinaw C + +
conversion sequence para kunin ang C++ double 1.0 at i-convert ito sa isang ns-3 oras gamit ang bagay
a Segundo cast. Magkaroon ng kamalayan na ang mga panuntunan sa conversion ay maaaring kontrolin ng may-akda ng modelo,
at ang C++ ay may sariling mga panuntunan, kaya hindi mo maaaring palaging ipagpalagay na ang mga parameter ay magiging masaya
nagpalit para sa iyo. Ang dalawang linya,
serverApps.Start (Second (1.0));
serverApps.Stop (Secons (10.0));
ay magiging sanhi ng echo server application sa simula (paganahin ang sarili) sa isang segundo sa
simulation at sa Itigil (huwag paganahin ang sarili nito) sa sampung segundo sa simulation. Sa bisa ng
ang katotohanan na kami ay nagdeklara ng isang simulation event (ang application stop event) na
naisakatuparan sa sampung segundo, tatagal ang simulation at pinakamaliit sampung segundo.
UdpEchoClientHelper
Ang echo client application ay naka-set up sa isang paraan na halos kapareho ng para sa
server. May pinagbabatayan UdpEchoClientApplication na pinamamahalaan ng isang
UdpEchoClientHelper.
UdpEchoClientHelper echoClient (interfaces.GetAddress (1), 9);
echoClient.SetAttribute ("MaxPackets", UintegerValue (1));
echoClient.SetAttribute ("Interval", TimeValue (Second (1.0)));
echoClient.SetAttribute ("PacketSize", UintegerValue (1024));
ApplicationContainer clientApps = echoClient.Install (nodes.Get (0));
clientApps.Start (Second (2.0));
clientApps.Stop (Second (10.0));
Para sa echo client, gayunpaman, kailangan naming magtakda ng limang magkakaibang katangian. Ang unang dalawa
katangian ay nakatakda sa panahon ng pagtatayo ng UdpEchoClientHelper. Nagpapasa kami ng mga parameter
na ginagamit (panloob sa helper) upang itakda ang "RemoteAddress" at "RemotePort"
katangian alinsunod sa aming convention na gawin kinakailangan katangian mga parameter sa
katulong na mga konstruktor.
Alalahanin na ginamit namin ang isang IPv4InterfaceContainer para subaybayan ang mga IP address namin
itinalaga sa aming mga device. Ang zeroth interface sa interface pupuntahan ang lalagyan
tumutugma sa IP address ng zeroth node sa nodes lalagyan. Ang una
interface sa interface ang container ay tumutugma sa IP address ng unang node in
ang nodes lalagyan. Kaya, sa unang linya ng code (mula sa itaas), nililikha namin ang
helper at sabihin ito kaya itakda ang remote na address ng kliyente upang maging IP address
itinalaga sa node kung saan nakatira ang server. Sinasabi rin namin ito na ayusin ang pagpapadala
packet sa port nine.
Ang "MaxPackets" katangian sinasabi sa kliyente ang maximum na bilang ng mga packet na pinapayagan namin
ipadala sa panahon ng simulation. Ang "Interval" katangian nagsasabi sa kliyente kung gaano katagal maghintay
sa pagitan ng mga packet, at ang "PacketSize" katangian nagsasabi sa kliyente kung gaano kalaki ang pakete nito
dapat na mga payload. Sa partikular na kumbinasyong ito ng katangian, sinasabi namin sa
client na magpadala ng isang 1024-byte na packet.
Tulad ng sa kaso ng echo server, sinasabi namin sa echo client na simula at Itigil, Ngunit
dito natin sisimulan ang kliyente isang segundo pagkatapos paganahin ang server (sa dalawang segundo sa
simulation).
Simulator
Ang kailangan nating gawin sa puntong ito ay aktwal na patakbuhin ang simulation. Ginagawa ito gamit ang
ang pandaigdigang pag-andar Simulator::Tumakbo.
Simulator::Run ();
Noong tinawag natin dati ang mga pamamaraan,
serverApps.Start (Second (1.0));
serverApps.Stop (Secons (10.0));
...
clientApps.Start (Second (2.0));
clientApps.Stop (Second (10.0));
talagang nag-iskedyul kami ng mga kaganapan sa simulator sa 1.0 segundo, 2.0 segundo at dalawang kaganapan
sa 10.0 segundo. Kailan Simulator::Tumakbo ay tinatawag na, ang sistema ay magsisimulang tumingin sa pamamagitan ng
listahan ng mga naka-iskedyul na kaganapan at pagsasagawa ng mga ito. Una ay tatakbo ito sa kaganapan sa 1.0 segundo,
na magbibigay-daan sa echo server application (ang kaganapang ito ay maaaring mag-iskedyul ng marami
iba pang mga kaganapan). Pagkatapos ay tatakbo ito sa kaganapang naka-iskedyul para sa t=2.0 segundo na magsisimula
ang echo client application. Muli, ang kaganapang ito ay maaaring mag-iskedyul ng marami pang kaganapan. Ang simula
ang pagpapatupad ng kaganapan sa echo client application ay magsisimula sa yugto ng paglilipat ng data ng
ang simulation sa pamamagitan ng pagpapadala ng packet sa server.
Ang pagkilos ng pagpapadala ng packet sa server ay magti-trigger ng isang hanay ng mga kaganapan na magiging
awtomatikong nakaiskedyul sa likod ng mga eksena at kung saan gaganap ang mga mekanika ng
packet echo ayon sa iba't ibang mga parameter ng timing na itinakda namin sa script.
Sa kalaunan, dahil isang packet lang ang ipinapadala namin (recall the MaxPackets katangian ay naitakda
isa), ang hanay ng mga kaganapan na na-trigger ng nag-iisang kahilingan sa echo ng kliyente ay taper off at
magiging idle ang simulation. Kapag nangyari ito, ang mga natitirang kaganapan ay ang Itigil
mga kaganapan para sa server at sa kliyente. Kapag ang mga kaganapang ito ay naisakatuparan, walang
karagdagang mga kaganapan upang iproseso at Simulator::Tumakbo nagbabalik. Tapos na ang simulation.
Ang natitira na lang ay maglinis. Ginagawa ito sa pamamagitan ng pagtawag sa global function
Simulator:: Wasakin. Habang gumagana ang katulong (o mababang antas ns-3 code) naisakatuparan, sila
inayos ito upang ang mga kawit ay naipasok sa simulator upang sirain ang lahat ng mga bagay
na nilikha. Hindi mo kailangang subaybayan ang alinman sa mga bagay na ito sa iyong sarili ---
ang kailangan mo lang gawin ay tumawag Simulator:: Wasakin at lumabas. Ang ns-3 inalagaan ng system
ang hirap sayo. Ang natitirang mga linya ng aming una ns-3 script, una.cc, gawin mo lang
na:
Simulator:: Wasakin ();
0 bumalik;
}
Kailan ang simulator habilin titigil na
ns-3 ay isang Discrete Event (DE) simulator. Sa naturang simulator, nauugnay ang bawat kaganapan
sa oras ng pagpapatupad nito, at ang simulation ay nagpapatuloy sa pamamagitan ng pagsasagawa ng mga kaganapan sa temporal
pagkakasunud-sunod ng oras ng simulation. Ang mga kaganapan ay maaaring maging sanhi ng pag-iskedyul ng mga kaganapan sa hinaharap (halimbawa, a
Maaaring mag-reschedule ang timer upang mag-expire sa susunod na agwat).
Ang mga unang kaganapan ay karaniwang na-trigger ng bawat bagay, hal, IPv6 ay mag-iskedyul ng Router
Mga Advertisement, Neighbor Solicitation, atbp., isang Application schedule ang unang packet
pagpapadala ng kaganapan, atbp.
Kapag naproseso ang isang kaganapan, maaari itong bumuo ng zero, isa o higit pang mga kaganapan. Bilang isang simulation
executes, mga kaganapan ay natupok, ngunit higit pang mga kaganapan ay maaaring (o maaaring hindi) mabuo. Ang
Awtomatikong hihinto ang simulation kapag wala nang karagdagang kaganapan sa queue ng kaganapan, o kung kailan
may nakitang espesyal na kaganapan sa Stop. Ang kaganapang Stop ay nilikha sa pamamagitan ng Simulator::Tumigil
(stopTime); function.
Mayroong isang tipikal na kaso kung saan Simulator::Tumigil ay talagang kinakailangan upang ihinto ang
simulation: kapag may self-sustaining event. Mga kaganapang nakakapagpapanatili sa sarili (o umuulit).
ay mga kaganapan na palaging nagre-reschedule ng kanilang mga sarili. Bilang resulta, palagi nilang pinapanatili ang kaganapan
walang laman ang pila.
Mayroong maraming mga protocol at module na naglalaman ng mga umuulit na kaganapan, hal:
· FlowMonitor - panaka-nakang pagsusuri para sa mga nawawalang packet
· RIPng - panaka-nakang broadcast ng pag-update ng mga routing table
· atbp.
Sa mga kasong ito, Simulator::Tumigil ay kinakailangan upang maayos na ihinto ang simulation. Sa
karagdagan, kapag ns-3 ay nasa emulation mode, ang RealtimeSimulator ay ginagamit upang panatilihin ang
simulation clock na nakahanay sa machine clock, at Simulator::Tumigil ay kinakailangan upang ihinto
ang proseso.
Marami sa mga simulation program sa tutorial ay hindi tahasang tumatawag Simulator::Tumigil,
dahil ang queue ng kaganapan ay awtomatikong mauubusan ng mga kaganapan. Gayunpaman, gagawin ng mga programang ito
tumanggap din ng tawag sa Simulator::Tumigil. Halimbawa, ang sumusunod na karagdagang pahayag sa
ang unang halimbawang programa ay mag-iskedyul ng tahasang paghinto sa 11 segundo:
+ Simulator::Stop (Segundo (11.0));
Simulator::Run ();
Simulator:: Wasakin ();
0 bumalik;
}
Hindi talaga mababago ng nasa itaas ang pag-uugali ng programang ito, dahil partikular na ito
Ang simulation ay natural na nagtatapos pagkatapos ng 10 segundo. Ngunit kung babaguhin mo ang oras ng paghinto
ang pahayag sa itaas mula 11 segundo hanggang 1 segundo, mapapansin mo na ang simulation
hihinto bago mai-print ang anumang output sa screen (dahil ang output ay nangyayari sa paligid ng oras 2
segundo ng simulation time).
Mahalagang tumawag Simulator::Tumigil bago pagtatawag Simulator::Tumakbo; kung hindi man,
Simulator::Tumakbo maaaring hindi na ibalik ang kontrol sa pangunahing programa upang maisagawa ang paghinto!
gusali Iyong Iskrip
Ginawa naming walang halaga ang pagbuo ng iyong mga simpleng script. Ang kailangan mo lang gawin ay i-drop ang iyong
script sa scratch directory at awtomatiko itong mabubuo kung tatakbo ka ng Waf.
Subukan Natin. Kopya mga halimbawa/tutorial/first.cc sa kumamot direktoryo pagkatapos baguhin
bumalik sa direktoryo ng pinakamataas na antas.
$cd../..
$ cp examples/tutorial/first.cc scratch/myfirst.cc
Buuin ngayon ang iyong unang halimbawa ng script gamit ang waf:
$ ./waf
Dapat mong makita ang mga mensahe na nag-uulat na iyong ang una ko matagumpay na naitayo ang halimbawa.
Waf: Pagpasok ng direktoryo `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
[614/708] cxx: scratch/myfirst.cc -> build/debug/scratch/myfirst_3.o
[706/708] cxx_link: build/debug/scratch/myfirst_3.o -> build/debug/scratch/myfirst
Waf: Umalis sa direktoryo `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Matagumpay na natapos ang 'build' (2.357s)
Maaari mo na ngayong patakbuhin ang halimbawa (tandaan na kung bubuo ka ng iyong programa sa scratch directory
dapat mong patakbuhin ito mula sa scratch directory):
$ ./waf --run scratch/myfirst
Dapat mong makita ang ilang output:
Waf: Pagpasok ng direktoryo `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Umalis sa direktoryo `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Matagumpay na natapos ang 'build' (0.418s)
Nagpadala ng 1024 bytes sa 10.1.1.2
Nakatanggap ng 1024 bytes mula sa 10.1.1.1
Nakatanggap ng 1024 bytes mula sa 10.1.1.2
Dito makikita mo na ang build system ay sumusuri upang matiyak na ang file ay binuo at
pagkatapos ay pinapatakbo ito. Nakikita mo ang bahagi ng pag-log sa echo client na nagpapahiwatig na ito ay nagpadala
isang 1024 byte packet sa Echo Server sa 10.1.1.2. Makikita mo rin ang bahagi ng pag-log
sa echo server sabihin na natanggap nito ang 1024 bytes mula sa 10.1.1.1. Ang echo server
tahimik na nag-echo sa packet at makikita mo ang echo client log na natanggap nito ang packet nito
pabalik mula sa server.
Ns-3 pinagmulan kodigo
Ngayong nagamit mo na ang ilan sa mga ns-3 mga katulong na maaaring gusto mong tingnan ang ilan sa mga
source code na nagpapatupad ng functionality na iyon. Ang pinakabagong code ay maaaring i-browse sa
aming web server sa sumusunod na link: http://code.nsnam.org/ns-3-dev. Doon, makikita mo
ang pahina ng buod ng Mercurial para sa aming ns-3 puno ng pag-unlad.
Sa tuktok ng pahina, makikita mo ang ilang mga link,
buod | shortlog | changelog | graph | mga tag | mga file
Sige at piliin ang file link. Ito ang pinakamataas na antas ng karamihan sa atin
mga repository titingnan:
drwxr-xr-x [pataas]
drwxr-xr-x bindings python file
drwxr-xr-x doc file
drwxr-xr-x halimbawa ng mga file
drwxr-xr-x ns3 file
drwxr-xr-x scratch file
drwxr-xr-x src file
Ang drwxr-xr-x ay gumagamit ng mga file
-rw-r--r-- 2009-07-01 12:47 +0200 560 .hgignore file | mga rebisyon | i-annotate
-rw-r--r-- 2009-07-01 12:47 +0200 1886 .hgtags file | mga rebisyon | i-annotate
-rw-r--r-- 2009-07-01 12:47 +0200 1276 AUTHORS file | mga rebisyon | i-annotate
-rw-r--r-- 2009-07-01 12:47 +0200 30961 CHANGES.html file | mga rebisyon | i-annotate
-rw-r--r-- 2009-07-01 12:47 +0200 17987 LICENSE file | mga rebisyon | i-annotate
-rw-r--r-- 2009-07-01 12:47 +0200 3742 README file | mga rebisyon | i-annotate
-rw-r--r-- 2009-07-01 12:47 +0200 16171 RELEASE_NOTES file | mga rebisyon | i-annotate
-rw-r--r-- 2009-07-01 12:47 +0200 6 VERSION file | mga rebisyon | i-annotate
-rwxr-xr-x 2009-07-01 12:47 +0200 88110 waf file | mga rebisyon | i-annotate
-rwxr-xr-x 2009-07-01 12:47 +0200 28 waf.bat file | mga rebisyon | i-annotate
-rw-r--r-- 2009-07-01 12:47 +0200 35395 wscript file | mga rebisyon | i-annotate
-rw-r--r-- 2009-07-01 12:47 +0200 7673 wutils.py file | mga rebisyon | i-annotate
Ang aming mga halimbawang script ay nasa halimbawa direktoryo. Kung nag-click ka sa halimbawa makikita mo
isang listahan ng mga subdirectory. Isa sa mga file sa sangguni ang subdirectory ay una.cc. Kung
mag-click sa una.cc makikita mo ang code na kakalakad mo lang.
Ang source code ay pangunahin sa SRC direktoryo. Maaari mong tingnan ang source code alinman sa pamamagitan ng
pag-click sa pangalan ng direktoryo o sa pamamagitan ng pag-click sa file link sa kanan ng
pangalan ng direktoryo. Kung mag-click ka sa SRC direktoryo, dadalhin ka sa listahan ng
ang SRC mga subdirectory. Kung mag-click ka sa ubod subdirectory, makikita mo ang isang listahan ng
mga file. Ang unang file na makikita mo (sa pagsulat na ito) ay ipalaglag.h. Kung mag-click ka sa
ipalaglag.h link, ipapadala ka sa source file para sa ipalaglag.h na naglalaman ng mga kapaki-pakinabang na macro
para sa paglabas ng mga script kung may nakitang abnormal na kundisyon.
Ang source code para sa mga katulong na ginamit namin sa kabanatang ito ay matatagpuan sa
src/applications/helper direktoryo. Huwag mag-atubiling sundutin sa puno ng direktoryo upang makakuha
isang pakiramdam para sa kung ano ang naroroon at ang estilo ng ns-3 mga programa.
TWEAKING
paggamit ang Pagtotroso Module
Nakuha na namin ang isang maikling pagtingin sa ns-3 pag-log module habang binabasa ang
una.cc iskrip. Susuriin natin ngayon nang maigi at tingnan kung anong uri ng mga kaso ng paggamit ang
logging subsystem ay idinisenyo upang masakop.
Pagtotroso Pangkalahatang-ideya
Maraming malalaking sistema ang sumusuporta sa ilang uri ng pasilidad ng pag-log ng mensahe, at ns-3 ay hindi isang
pagbubukod. Sa ilang mga kaso, ang mga mensahe ng error lamang ang naka-log sa "operator console" (na
ay karaniwang stderr sa mga sistemang nakabatay sa Unix). Sa ibang mga system, maaaring may mga mensahe ng babala
output pati na rin ang mas detalyadong mga mensaheng nagbibigay-kaalaman. Sa ilang mga kaso, ang mga pasilidad ng pagtotroso
ay ginagamit upang mag-output ng mga mensahe sa pag-debug na maaaring mabilis na gawing blur ang output.
ns-3 isinasaalang-alang na ang lahat ng antas ng verbosity na ito ay kapaki-pakinabang at nagbibigay kami ng a
maaaring piliin, multi-level na diskarte sa pag-log ng mensahe. Maaaring ganap na hindi paganahin ang pag-log,
pinagana sa isang component-by-component na batayan, o pinagana sa buong mundo; at nagbibigay ito ng mapipili
mga antas ng verbosity. Ang ns-3 Ang log module ay nagbibigay ng isang tapat, medyo madaling gamitin
paraan upang makakuha ng kapaki-pakinabang na impormasyon mula sa iyong simulation.
Dapat mong maunawaan na nagbibigay kami ng mekanismo ng pangkalahatang layunin --- pagsubaybay --- sa
kumuha ng data mula sa iyong mga modelo na dapat mas gusto para sa simulation output (tingnan ang
seksyon ng tutorial Gamit ang Tracing System para sa higit pang mga detalye sa aming tracing system).
Ang pag-log ay dapat na mas gusto para sa pag-debug ng impormasyon, mga babala, mga mensahe ng error, o anupaman
oras na gusto mong madaling makakuha ng mabilis na mensahe mula sa iyong mga script o modelo.
Sa kasalukuyan ay may pitong antas ng mga mensahe ng log ng pagtaas ng verbosity na tinukoy sa
system.
· LOG_ERROR --- Mga mensahe ng error sa log (kaugnay na macro: NS_LOG_ERROR);
· LOG_WARN --- Mga mensahe ng babala sa log (kaugnay na macro: NS_LOG_WARN);
· LOG_DEBUG --- Mag-log medyo bihira, ad-hoc debugging na mga mensahe (kaugnay na macro:
NS_LOG_DEBUG);
· LOG_INFO --- Mag-log ng mga mensaheng nagbibigay-kaalaman tungkol sa pag-unlad ng programa (kaugnay na macro:
NS_LOG_INFO);
· LOG_FUNCTION --- Mag-log ng mensahe na naglalarawan sa bawat function na tinatawag (dalawang nauugnay na macro:
NS_LOG_FUNCTION, ginagamit para sa mga function ng miyembro, at NS_LOG_FUNCTION_NOARGS, ginagamit para sa static
mga pag-andar);
· LOG_LOGIC -- Log ng mga mensahe na naglalarawan ng lohikal na daloy sa loob ng isang function (kaugnay na macro:
NS_LOG_LOGIC);
· LOG_ALL --- I-log ang lahat ng nabanggit sa itaas (walang nauugnay na macro).
Para sa bawat LOG_TYPE mayroon ding LOG_LEVEL_TYPE na, kung gagamitin, ay nagbibigay-daan sa pag-log ng lahat ng
mga antas sa itaas nito bilang karagdagan sa antas nito. (Bilang resulta nito, LOG_ERROR at
LOG_LEVEL_ERROR at gayundin ang LOG_ALL at LOG_LEVEL_ALL ay functionally equivalent.) Para sa
halimbawa, ang pagpapagana sa LOG_INFO ay magpapagana lamang sa mga mensaheng ibinigay ng NS_LOG_INFO macro, habang
paganahin ang LOG_LEVEL_INFO ay papaganahin din ang mga mensaheng ibinigay ng NS_LOG_DEBUG, NS_LOG_WARN
at NS_LOG_ERROR na mga macro.
Nagbibigay din kami ng unconditional logging macro na palaging ipinapakita, anuman ang
mga antas ng pag-log o pagpili ng bahagi.
· NS_LOG_UNCOND -- I-log ang nauugnay na mensahe nang walang kondisyon (walang nauugnay na antas ng log).
Ang bawat antas ay maaaring hilingin nang isa-isa o pinagsama-samang; at ang pag-log ay maaaring i-set up gamit ang a
shell environment variable (NS_LOG) o sa pamamagitan ng logging system function na tawag. Gaya ng nakita
mas maaga sa tutorial, ang sistema ng pag-log ay mayroong dokumentasyon ng Doxygen at ngayon ay magiging a
magandang oras upang pag-aralan ang dokumentasyon ng Logging Module kung hindi mo pa ito nagagawa.
Ngayong nabasa mo nang detalyado ang dokumentasyon, gamitin natin ang ilan sa kaalamang iyon
upang makakuha ng ilang kawili-wiling impormasyon mula sa scratch/myfirst.cc halimbawa ng script na mayroon ka
naitayo na.
Pag-enable Pagtotroso
Gamitin natin ang NS_LOG environment variable upang i-on ang ilang higit pang pag-log, ngunit una, para lang
kunin ang aming paniniwala, magpatuloy at patakbuhin ang huling script tulad ng ginawa mo dati,
$ ./waf --run scratch/myfirst
Dapat mong makita ang pamilyar na ngayon na output ng una ns-3 halimbawa ng programa
$ Waf: Pagpasok ng direktoryo `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Umalis sa direktoryo `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Matagumpay na natapos ang 'build' (0.413s)
Nagpadala ng 1024 bytes sa 10.1.1.2
Nakatanggap ng 1024 bytes mula sa 10.1.1.1
Nakatanggap ng 1024 bytes mula sa 10.1.1.2
Lumalabas na ang mga "Naipadala" at "Natanggap" na mga mensahe na nakikita mo sa itaas ay aktwal na nagla-log
mga mensahe mula sa UdpEchoClientApplication at UdpEchoServerApplication. Maaari naming itanong ang
application ng kliyente, halimbawa, upang mag-print ng higit pang impormasyon sa pamamagitan ng pagtatakda ng antas ng pag-log nito
sa pamamagitan ng NS_LOG environment variable.
Ipagpalagay ko mula dito na gumagamit ka ng isang sh-like shell na gumagamit
ang "VARIABLE=value" syntax. Kung gumagamit ka ng tulad-csh na shell, kakailanganin mo
i-convert ang aking mga halimbawa sa "setenv VARIABLE value" na syntax na kinakailangan ng mga shell na iyon.
Sa ngayon, ang UDP echo client application ay tumutugon sa sumusunod na linya ng code sa
scratch/myfirst.cc,
LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO);
Ang linya ng code na ito ay nagbibigay-daan sa LOG_LEVEL_INFO antas ng pag-log. Kapag dumaan kami sa isang pagtotroso
level flag, talagang pinapagana namin ang ibinigay na antas at lahat ng mas mababang antas. Sa kasong ito,
pinagana namin NS_LOG_INFO, NS_LOG_DEBUG, NS_LOG_WARN at NS_LOG_ERROR. Maaari tayong madagdagan
ang antas ng pag-log at makakuha ng higit pang impormasyon nang hindi binabago ang script at muling kino-compile ni
pagtatakda ng NS_LOG environment variable tulad nito:
$ export NS_LOG=UdpEchoClientApplication=level_all
Itinatakda nito ang variable ng kapaligiran ng shell NS_LOG sa string,
UdpEchoClientApplication=level_all
Ang kaliwang bahagi ng takdang-aralin ay ang pangalan ng bahagi ng pag-log na gusto naming itakda,
at ang kanang bahagi ay ang watawat na gusto nating gamitin. Sa kasong ito, i-on namin
lahat ng antas ng pag-debug para sa application. Kung pinapatakbo mo ang script na may NS_LOG set
sa ganitong paraan, ang ns-3 kukunin ng sistema ng pag-log ang pagbabago at dapat mong makita ang sumusunod
output:
Waf: Pagpasok ng direktoryo `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Umalis sa direktoryo `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Matagumpay na natapos ang 'build' (0.404s)
UdpEchoClientApplication:UdpEchoClient()
UdpEchoClientApplication:SetDataSize(1024)
UdpEchoClientApplication:StartApplication()
UdpEchoClientApplication:ScheduleTransmit()
UdpEchoClientApplication:Ipadala()
Nagpadala ng 1024 bytes sa 10.1.1.2
Nakatanggap ng 1024 bytes mula sa 10.1.1.1
UdpEchoClientApplication:HandleRead(0x6241e0, 0x624a20)
Nakatanggap ng 1024 bytes mula sa 10.1.1.2
UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()
Ang karagdagang impormasyon sa pag-debug na ibinigay ng application ay mula sa NS_LOG_FUNCTION
antas. Ito ay nagpapakita sa bawat oras na ang isang function sa application ay tinatawag sa panahon ng script
pagbitay. Sa pangkalahatan, ang paggamit ng (hindi bababa sa) NS_LOG_FUNCTION(ito) sa mga function ng miyembro ay
ginusto. Gamitin lang ang NS_LOG_FUNCTION_NOARGS() sa mga static na function. Tandaan, gayunpaman, iyon
walang mga kinakailangan sa ns-3 sistema na dapat suportahan ng mga modelo ang anumang partikular
pag-andar ng pag-log. Ang desisyon tungkol sa kung gaano karaming impormasyon ang naka-log ay naiwan
ang indibidwal na developer ng modelo. Sa kaso ng mga echo application, isang mahusay na deal ng log
magagamit ang output.
Makakakita ka na ngayon ng log ng mga function na tawag na ginawa sa application. kung ikaw
tingnang mabuti mapapansin mo ang isang colon sa pagitan ng string UdpEchoClientApplication
at ang pangalan ng pamamaraan kung saan maaaring inaasahan mo ang isang operator ng saklaw ng C++ (::). Ito ay
intensyonal.
Ang pangalan ay hindi talaga isang pangalan ng klase, ito ay isang pangalan ng bahagi ng pag-log. Kapag may a
isa-sa-isang sulat sa pagitan ng isang source file at isang klase, ito ay karaniwang ang
pangalan ng klase ngunit dapat mong maunawaan na ito ay hindi talaga isang pangalan ng klase, at mayroong isang
single colon doon sa halip na double colon para ipaalala sa iyo sa medyo banayad na paraan
konseptong paghiwalayin ang pangalan ng bahagi ng pag-log mula sa pangalan ng klase.
Lumalabas na sa ilang mga kaso, maaaring mahirap matukoy kung aling paraan talaga
bumubuo ng isang log message. Kung titingnan mo ang teksto sa itaas, maaari kang magtaka kung saan ang string
"Natanggap 1024 bytes mula 10.1.1.2" nanggaling. Mareresolba mo ito sa pamamagitan ng pag-OR sa
prefix_func antas sa NS_LOG variable ng kapaligiran. Subukang gawin ang mga sumusunod,
$ export 'NS_LOG=UdpEchoClientApplication=level_all|prefix_func'
Tandaan na ang mga quote ay kinakailangan dahil ang vertical bar na ginagamit namin upang ipahiwatig ang isang OR
Ang operasyon ay isa ring Unix pipe connector.
Ngayon, kung patakbuhin mo ang script makikita mo na tinitiyak ng sistema ng pag-log na ang bawat
ang mensahe mula sa ibinigay na bahagi ng log ay may prefix na pangalan ng bahagi.
Waf: Pagpasok ng direktoryo `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Umalis sa direktoryo `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Matagumpay na natapos ang 'build' (0.417s)
UdpEchoClientApplication:UdpEchoClient()
UdpEchoClientApplication:SetDataSize(1024)
UdpEchoClientApplication:StartApplication()
UdpEchoClientApplication:ScheduleTransmit()
UdpEchoClientApplication:Ipadala()
UdpEchoClientApplication:Send(): Nagpadala ng 1024 bytes sa 10.1.1.2
Nakatanggap ng 1024 bytes mula sa 10.1.1.1
UdpEchoClientApplication:HandleRead(0x6241e0, 0x624a20)
UdpEchoClientApplication:HandleRead(): Nakatanggap ng 1024 bytes mula sa 10.1.1.2
UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()
Maaari mo na ngayong makita ang lahat ng mga mensahe na nagmumula sa UDP echo client application ay
kinilala bilang ganoon. Ang mensaheng "Nakatanggap ng 1024 bytes mula sa 10.1.1.2" ay malinaw na ngayon
natukoy na nagmumula sa echo client application. Ang natitirang mensahe ay dapat na
nagmumula sa UDP echo server application. Mapapagana natin ang bahaging iyon sa pamamagitan ng paglalagay ng a
colon separated na listahan ng mga bahagi sa NS_LOG environment variable.
$ export 'NS_LOG=UdpEchoClientApplication=level_all|prefix_func:
UdpEchoServerApplication=level_all|prefix_func'
Babala: Kakailanganin mong alisin ang bagong linya pagkatapos ng : sa halimbawang teksto sa itaas kung saan
ay doon lamang para sa mga layunin ng pag-format ng dokumento.
Ngayon, kung patakbuhin mo ang script makikita mo ang lahat ng mga mensahe ng log mula sa parehong echo client
at mga application ng server. Maaari mong makita na ito ay maaaring maging lubhang kapaki-pakinabang sa mga problema sa pag-debug.
Waf: Pagpasok ng direktoryo `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Umalis sa direktoryo `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Matagumpay na natapos ang 'build' (0.406s)
UdpEchoServerApplication:UdpEchoServer()
UdpEchoClientApplication:UdpEchoClient()
UdpEchoClientApplication:SetDataSize(1024)
UdpEchoServerApplication:StartApplication()
UdpEchoClientApplication:StartApplication()
UdpEchoClientApplication:ScheduleTransmit()
UdpEchoClientApplication:Ipadala()
UdpEchoClientApplication:Send(): Nagpadala ng 1024 bytes sa 10.1.1.2
UdpEchoServerApplication:HandleRead(): Nakatanggap ng 1024 bytes mula sa 10.1.1.1
UdpEchoServerApplication:HandleRead(): Echoing packet
UdpEchoClientApplication:HandleRead(0x624920, 0x625160)
UdpEchoClientApplication:HandleRead(): Nakatanggap ng 1024 bytes mula sa 10.1.1.2
UdpEchoServerApplication:StopApplication()
UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoServerApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()
UdpEchoServerApplication:~UdpEchoServer()
Minsan din ay kapaki-pakinabang na makita ang simulation time kung kailan ang isang log message
ay nabuo. Magagawa mo ito sa pamamagitan ng ORing sa prefix_time bit.
$ export 'NS_LOG=UdpEchoClientApplication=level_all|prefix_func|prefix_time:
UdpEchoServerApplication=level_all|prefix_func|prefix_time'
Muli, kakailanganin mong alisin ang bagong linya sa itaas. Kung pinapatakbo mo ang script ngayon, dapat
tingnan ang sumusunod na output:
Waf: Pagpasok ng direktoryo `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Umalis sa direktoryo `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Matagumpay na natapos ang 'build' (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(): Nagpadala ng 1024 bytes sa 10.1.1.2
2.00369s UdpEchoServerApplication:HandleRead(): Nakatanggap ng 1024 bytes mula sa 10.1.1.1
2.00369s UdpEchoServerApplication:HandleRead(): Echoing packet
2.00737s UdpEchoClientApplication:HandleRead(0x624290, 0x624ad0)
2.00737s UdpEchoClientApplication:HandleRead(): Nakatanggap ng 1024 bytes mula sa 10.1.1.2
10s UdpEchoServerApplication:StopApplication()
10s UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoServerApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()
UdpEchoServerApplication:~UdpEchoServer()
Makikita mo na ang constructor para sa UdpEchoServer ay tinawag sa isang simulation time ng
0 segundo. Ito ay aktwal na nangyayari bago magsimula ang simulation, ngunit ang oras ay
ipinapakita bilang zero segundo. Ang parehong ay totoo para sa UdpEchoClient constructor mensahe.
Tandaan na ang scratch/first.cc Sinimulan ng script ang echo server application sa isang segundo
sa simulation. Makikita mo na ngayon na ang StartApplication paraan ng server ay,
sa katunayan, tinawag sa isang segundo. Maaari mo ring makita na ang echo client application ay
nagsimula sa isang simulation time na dalawang segundo gaya ng hiniling namin sa script.
Maaari mo na ngayong sundin ang pag-usad ng simulation mula sa ScheduleTransmit tawagan ang
kliyente na tumatawag magpadala sa HandleRead callback sa echo server application. Tandaan
na ang lumipas na oras para sa packet na maipadala sa point-to-point na link ay 3.69
millisecond. Nakikita mo ang echo server na nagla-log ng isang mensahe na nagsasabi sa iyo na ito ay nag-echoed
ang packet at pagkatapos, pagkatapos ng isa pang pagkaantala ng channel, makikita mong natanggap ng echo client ang
echoed packet sa loob nito HandleRead pamamaraan.
Maraming nangyayari sa ilalim ng mga pabalat sa simulation na ito na hindi ikaw
nakikita rin. Madali mong masusunod ang buong proseso sa pamamagitan ng pag-on sa lahat ng
pag-log ng mga bahagi sa system. Subukang itakda ang NS_LOG variable sa mga sumusunod,
$ export 'NS_LOG=*=level_all|prefix_func|prefix_time'
Ang asterisk sa itaas ay ang logging component wildcard. I-on nito ang lahat ng
pag-log in sa lahat ng bahaging ginamit sa simulation. Hindi ko ireproduce ang output
dito (sa pagsulat na ito ay gumagawa ito ng 1265 na linya ng output para sa solong packet echo) ngunit
maaari mong i-redirect ang impormasyong ito sa isang file at tingnan ito gamit ang iyong paborito
editor kung gusto mo,
$ ./waf --run scratch/myfirst > log.out 2>&1
Personal kong ginagamit itong napaka-verbose na bersyon ng pag-log kapag ako ay iniharap sa isang
problema at wala akong ideya kung saan nangyayari ang mga bagay na mali. Maaari kong sundin ang pag-unlad ng
medyo madali ang code nang hindi kinakailangang magtakda ng mga breakpoint at hakbang sa code sa isang debugger.
Maaari ko lang i-edit ang output sa aking paboritong editor at maghanap sa paligid ng mga bagay na inaasahan ko,
at makita ang mga nangyayaring hindi ko inaasahan. Kapag mayroon akong pangkalahatang ideya tungkol sa kung ano ang
nagkakamali, lumipat ako sa isang debugger para sa isang pinong pagsusuri ng problema.
Ang ganitong uri ng output ay maaaring maging kapaki-pakinabang lalo na kapag ang iyong script ay ganap na gumawa ng isang bagay
hindi inaasahan. Kung ikaw ay humahakbang gamit ang isang debugger maaari kang makaligtaan ng isang hindi inaasahang ekskursiyon
ganap. Ang pag-log sa iskursiyon ay ginagawa itong mabilis na nakikita.
Pagdaragdag Pagtotroso sa iyong kodigo
Maaari kang magdagdag ng bagong pag-log sa iyong mga simulation sa pamamagitan ng pagtawag sa bahagi ng log sa pamamagitan ng
ilang mga macro. Gawin natin ito sa myfirst.cc script na mayroon kami sa kumamot direktoryo.
Alalahanin na tinukoy namin ang isang bahagi ng pag-log sa script na iyon:
NS_LOG_COMPONENT_DEFINE ("FirstScriptExample");
Alam mo na ngayon na maaari mong paganahin ang lahat ng pag-log para sa bahaging ito sa pamamagitan ng pagtatakda ng
NS_LOG variable ng kapaligiran sa iba't ibang antas. Sige at magdagdag tayo ng ilang pag-log sa
ang script. Ang macro na ginamit upang magdagdag ng mensahe ng log sa antas ng impormasyon ay NS_LOG_INFO. Punta ka na
unahan at magdagdag ng isa (bago lang natin simulan ang paggawa ng mga node) na nagsasabi sa iyo na ang script
ay "Paglikha ng Topology." Ginagawa ito tulad ng sa snippet ng code na ito,
Pagbubukas scratch/myfirst.cc sa iyong paboritong editor at idagdag ang linya,
NS_LOG_INFO ("Paglikha ng Topology");
bago ang mga linya,
NodeContainer node;
nodes.Lumikha (2);
Buuin ngayon ang script gamit ang waf at i-clear ang NS_LOG variable upang patayin ang torrent ng
pag-log na dati naming pinagana:
$ ./waf
$ export NS_LOG=
Ngayon, kung patakbuhin mo ang script,
$ ./waf --run scratch/myfirst
gagawin mo hindi makita ang iyong bagong mensahe mula noong nauugnay na bahagi ng pag-log
(FirstScriptExample) ay hindi pinagana. Upang makita ang iyong mensahe kailangan mong
paganahin ang FirstScriptExample logging component na may antas na mas mataas sa o katumbas ng
NS_LOG_INFO. Kung gusto mo lang makita ang partikular na antas ng pag-log, maaari mo itong paganahin
ni,
$ export NS_LOG=FirstScriptExample=info
Kung patakbuhin mo na ngayon ang script makikita mo ang iyong bagong "Paglikha ng Topology" na mensahe ng log,
Waf: Pagpasok ng direktoryo `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Umalis sa direktoryo `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Matagumpay na natapos ang 'build' (0.404s)
Paglikha ng Topology
Nagpadala ng 1024 bytes sa 10.1.1.2
Nakatanggap ng 1024 bytes mula sa 10.1.1.1
Nakatanggap ng 1024 bytes mula sa 10.1.1.2
paggamit Utos Linya Mga argumento
Sobra default katangian
Isa pang paraan na maaari mong baguhin kung paano ns-3 ang mga script ay kumikilos nang walang pag-edit at ang pagbuo ay sa pamamagitan ng
utos linya argumento. Nagbibigay kami ng mekanismo para i-parse ang mga argumento ng command line at
awtomatikong nagtatakda ng mga lokal at pandaigdigang variable batay sa mga argumentong iyon.
Ang unang hakbang sa paggamit ng command line argument system ay ang pagdeklara ng command line
parser. Ginagawa ito nang simple (sa iyong pangunahing programa) tulad ng sa sumusunod na code,
int
pangunahing (int argc, char *argv[])
{
...
CommandLine cmd;
cmd.Parse (argc, argv);
...
}
Ang simpleng dalawang linyang snippet na ito ay talagang napaka-kapaki-pakinabang nang mag-isa. Binuksan nito ang pinto sa
ns-3 pandaigdigang variable at katangian mga sistema. Sige at idagdag ang dalawang linya ng code sa
ang scratch/myfirst.cc script sa simula ng pangunahin. Sige at buuin ang script at tumakbo
ito, ngunit humingi ng tulong sa script sa sumusunod na paraan,
$ ./waf --run "scratch/myfirst --PrintHelp"
Hihilingin nito kay Waf na patakbuhin ang scratch/myfirst script at ipasa ang argumento ng command line
--PrintHelp sa script. Ang mga quote ay kinakailangan upang ayusin kung aling programa ang makakakuha ng alin
argumento. Makikita na ngayon ng command line parser ang --PrintHelp argumento at tumugon ng,
Waf: Pagpasok ng direktoryo `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Umalis sa direktoryo `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Matagumpay na natapos ang 'build' (0.413s)
TcpL4Protocol:TcpStateMachine()
CommandLine:HandleArgument(): Pangasiwaan ang arg name=PrintHelp value=
--PrintHelp: I-print ang mensahe ng tulong na ito.
--PrintGroups: I-print ang listahan ng mga grupo.
--PrintTypeIds: I-print ang lahat ng TypeIds.
--PrintGroup=[group]: I-print ang lahat ng TypeIds ng grupo.
--PrintAttributes=[typeid]: I-print ang lahat ng attribute ng typeid.
--PrintGlobals: I-print ang listahan ng mga global.
Tumutok tayo sa --PrintAttributes opsyon. Nagpahiwatig na kami sa ns-3 katangian
sistema habang naglalakad sa una.cc iskrip. Tiningnan namin ang mga sumusunod na linya ng
code,
PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
at nabanggit iyon DataRate ay talagang isang katangian ng PointToPointNetDevice. tayo
gamitin ang command line argument parser upang tingnan ang katangian ng
PointToPointNetDevice. Ang listahan ng tulong ay nagsasabi na dapat kaming magbigay ng a TypeId. ito
tumutugma sa pangalan ng klase ng klase kung saan ang katangian nabibilang. Sa kasong ito
ito ay magiging ns3::PointToPointNetDevice. Sige at mag-type tayo,
$ ./waf --run "scratch/myfirst --PrintAttributes=ns3::PointToPointNetDevice"
Ipi-print ng system ang lahat ng katangian ng ganitong uri ng net device. Kabilang sa mga
katangian makikita mo ang nakalista ay,
--ns3::PointToPointNetDevice::DataRate=[32768bps]:
Ang default na rate ng data para sa point to point na mga link
Ito ang default na halaga na gagamitin kapag a PointToPointNetDevice ay nilikha sa
sistema. Na-overrode namin ang default na ito gamit ang katangian setting sa PointToPointHelper
sa itaas. Gamitin natin ang mga default na halaga para sa mga point-to-point na device at channel sa pamamagitan ng
tinatanggal ang SetDeviceAttribute tawag at ang SetChannelAttribute tawag mula sa myfirst.cc
mayroon kami sa scratch directory.
Ang iyong script ay dapat na ngayong ideklara ang PointToPointHelper at walang gagawin itakda pagpapatakbo
tulad ng sa sumusunod na halimbawa,
...
NodeContainer node;
nodes.Lumikha (2);
PointToPointHelper pointToPoint;
Mga aparatong NetDeviceContainer;
mga device = pointToPoint.Install (nodes);
...
Sige at bumuo ng bagong script gamit ang Waf (./waff) at bumalik tayo at paganahin ang ilan
pag-log mula sa UDP echo server application at i-on ang time prefix.
$ export 'NS_LOG=UdpEchoServerApplication=level_all|prefix_time'
Kung pinapatakbo mo ang script, dapat mo na ngayong makita ang sumusunod na output,
Waf: Pagpasok ng direktoryo `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Umalis sa direktoryo `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Matagumpay na natapos ang 'build' (0.405s)
0s UdpEchoServerApplication:UdpEchoServer()
1s UdpEchoServerApplication:StartApplication()
Nagpadala ng 1024 bytes sa 10.1.1.2
2.25732s Nakatanggap ng 1024 bytes mula sa 10.1.1.1
2.25732s Echoing packet
Nakatanggap ng 1024 bytes mula sa 10.1.1.2
10s UdpEchoServerApplication:StopApplication()
UdpEchoServerApplication:DoDispose()
UdpEchoServerApplication:~UdpEchoServer()
Alalahanin na ang huling pagkakataon na tiningnan namin ang simulation time kung saan naroon ang packet
natanggap ng echo server, ito ay nasa 2.00369 segundo.
2.00369s UdpEchoServerApplication:HandleRead(): Nakatanggap ng 1024 bytes mula sa 10.1.1.1
Ngayon ay tinatanggap nito ang packet sa 2.25732 segundo. Ito ay dahil ibinaba lang namin ang
data rate ng PointToPointNetDevice hanggang sa default nito na 32768 bits bawat segundo mula sa
limang megabit bawat segundo.
Kung magbibigay tayo ng bago DataRate gamit ang command line, mapapabilis natin ang ating simulation
pataas ulit. Ginagawa namin ito sa sumusunod na paraan, ayon sa formula na ipinahiwatig ng tulong
item:
$ ./waf --run "scratch/myfirst --ns3::PointToPointNetDevice::DataRate=5Mbps"
Itatakda nito ang default na halaga ng DataRate katangian bumalik sa limang megabits bawat
pangalawa. Nagulat ka ba sa resulta? Ito ay lumiliko na upang makuha ang orihinal
pag-uugali ng script pabalik, kailangan nating itakda ang bilis ng liwanag na pagkaantala ng channel
din. Maaari naming hilingin sa command line system na i-print ang katangian ng channel
tulad ng ginawa namin para sa net device:
$ ./waf --run "scratch/myfirst --PrintAttributes=ns3::PointToPointChannel"
Natuklasan namin ang Pagkaantala katangian ng channel ay nakatakda sa sumusunod na paraan:
--ns3::PointToPointChannel::Delay=[0ns]:
Pagkaantala ng paghahatid sa pamamagitan ng channel
Pagkatapos ay maaari naming itakda ang parehong mga default na halaga sa pamamagitan ng command line system,
$ ./waf --run "scratch/myfirst
--ns3::PointToPointNetDevice::DataRate=5Mbps
--ns3::PointToPointChannel::Delay=2ms"
kung saan binabawi namin ang timing na mayroon kami noong tahasan naming itinakda ang DataRate at Pagkaantala
sa script:
Waf: Pagpasok ng direktoryo `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Umalis sa direktoryo `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Matagumpay na natapos ang 'build' (0.417s)
0s UdpEchoServerApplication:UdpEchoServer()
1s UdpEchoServerApplication:StartApplication()
Nagpadala ng 1024 bytes sa 10.1.1.2
2.00369s Nakatanggap ng 1024 bytes mula sa 10.1.1.1
2.00369s Echoing packet
Nakatanggap ng 1024 bytes mula sa 10.1.1.2
10s UdpEchoServerApplication:StopApplication()
UdpEchoServerApplication:DoDispose()
UdpEchoServerApplication:~UdpEchoServer()
Tandaan na ang packet ay muling natanggap ng server sa 2.00369 segundo. kaya namin
aktwal na itakda ang alinman sa katangian ginamit sa script sa ganitong paraan. Sa partikular na magagawa namin
itakda ang UdpEchoClient katangian MaxPackets sa ibang halaga kaysa sa isa.
Paano mo gagawin iyon? Subukan. Tandaan na kailangan mong magkomento sa lugar
na-override namin ang default katangian at tahasang itinakda MaxPackets sa script. Tapos ikaw
kailangang muling buuin ang script. Kakailanganin mo ring hanapin ang syntax para sa aktwal na setting
ang bagong default na value ng attribute gamit ang command line help facility. Kapag mayroon ka nito
Naisip mo na dapat mong kontrolin ang bilang ng mga packet na na-echo mula sa utos
linya. Dahil mabait kaming mga tao, sasabihin namin sa iyo na ang iyong command line ay dapat na maghahanap
parang,
$ ./waf --run "scratch/myfirst
--ns3::PointToPointNetDevice::DataRate=5Mbps
--ns3::PointToPointChannel::Delay=2ms
--ns3::UdpEchoClient::MaxPackets=2"
Hooking Iyong Sarili Halaga ng
Maaari ka ring magdagdag ng iyong sariling mga kawit sa command line system. Ginagawa ito nang simple sa pamamagitan ng
gamit ang Magdagdag ng Halaga paraan sa command line parser.
Gamitin natin ang pasilidad na ito upang tukuyin ang bilang ng mga packet na mag-echo sa isang ganap na naiiba
paraan. Magdagdag tayo ng lokal na variable na tinatawag nPackets sa pangunahin function. Magsisimula kami
ito sa isa upang tumugma sa aming nakaraang default na gawi. Upang payagan ang command line parser na
baguhin ang halagang ito, kailangan nating i-hook ang halaga sa parser. Ginagawa namin ito sa pamamagitan ng pagdaragdag ng isang tawag
sa Magdagdag ng Halaga. Sige at baguhin ang scratch/myfirst.cc script upang magsimula sa
sumusunod na code,
int
pangunahing (int argc, char *argv[])
{
uint32_t nPackets = 1;
CommandLine cmd;
cmd.AddValue("nPackets", "Bilang ng mga packet na ie-echo", nPackets);
cmd.Parse (argc, argv);
...
Mag-scroll pababa sa punto sa script kung saan itinakda namin ang MaxPackets katangian at baguhin ito
upang ito ay nakatakda sa variable nPackets sa halip na pare-pareho 1 tulad ng ipinapakita sa ibaba.
echoClient.SetAttribute ("MaxPackets", UintegerValue (nPackets));
Ngayon kung patakbuhin mo ang script at ibigay ang --PrintHelp argumento, dapat mong makita ang iyong bago
gumagamit Argumento nakalista sa display ng tulong.
Subukan,
$ ./waf --run "scratch/myfirst --PrintHelp"
Waf: Pagpasok ng direktoryo `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Umalis sa direktoryo `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Matagumpay na natapos ang 'build' (0.403s)
--PrintHelp: I-print ang mensahe ng tulong na ito.
--PrintGroups: I-print ang listahan ng mga grupo.
--PrintTypeIds: I-print ang lahat ng TypeIds.
--PrintGroup=[group]: I-print ang lahat ng TypeIds ng grupo.
--PrintAttributes=[typeid]: I-print ang lahat ng attribute ng typeid.
--PrintGlobals: I-print ang listahan ng mga global.
Mga Argumento ng User:
--nPackets: Bilang ng mga packet na ie-echo
Kung gusto mong tukuyin ang bilang ng mga packet na ie-echo, maaari mo na ngayong gawin ito sa pamamagitan ng pagtatakda ng
--nPackets argumento sa command line,
$ ./waf --run "scratch/myfirst --nPackets=2"
Dapat mong makita ngayon
Waf: Pagpasok ng direktoryo `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Umalis sa direktoryo `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Matagumpay na natapos ang 'build' (0.404s)
0s UdpEchoServerApplication:UdpEchoServer()
1s UdpEchoServerApplication:StartApplication()
Nagpadala ng 1024 bytes sa 10.1.1.2
2.25732s Nakatanggap ng 1024 bytes mula sa 10.1.1.1
2.25732s Echoing packet
Nakatanggap ng 1024 bytes mula sa 10.1.1.2
Nagpadala ng 1024 bytes sa 10.1.1.2
3.25732s Nakatanggap ng 1024 bytes mula sa 10.1.1.1
3.25732s Echoing packet
Nakatanggap ng 1024 bytes mula sa 10.1.1.2
10s UdpEchoServerApplication:StopApplication()
UdpEchoServerApplication:DoDispose()
UdpEchoServerApplication:~UdpEchoServer()
Nag-echo ka na ngayon ng dalawang packet. Medyo madali, hindi ba?
Makikita mo iyon kung ikaw ay isang ns-3 user, maaari mong gamitin ang command line argument system upang
kontrolin ang mga pandaigdigang halaga at katangian. Kung ikaw ay isang modelong may-akda, maaari kang magdagdag ng bago
katangian sa iyong bagay at awtomatiko silang magiging available para itakda ng iyong
mga gumagamit sa pamamagitan ng command line system. Kung ikaw ay isang may-akda ng script, maaari kang magdagdag ng bago
variable sa iyong mga script at i-hook ang mga ito sa command line system nang walang sakit.
paggamit ang Pagsubaybay Sistema
Ang buong punto ng simulation ay upang makabuo ng output para sa karagdagang pag-aaral, at ang ns-3
Ang sistema ng pagsubaybay ay isang pangunahing mekanismo para dito. Since ns-3 ay isang C++ program, standard
Ang mga pasilidad para sa pagbuo ng output mula sa mga programang C++ ay maaaring gamitin:
# isama
...
int pangunahing ()
{
...
std::cout << "Ang halaga ng x ay " << x << std::endl;
...
}
Maaari mo ring gamitin ang logging module upang magdagdag ng kaunting istraktura sa iyong solusyon. doon
ay maraming mga kilalang problema na nabuo sa pamamagitan ng naturang mga diskarte at kaya nagbigay kami ng a
generic na event tracing subsystem upang matugunan ang mga isyung inakala naming mahalaga.
Ang mga pangunahing layunin ng ns-3 Ang sistema ng pagsubaybay ay:
· Para sa mga pangunahing gawain, dapat pahintulutan ng sistema ng pagsubaybay ang user na bumuo ng karaniwang pagsubaybay
para sa mga sikat na pinagmumulan ng pagsubaybay, at upang i-customize kung aling mga bagay ang bumubuo ng pagsubaybay;
· Dapat na ma-extend ng mga intermediate na user ang tracing system para baguhin ang output format
nabuo, o upang magpasok ng mga bagong pinagmumulan ng pagsubaybay, nang hindi binabago ang core ng
simulator;
· Maaaring baguhin ng mga advanced na user ang simulator core para magdagdag ng mga bagong tracing source at sink.
Ang ns-3 Ang sistema ng pagsubaybay ay binuo sa mga konsepto ng mga independiyenteng pinagmumulan ng pagsubaybay at
pagsubaybay sa mga lababo, at isang pare-parehong mekanismo para sa pagkonekta ng mga mapagkukunan sa mga lababo. Ang mga pinagmumulan ng bakas ay
mga entity na maaaring magsenyas ng mga kaganapang nangyayari sa isang simulation at magbigay ng access sa
kawili-wiling pinagbabatayan ng data. Halimbawa, maaaring ipahiwatig ng isang trace source kung kailan ang isang packet
natanggap ng isang net device at nagbibigay ng access sa mga nilalaman ng packet para sa bakas na interesado
lababo.
Ang mga pinagmumulan ng bakas ay hindi kapaki-pakinabang sa kanilang sarili, dapat silang "konektado" sa iba pang mga piraso ng
code na aktwal na gumagawa ng isang bagay na kapaki-pakinabang sa impormasyong ibinigay ng lababo. Bakas
Ang mga lababo ay mga mamimili ng mga kaganapan at data na ibinigay ng mga pinagmumulan ng bakas. Halimbawa,
ang isa ay maaaring lumikha ng isang trace sink na (kapag nakakonekta sa trace source ng
nakaraang halimbawa) mag-print ng mga kagiliw-giliw na bahagi ng natanggap na packet.
Ang katwiran para sa tahasang paghahati na ito ay upang payagan ang mga user na mag-attach ng mga bagong uri ng sink
mga kasalukuyang pinagmumulan ng pagsubaybay, nang hindi nangangailangan ng pag-edit at muling pagsasama-sama ng core ng
simulator. Kaya, sa halimbawa sa itaas, maaaring tukuyin ng isang user ang isang bagong tracing sink sa kanya
script at ilakip ito sa isang kasalukuyang pinagmumulan ng pagsubaybay na tinukoy sa simulation core ni
ang pag-edit lamang ng script ng gumagamit.
Sa tutorial na ito, tatalakayin natin ang ilang paunang natukoy na mga mapagkukunan at lababo at ipapakita kung paano
maaaring i-customize ang mga ito sa kaunting pagsisikap ng user. Tingnan ang ns-3 manual o how-to na mga seksyon
para sa impormasyon sa advanced na pagsasaayos ng pagsubaybay kasama ang pagpapahaba ng pagsubaybay
namespace at paglikha ng mga bagong tracing source.
ASCII Pagsubaybay
ns-3 nagbibigay ng helper functionality na bumabalot sa mababang antas ng tracing system upang matulungan ka
kasama ang mga detalyeng kasangkot sa pag-configure ng ilang madaling maunawaan na packet traces. kung ikaw
paganahin ang pagpapaandar na ito, makikita mo ang output sa isang ASCII file --- kaya ang pangalan. Para sa
mga pamilyar sa ns-2 output, ang ganitong uri ng bakas ay kahalintulad sa out.tr nabuo
sa pamamagitan ng maraming mga script.
Tumalon lang tayo at magdagdag ng ilang ASCII tracing output sa ating scratch/myfirst.cc
iskrip. Bago ang tawag sa Simulator::Tumakbo (), idagdag ang mga sumusunod na linya ng code:
AsciiTraceHelper ascii;
pointToPoint.EnableAsciiAll (ascii.CreateFileStream ("myfirst.tr"));
Tulad ng sa marami pang iba ns-3 idioms, ang code na ito ay gumagamit ng helper object upang makatulong sa paglikha ng ASCII
bakas. Ang pangalawang linya ay naglalaman ng dalawang nested method na tawag. Ang pamamaraang "loob",
CreateFileStream() ay gumagamit ng isang hindi pinangalanang object idiom upang lumikha ng isang file stream object sa
stack (nang walang pangalan ng object) at ipasa ito sa tinatawag na pamamaraan. Papasok tayo dito
higit pa sa hinaharap, ngunit ang kailangan mo lang malaman sa puntong ito ay lumilikha ka ng isang
object na kumakatawan sa isang file na pinangalanang "myfirst.tr" at ipinapasa ito sa ns-3. Ikaw ay nagsasabi
ns-3 upang harapin ang mga panghabambuhay na isyu ng nilikhang bagay at gayundin upang harapin ang mga problema
sanhi ng isang maliit na kilalang (intensyonal) na limitasyon ng C++ ng mga bagay sa stream na nauugnay sa kopya
mga konstruktor.
Ang tawag sa labas, sa EnableAsciiAll(), sasabihin sa katulong na gusto mong paganahin ang ASCII
pagsubaybay sa lahat ng point-to-point na device sa iyong simulation; at gusto mo ang (ibinigay)
trace sinks upang isulat ang impormasyon tungkol sa paggalaw ng packet sa ASCII format.
Para sa mga pamilyar sa ns-2, ang mga sinusubaybayang kaganapan ay katumbas ng mga sikat na trace point
ang log na "+", "-", "d", at "r" na mga kaganapan.
Maaari mo na ngayong buuin ang script at patakbuhin ito mula sa command line:
$ ./waf --run scratch/myfirst
Tulad ng nakita mo nang maraming beses dati, makakakita ka ng ilang mensahe mula kay Waf at pagkatapos
"Matagumpay na natapos ang 'build'" na may ilang bilang ng mga mensahe mula sa tumatakbong programa.
Kapag tumakbo ito, gagawa ang program ng isang file na pinangalanan myfirst.tr. Dahil sa paraan
na gumagana ang Waf, ang file ay hindi nilikha sa lokal na direktoryo, ito ay nilikha sa
top-level na direktoryo ng repository bilang default. Kung gusto mong kontrolin kung saan ang mga bakas
ay nai-save maaari mong gamitin ang --cwd opsyon ng Waf upang tukuyin ito. Hindi namin ginawa ito, kaya
kailangan nating lumipat sa pinakamataas na antas ng direktoryo ng ating repo at tingnan ang ASCII
trace file myfirst.tr sa iyong paboritong editor.
Nagpaparada ASCII traces
Mayroong maraming impormasyon doon sa medyo siksik na anyo, ngunit ang unang bagay na mapapansin
ay mayroong isang bilang ng mga natatanging linya sa file na ito. Maaaring mahirap makita
malinaw ito maliban kung palakihin mo nang husto ang iyong bintana.
Ang bawat linya sa file ay tumutugma sa a kopyahin o sipiin sa pamamagitan ng pag-aninag pangyayari. Sa kasong ito, sinusubaybayan namin ang mga kaganapan
ang magpadala pila naroroon sa bawat point-to-point net device sa simulation. Ang
Ang transmit queue ay isang pila kung saan ang bawat packet ay nakalaan para sa isang point-to-point na channel
dapat pumasa. Tandaan na ang bawat linya sa trace file ay nagsisimula sa isang solong character (may a
espasyo pagkatapos nito). Ang karakter na ito ay magkakaroon ng sumusunod na kahulugan:
· +: Isang enqueue operation ang naganap sa queue ng device;
· -: Isang dequeue operation ang naganap sa queue ng device;
· d: Nahulog ang isang pakete, kadalasan dahil puno ang pila;
· r: Isang packet ang natanggap ng net device.
Tingnan natin ang isang mas detalyadong view ng unang linya sa trace file. sisirain ko na
sa mga seksyon (naka-indent para sa kalinawan) na may reference number sa kaliwang bahagi:
+
2
/NodeList/0/DeviceList/0/$ns3::PointToPointNetDevice/TxQueue/Enqueue
ns3::PppHeader (
Point-to-Point Protocol: IP (0x0021))
ns3::Ipv4Header (
tos 0x0 ttl 64 id 0 protocol 17 offset 0 flag [wala]
haba: 1052 10.1.1.1 > 10.1.1.2)
ns3::UdpHeader (
haba: 1032 49153 > 9)
Payload (laki=1024)
Ang unang seksyon ng pinalawak na trace event na ito (reference number 0) ay ang operasyon. Kami
magkaroon ng isang + karakter, kaya tumutugma ito sa isang enqueue operasyon sa transmit queue.
Ang pangalawang seksyon (reference 1) ay ang simulation time na ipinahayag sa mga segundo. Maaari mong
tandaan na tinanong namin ang UdpEchoClientApplication upang simulan ang pagpapadala ng mga packet sa dalawang segundo.
Dito makikita natin ang kumpirmasyon na ito nga ay nangyayari.
Ang susunod na seksyon ng halimbawang bakas (reference 2) ay nagsasabi sa amin kung aling trace ang pinagmulan
ang kaganapang ito (ipinahayag sa tracing namespace). Maaari mong isipin ang pagsubaybay sa namespace
medyo tulad ng gagawin mo sa isang filesystem namespace. Ang ugat ng namespace ay ang
NodeList. Ito ay tumutugma sa isang container na pinamamahalaan sa ns-3 core code na naglalaman ng lahat
ng mga node na nilikha sa isang script. Tulad ng isang filesystem ay maaaring may mga direktoryo
sa ilalim ng ugat, maaaring mayroon tayong mga numero ng node sa NodeList. Ang tali /NodeList/0
samakatuwid ay tumutukoy sa zeroth node sa NodeList na karaniwang iniisip natin bilang "node
0". Sa bawat node ay may listahan ng mga device na na-install. Lumilitaw ang listahang ito
susunod sa namespace. Makikita mong nagmula ang trace event na ito DeviceList/0 na
ang zeroth device na naka-install sa node.
Ang susunod na string, $ns3::PointToPointNetDevice nagsasabi sa iyo kung anong uri ng device ang nasa
zeroth position ng listahan ng device para sa node zero. Alalahanin na ang operasyon + natagpuan sa
reference 00 ay nangangahulugan na ang isang enqueue operation ay nangyari sa transmit queue ng device.
Ito ay makikita sa mga huling bahagi ng "trace path" na TxQueue/Enqueue.
Ang natitirang mga seksyon sa bakas ay dapat na medyo intuitive. Ipinapahiwatig ng mga sanggunian 3-4
na ang packet ay naka-encapsulated sa point-to-point protocol. Ang mga sanggunian 5-7 ay nagpapakita na
ang packet ay may bersyon ng IP apat na header at nagmula sa IP address 10.1.1.1 at
ay nakalaan para sa 10.1.1.2. Ipinapakita ng mga sanggunian 8-9 na ang packet na ito ay may UDP header at,
sa wakas, ipinapakita ng reference 10 na ang payload ay ang inaasahang 1024 bytes.
Ang susunod na linya sa trace file ay nagpapakita ng parehong packet na na-dequeued mula sa transmit
pila sa parehong node.
Ang Ikatlong linya sa trace file ay nagpapakita ng packet na natatanggap ng net device sa
node na may echo server. Ni-reproduce ko ang kaganapang iyon sa ibaba.
r
2.25732
/NodeList/1/DeviceList/0/$ns3::PointToPointNetDevice/MacRx
ns3::Ipv4Header (
tos 0x0 ttl 64 id 0 protocol 17 offset 0 flag [wala]
haba: 1052 10.1.1.1 > 10.1.1.2)
ns3::UdpHeader (
haba: 1032 49153 > 9)
Payload (laki=1024)
Pansinin na ang trace operation ay ngayon r at ang simulation time ay tumaas sa 2.25732
segundo. Kung sinusunod mo nang mabuti ang mga hakbang sa tutorial, nangangahulugan ito na mayroon ka
iniwan ang DataRate ng mga net device at ng channel Pagkaantala itinakda sa kanilang mga default na halaga.
Ang oras na ito ay dapat na pamilyar tulad ng nakita mo ito dati sa isang nakaraang seksyon.
Nagbago ang bakas na source namespace entry (reference 02) upang ipakita na ang kaganapang ito ay
galing sa node 1 (/NodeList/1) at ang packet reception trace source (/MacRx). Ito
dapat ay medyo madali para sa iyo na sundan ang pag-usad ng packet sa pamamagitan ng topology sa pamamagitan ng
tinitingnan ang natitirang mga bakas sa file.
PCAP Pagsubaybay
Ang ns-3 ang mga katulong ng device ay maaari ding gamitin upang lumikha ng mga trace file sa .pcap pormat. Ang
acronym pcap (karaniwang nakasulat sa maliit na titik) ay kumakatawan sa packet capture, at ito ay talagang isang
API na kinabibilangan ng kahulugan ng a .pcap format ng file. Ang pinakasikat na programa na
maaaring basahin at ipakita ang format na ito ay Wireshark (dating tinatawag na Ethereal). Gayunpaman, doon
ay maraming traffic trace analyzer na gumagamit ng packet format na ito. Hinihikayat namin ang mga gumagamit na
samantalahin ang maraming tool na magagamit para sa pagsusuri ng mga bakas ng pcap. Sa tutorial na ito, kami
tumutok sa pagtingin sa mga bakas ng pcap gamit ang tcpdump.
Ang code na ginamit upang paganahin ang pcap tracing ay isang one-liner.
pointToPoint.EnablePcapAll ("myfirst");
Sige at ipasok ang linyang ito ng code pagkatapos ng ASCII tracing code na idinagdag namin
scratch/myfirst.cc. Pansinin na ipinasa lang namin ang string na "myfirst," at hindi
"myfirst.pcap" o katulad nito. Ito ay dahil ang parameter ay isang prefix, hindi a
kumpletong pangalan ng file. Ang katulong ay talagang gagawa ng trace file para sa bawat point-to-point
aparato sa simulation. Ang mga pangalan ng file ay bubuuin gamit ang prefix, ang node number,
ang numero ng device at isang ".pcap" na suffix.
Sa aming halimbawang script, makikita natin ang mga file na pinangalanang "myfirst-0-0.pcap" at
"myfirst-1-0.pcap" na mga bakas ng pcap para sa node 0-device 0 at node 1-device 0,
ayon sa pagkakabanggit.
Kapag naidagdag mo na ang linya ng code upang paganahin ang pcap tracing, maaari mong patakbuhin ang script sa
karaniwang paraan:
$ ./waf --run scratch/myfirst
Kung titingnan mo ang pinakamataas na antas ng direktoryo ng iyong pamamahagi, dapat mo na ngayong makita ang tatlong log
file: myfirst.tr ay ang ASCII trace file na dati naming napagmasdan. myfirst-0-0.pcap
at myfirst-1-0.pcap ay ang mga bagong pcap file na kakagawa lang namin.
Pagbabasa output sa tcpdump
Ang pinakamadaling gawin sa puntong ito ay ang paggamit tcpdump upang tingnan ang pcap file.
$ tcpdump -nn -tt -r myfirst-0-0.pcap
pagbabasa mula sa file myfirst-0-0.pcap, link-type na PPP (PPP)
2.000000 IP 10.1.1.1.49153 > 10.1.1.2.9: UDP, haba 1024
2.514648 IP 10.1.1.2.9 > 10.1.1.1.49153: UDP, haba 1024
tcpdump -nn -tt -r myfirst-1-0.pcap
pagbabasa mula sa file myfirst-1-0.pcap, link-type na PPP (PPP)
2.257324 IP 10.1.1.1.49153 > 10.1.1.2.9: UDP, haba 1024
2.257324 IP 10.1.1.2.9 > 10.1.1.1.49153: UDP, haba 1024
Makikita mo sa tambakan ng myfirst-0-0.pcap (ang client device) na ang echo packet ay
ipinadala sa 2 segundo sa simulation. Kung titingnan mo ang pangalawang dump (myfirst-1-0.pcap)
makikita mo ang packet na natanggap sa 2.257324 segundo. Nakikita mo ang packet
nag-echo pabalik sa 2.257324 segundo sa pangalawang dump, at sa wakas, makikita mo ang packet na
natanggap pabalik sa kliyente sa unang dump sa 2.514648 segundo.
Pagbabasa output sa Wireshark
Kung hindi ka pamilyar sa Wireshark, mayroong isang web site na magagamit kung saan maaari mo
mag-download ng mga programa at dokumentasyon: http://www.wireshark.org/.
Ang Wireshark ay isang graphical na user interface na maaaring magamit para sa pagpapakita ng mga bakas na ito
mga file. Kung mayroon kang available na Wireshark, maaari mong buksan ang bawat isa sa mga trace file at display
ang mga nilalaman na parang nakuha mo ang mga packet gamit ang a packet mas matalino.
Building MGA TOPOLOGIES
gusali a bus network topology
Sa bahaging ito, palalawakin natin ang ating karunungan ns-3 mga device at channel sa network sa
takpan ang isang halimbawa ng isang network ng bus. ns-3 nagbibigay ng net device at channel na tinatawag naming CSMA
(Carrier Sense Multiple Access).
Ang ns-3 Ang CSMA device ay nagmomodelo ng isang simpleng network sa diwa ng Ethernet. Isang tunay na Ethernet
gumagamit ng CSMA/CD (Carrier Sense Multiple Access with Collision Detection) scheme na may
exponentially pagtaas ng backoff upang makipaglaban para sa shared transmission medium. Ang ns-3
Ang CSMA device at mga modelo ng channel ay isang subset lamang nito.
Tulad ng nakita natin na point-to-point topology helper object kapag gumagawa
point-to-point topologies, makikita natin ang katumbas na CSMA topology helpers sa seksyong ito.
Ang hitsura at operasyon ng mga katulong na ito ay dapat mukhang pamilyar sa iyo.
Nagbibigay kami ng halimbawang script sa aming mga halimbawa/tutorial} na direktoryo. Ang script na ito ay binuo
ang una.cc script at nagdaragdag ng network ng CSMA sa point-to-point simulation na mayroon na kami
isinasaalang-alang. Sige at buksan mo mga halimbawa/tutorial/pangalawa.cc sa iyong paboritong editor. Ikaw
sapat na ang nakita ns-3 code upang maunawaan ang karamihan sa kung ano ang nangyayari dito
halimbawa, ngunit susuriin natin ang buong script at susuriin ang ilan sa mga output.
Tulad ng sa una.cc halimbawa (at sa lahat ng mga halimbawa ng ns-3) ang file ay nagsisimula sa isang emacs
mode line at ilang GPL boilerplate.
Ang aktwal na code ay nagsisimula sa pamamagitan ng pag-load ng module kasama ang mga file tulad ng ginawa sa una.cc
Halimbawa.
#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/csma-module.h"
#include "ns3/internet-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/applications-module.h"
#include "ns3/ipv4-global-routing-helper.h"
Ang isang bagay na nakakagulat na kapaki-pakinabang ay isang maliit na piraso ng sining ng ASCII na nagpapakita ng isang cartoon
ng network topology na binuo sa halimbawa. Makakakita ka ng katulad na "pagguhit" sa
karamihan sa ating mga halimbawa.
Sa kasong ito, makikita mo na palawigin namin ang aming point-to-point na halimbawa (ang link
sa pagitan ng mga node n0 at n1 sa ibaba) sa pamamagitan ng pagsasabit ng network ng bus sa kanang bahagi. Pansinin
na ito ang default na topology ng network dahil maaari mo talagang pag-iba-ibahin ang bilang ng mga node
nilikha sa LAN. Kung itatakda mo ang nCsma sa isa, magkakaroon ng kabuuang dalawang node sa
LAN (CSMA channel) --- isang kinakailangang node at isang "dagdag" na node. Bilang default mayroong tatlo
"dagdag" na mga node tulad ng nakikita sa ibaba:
// Default na Topology ng Network
//
// 10.1.1.0
// n0 -------------- n1 n2 n3 n4
// point-to-point | | | |
// =================
// LAN 10.1.2.0
Kung gayon ang ns-3 namespace ay ginamit at isang bahagi ng pag-log ay tinukoy. Ang lahat ng ito ay parang
ito ay sa una.cc, kaya wala pang bago.
gamit ang namespace ns3;
NS_LOG_COMPONENT_DEFINE ("SecondScriptExample");
Ang pangunahing programa ay nagsisimula sa isang bahagyang naiibang twist. Gumagamit kami ng verbose flag sa
matukoy kung o hindi ang UdpEchoClientApplication at UdpEchoServerApplication pagtotroso
pinagana ang mga bahagi. Ang flag na ito ay default sa true (ang mga bahagi ng pag-log ay pinagana)
ngunit nagbibigay-daan sa amin na i-off ang pag-log sa panahon ng pagsubok ng regression ng halimbawang ito.
Makakakita ka ng ilang pamilyar na code na magbibigay-daan sa iyong baguhin ang bilang ng mga device sa
CSMA network sa pamamagitan ng command line argument. May ginawa kaming katulad noong pinayagan namin ang
bilang ng mga packet na ipinadala upang baguhin sa seksyon sa mga argumento ng command line. Ang huli
tinitiyak ng linya na mayroon kang kahit isang "dagdag" na node.
Binubuo ang code ng mga variation ng dating sakop na API kaya dapat ay ganap ka
komportable sa sumusunod na code sa puntong ito sa tutorial.
bool verbose = totoo;
uint32_t nCsma = 3;
CommandLine cmd;
cmd.AddValue ("nCsma", "Bilang ng \"dagdag\" CSMA node/device", nCsma);
cmd.AddValue ("verbose", "Sabihin ang mga echo application na mag-log kung totoo", verbose);
cmd.Parse (argc, argv);
kung (verbose)
{
LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO);
LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO);
}
nCsma = nCsma == 0 ? 1 : nCsma;
Ang susunod na hakbang ay lumikha ng dalawang node na ikokonekta namin sa pamamagitan ng point-to-point na link.
Ang NodeContainer ay ginagamit upang gawin ito tulad ng ginawa sa una.cc.
NodeContainer p2pNodes;
p2pNodes.Create (2);
Susunod, idineklara namin ang isa pa NodeContainer upang hawakan ang mga node na magiging bahagi ng bus
(CSMA) network. Una, ginagawa lang natin ang mismong container object.
NodeContainer csmaNodes;
csmaNodes.Add (p2pNodes.Get (1));
csmaNodes.Create (nCsma);
Ang susunod na linya ng code Ay nakakakuha ang unang node (tulad ng pagkakaroon ng index ng isa) mula sa
point-to-point na lalagyan ng node at idagdag ito sa lalagyan ng mga node na makakakuha ng CSMA
mga device. Ang node na pinag-uusapan ay magtatapos sa isang point-to-point na device at isang CSMA
aparato. Pagkatapos ay lumikha kami ng isang bilang ng mga "dagdag" na node na bumubuo sa natitira sa CSMA
network. Dahil mayroon na tayong isang node sa CSMA network -- ang magkakaroon
parehong point-to-point at CSMA net device, ang bilang ng "dagdag" na mga node ay nangangahulugan ng numero
mga node na gusto mo sa seksyon ng CSMA minus one.
Ang susunod na bit ng code ay dapat na pamilyar na sa ngayon. Namin instantiate a PointToPointHelper
at itakda ang nauugnay na default katangian upang lumikha tayo ng limang megabit bawat segundo
transmitter sa mga device na ginawa gamit ang helper at dalawang millisecond na pagkaantala sa mga channel
nilikha ng katulong.
PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
NetDeviceContainer p2pDevices;
p2pDevices = pointToPoint.Install (p2pNodes);
Pagkatapos ay i-instantiate namin a NetDeviceContainer upang subaybayan ang mga point-to-point net device
at tayo I-install mga device sa point-to-point na mga node.
Nabanggit namin sa itaas na makakakita ka ng katulong para sa mga device at channel ng CSMA, at
ipinakilala sila ng mga susunod na linya. Ang CsmaHelper gumagana tulad ng isang PointToPointHelper, Ngunit
ito ay lumilikha at nagkokonekta ng mga CSMA device at channel. Sa kaso ng isang CSMA device at
channel pair, pansinin na ang data rate ay tinukoy ng a channel katangian sa halip na isang
aparato katangian. Ito ay dahil ang isang tunay na network ng CSMA ay hindi pinapayagan ang isa na maghalo, para sa
halimbawa, 10Base-T at 100Base-T na mga device sa isang partikular na channel. Itinakda muna namin ang rate ng data sa
100 megabits bawat segundo, at pagkatapos ay itakda ang speed-of-light delay ng channel sa 6560
nano-segundo (arbitraryong pinili bilang 1 nanosecond bawat paa sa isang 100 metrong segment).
Pansinin na maaari kang magtakda ng isang katangian gamit ang katutubong uri ng data nito.
CsmaHelper csma;
csma.SetChannelAttribute ("DataRate", StringValue ("100Mbps"));
csma.SetChannelAttribute ("Delay", TimeValue (NanoSeconds (6560)));
NetDeviceContainer csmaDevices;
csmaDevices = csma.Install (csmaNodes);
Tulad ng ginawa natin a NetDeviceContainer para hawakan ang mga device na ginawa ng
PointToPointHelper lumilikha kami ng a NetDeviceContainer para hawakan ang mga device na ginawa ng aming
CsmaHelper. Tinatawag namin ang I-install paraan ng CsmaHelper upang i-install ang mga device sa
mga node ng csmaNodes NodeContainer.
Nagawa na namin ngayon ang aming mga node, device at channel, ngunit wala kaming protocol stack
kasalukuyan. Tulad ng sa una.cc script, gagamitin namin ang InternetStackHelper i-install
mga stack na ito.
InternetStackHelper stack;
stack.Install (p2pNodes.Get (0));
stack.Install (csmaNodes);
Alalahanin na kinuha namin ang isa sa mga node mula sa p2pNode lalagyan at idinagdag ito sa
csmaNodes lalagyan. Kaya kailangan lang nating i-install ang mga stack sa natitira p2pNode
node, at lahat ng node sa csmaNodes lalagyan upang masakop ang lahat ng mga node sa
kunwa
Tulad ng sa una.cc halimbawa ng script, gagamitin namin ang IPv4AddressHelper sa
magtalaga ng mga IP address sa aming mga interface ng device. Una, ginagamit namin ang network 10.1.1.0 upang lumikha
ang dalawang address na kailangan para sa aming dalawang point-to-point na device.
Ipv4AddressHelper address;
address.SetBase ("10.1.1.0", "255.255.255.0");
Ipv4InterfaceContainer p2pInterfaces;
p2pInterfaces = address.Italaga (p2pDevices);
Alalahanin na ini-save namin ang mga ginawang interface sa isang lalagyan upang gawing madali ang pag-pull out
pagtugon sa impormasyon sa ibang pagkakataon para magamit sa pag-set up ng mga application.
Kailangan na naming magtalaga ng mga IP address sa aming mga interface ng CSMA device. Gumagana ang operasyon
tulad ng ginawa nito para sa point-to-point na kaso, maliban kung ginagawa natin ngayon ang operasyon
isang lalagyan na may variable na bilang ng mga CSMA device --- tandaan na ginawa namin ang bilang ng
Ang mga CSMA device ay nababago sa pamamagitan ng command line argument. Iuugnay ang mga CSMA device
na may mga IP address mula sa network number 10.1.2.0 sa kasong ito, tulad ng nakikita sa ibaba.
address.SetBase ("10.1.2.0", "255.255.255.0");
Ipv4InterfaceContainer csmaInterfaces;
csmaInterfaces = address.Assign (csmaDevices);
Ngayon ay mayroon kaming isang topology na binuo, ngunit kailangan namin ng mga application. Ang seksyong ito ay magiging
pangunahing katulad sa seksyon ng mga aplikasyon ng una.cc pero pupunta tayo
i-instantiate ang server sa isa sa mga node na mayroong CSMA device at ang client sa
node na mayroon lamang point-to-point na device.
Una, ise-set up namin ang echo server. Lumilikha kami ng isang UdpEchoServerHelper at magbigay ng kinakailangan
katangian halaga sa tagabuo na siyang numero ng port ng server. Alalahanin na ang port na ito
maaaring baguhin sa ibang pagkakataon gamit ang SetAttribute paraan kung ninanais, ngunit kailangan namin ito
ibinigay sa tagabuo.
UdpEchoServerHelper echoServer (9);
ApplicationContainer serverApps = echoServer.Install (csmaNodes.Get (nCsma));
serverApps.Start (Second (1.0));
serverApps.Stop (Secons (10.0));
Tandaan na ang csmaNodes NodeContainer naglalaman ng isa sa mga node na nilikha para sa
point-to-point network at nCsma "dagdag" na mga node. Ang gusto nating makuha ay ang huli sa
"dagdag" na mga node. Ang zeroth entry ng csmaNodes lalagyan ang magiging point-to-point
node. Ang madaling paraan para isipin ito, kung gayon, ay kung gagawa tayo ng isang "dagdag" na CSMA node, pagkatapos ito
ay nasa index ng isa sa csmaNodes lalagyan. Sa pamamagitan ng induction, kung tayo ay lumikha nCsma "dagdag"
node ang huling isa ay nasa index nCsma. Makikita mo ito na ipinakita sa Magsimula ng una
linya ng code.
Ang application ng kliyente ay naka-set up nang eksakto tulad ng ginawa namin sa una.cc halimbawa ng script. muli,
nagbibigay kami ng kinakailangan katangian sa UdpEchoClientHelper sa constructor (sa kasong ito
ang malayong address at port). Sinasabi namin sa kliyente na magpadala ng mga packet sa server na kami lang
naka-install sa huling ng "dagdag" na mga node ng CSMA. Ini-install namin ang kliyente sa pinakakaliwa
point-to-point node na makikita sa paglalarawan ng topology.
UdpEchoClientHelper echoClient (csmaInterfaces.GetAddress (nCsma), 9);
echoClient.SetAttribute ("MaxPackets", UintegerValue (1));
echoClient.SetAttribute ("Interval", TimeValue (Second (1.0)));
echoClient.SetAttribute ("PacketSize", UintegerValue (1024));
ApplicationContainer clientApps = echoClient.Install (p2pNodes.Get (0));
clientApps.Start (Second (2.0));
clientApps.Stop (Second (10.0));
Dahil talagang nakagawa kami ng isang internetwork dito, kailangan namin ng ilang uri ng internetwork
pagruruta. ns-3 nagbibigay ng tinatawag naming global na pagruruta para tulungan ka. Global routing tumatagal
bentahe ng katotohanan na ang buong internetwork ay naa-access sa simulation at
tumatakbo sa lahat ng mga node na nilikha para sa simulation --- ginagawa nito ang mahirap na trabaho ng
pag-set up ng pagruruta para sa iyo nang hindi kinakailangang i-configure ang mga router.
Karaniwan, ang nangyayari ay ang bawat node ay kumikilos na parang OSPF router iyon
nakikipag-usap kaagad at mahiwagang sa lahat ng iba pang mga router sa likod ng mga eksena. Bawat node
bumubuo ng mga link na advertisement at direktang nakikipag-ugnayan sa mga ito sa isang pandaigdigang tagapamahala ng ruta
na gumagamit ng pandaigdigang impormasyong ito upang bumuo ng mga routing table para sa bawat node. Setting
up ang form na ito ng pagruruta ay isang one-liner:
Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
Susunod, pinagana namin ang pcap tracing. Ang unang linya ng code upang paganahin ang pcap tracing sa
Dapat na pamilyar sa iyo ang point-to-point na katulong sa ngayon. Ang pangalawang linya ay nagbibigay-daan sa pcap
tracing sa CSMA helper at may extra parameter na hindi mo pa na-encounter.
pointToPoint.EnablePcapAll ("pangalawa");
csma.EnablePcap ("pangalawa", csmaDevices.Get (1), true);
Ang network ng CSMA ay isang multi-point-to-point na network. Nangangahulugan ito na mayroong (at nasa
sa kasong ito) maramihang mga endpoint sa isang nakabahaging medium. Ang bawat isa sa mga endpoint na ito ay may net
device na nauugnay dito. Mayroong dalawang pangunahing alternatibo sa pangangalap ng bakas
impormasyon mula sa naturang network. Ang isang paraan ay ang gumawa ng trace file para sa bawat net device
at iimbak lamang ang mga packet na inilalabas o natupok ng net device na iyon. Ibang paraan
ay ang pumili ng isa sa mga device at ilagay ito sa promiscuous mode. Ang nag-iisang device noon
"Sniffs" ang network para sa lahat ng mga packet at iniimbak ang mga ito sa isang solong pcap file. Ganito po
tcpdump, halimbawa, gumagana. Ang huling parameter na iyon ay nagsasabi sa CSMA helper kung gagawin o hindi
ayusin ang pagkuha ng mga packet sa promiscuous mode.
Sa halimbawang ito, pipili tayo ng isa sa mga device sa CSMA network at itatanong ito
upang magsagawa ng isang malaswang pagsinghot ng network, sa gayon ay tinutularan kung ano tcpdump gagawin.
Kung ikaw ay nasa isang Linux machine maaari kang gumawa ng katulad nito tcpdump -i eth0 upang makuha ang
bakas. Sa kasong ito, tinutukoy namin ang device na ginagamit csmaDevices.Get(1), na pumipili ng
unang device sa lalagyan. Ang pagtatakda ng huling parameter sa true ay nagbibigay-daan sa promiscuous
mga kinukuha.
Ang huling seksyon ng code ay tumatakbo at nililinis ang simulation tulad ng una.cc
Halimbawa.
Simulator::Run ();
Simulator:: Wasakin ();
0 bumalik;
}
Upang patakbuhin ang halimbawang ito, kopyahin ang pangalawa.cc halimbawa ng script sa scratch directory
at gumamit ng waf upang bumuo tulad ng ginawa mo sa una.cc halimbawa. Kung ikaw ay nasa
top-level na direktoryo ng repositoryo na tina-type mo lang,
$ cp examples/tutorial/second.cc scratch/mysecond.cc
$ ./waf
Babala: Ginagamit namin ang file pangalawa.cc bilang isa sa aming mga pagsubok sa pagbabalik upang ma-verify na gumagana ito
eksakto tulad ng iniisip namin na dapat gawin upang maging positibo ang iyong karanasan sa tutorial.
Nangangahulugan ito na ang isang executable na pinangalanan pangalawa mayroon na sa proyekto. Upang maiwasan ang anumang
pagkalito tungkol sa kung ano ang iyong isinasagawa, mangyaring gawin ang pagpapalit ng pangalan sa mysecond.cc iminungkahi
sa itaas.
Kung sinusunod mo ang tutorial sa relihiyon (ikaw nga, hindi ba) magkakaroon ka pa rin
ang NS_LOG variable set, kaya sige at i-clear ang variable na iyon at patakbuhin ang program.
$ export NS_LOG=
$ ./waf --run scratch/mysecond
Dahil na-set up namin ang UDP echo applications para mag-log tulad ng ginawa namin una.cc, gagawin mo
makita ang katulad na output kapag pinatakbo mo ang script.
Waf: Pagpasok ng direktoryo `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Umalis sa direktoryo `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Matagumpay na natapos ang 'build' (0.415s)
Nagpadala ng 1024 bytes sa 10.1.2.4
Nakatanggap ng 1024 bytes mula sa 10.1.1.1
Nakatanggap ng 1024 bytes mula sa 10.1.2.4
Alalahanin na ang unang mensahe, "Ipinadala 1024 bytes sa 10.1.2.4," ay ang UDP echo client
pagpapadala ng packet sa server. Sa kasong ito, ang server ay nasa ibang network
(10.1.2.0). Ang pangalawang mensahe, "Natanggap 1024 bytes mula 10.1.1.1," ay mula sa UDP echo
server, na nabuo kapag natanggap nito ang echo packet. Ang huling mensahe, "Natanggap 1024
bytes mula 10.1.2.4," ay mula sa echo client, na nagpapahiwatig na natanggap nito ang echo nito
pabalik mula sa server.
Kung pupunta ka ngayon at tumingin sa direktoryo sa pinakamataas na antas, makikita mo ang tatlong trace file:
second-0-0.pcap second-1-0.pcap second-2-0.pcap
Maglaan tayo ng ilang sandali upang tingnan ang pagpapangalan ng mga file na ito. Lahat sila ay may parehong anyo,
- - .pcap. Halimbawa, ang unang file sa listahan ay
pangalawa-0-0.pcap na kung saan ay ang pcap trace mula sa node zero, device zero. Ito ang
point-to-point net device sa node zero. Ang file pangalawa-1-0.pcap ay ang pcap trace para sa
device zero sa node one, isa ring point-to-point net device; at ang file pangalawa-2-0.pcap is
ang pcap trace para sa device na zero sa node two.
Kung sumangguni ka pabalik sa paglalarawan ng topology sa simula ng seksyon, makikita mo
ang node na zero ay ang pinakakaliwang node ng point-to-point na link at ang node ay ang node
na mayroong parehong point-to-point na device at isang CSMA device. Makikita mo na ang node two ay
ang unang "dagdag" na node sa CSMA network at ang device zero nito ay napili bilang device
para makuha ang promiscuous-mode trace.
Ngayon, sundan natin ang echo packet sa pamamagitan ng internetwork. Una, gawin ang isang tcpdump ng
trace file para sa pinakakaliwang point-to-point node --- node zero.
$ tcpdump -nn -tt -r second-0-0.pcap
Dapat mong makita ang mga nilalaman ng pcap file na ipinapakita:
pagbabasa mula sa file second-0-0.pcap, link-type na PPP (PPP)
2.000000 IP 10.1.1.1.49153 > 10.1.2.4.9: UDP, haba 1024
2.017607 IP 10.1.2.4.9 > 10.1.1.1.49153: UDP, haba 1024
Ang unang linya ng dump ay nagpapahiwatig na ang uri ng link ay PPP (point-to-point) na kami
asahan. Pagkatapos ay makikita mo ang echo packet na umaalis sa node na zero sa pamamagitan ng device na nauugnay sa IP
address 10.1.1.1 patungo sa IP address 10.1.2.4 (ang pinakakanang CSMA node). Ang paketeng ito
lilipat sa point-to-point na link at matatanggap ng point-to-point net device na naka-on
node isa. Tignan natin:
$ tcpdump -nn -tt -r second-1-0.pcap
Dapat mo na ngayong makita ang pcap trace na output ng kabilang panig ng point-to-point na link:
pagbabasa mula sa file second-1-0.pcap, link-type na PPP (PPP)
2.003686 IP 10.1.1.1.49153 > 10.1.2.4.9: UDP, haba 1024
2.013921 IP 10.1.2.4.9 > 10.1.1.1.49153: UDP, haba 1024
Dito makikita natin na ang uri ng link ay PPP din gaya ng inaasahan natin. Nakikita mo ang packet mula sa IP
address 10.1.1.1 (na ipinadala sa 2.000000 segundo) patungo sa IP address 10.1.2.4
lalabas sa interface na ito. Ngayon, sa loob ng node na ito, ang packet ay ipapasa sa
ang interface ng CSMA at dapat nating makita itong lumabas sa device na iyon na patungo sa pinakahuli nito
patutunguhan.
Tandaan na pinili namin ang node 2 bilang ang promiscuous sniffer node para sa CSMA network kaya
tingnan natin ang second-2-0.pcap at tingnan kung nandoon.
$ tcpdump -nn -tt -r second-2-0.pcap
Dapat mo na ngayong makita ang promiscuous dump ng node two, device zero:
pagbabasa mula sa file second-2-0.pcap, link-type EN10MB (Ethernet)
2.007698 ARP, Humiling kung sino ang may 10.1.2.4 (ff:ff:ff:ff:ff:ff) sabihin sa 10.1.2.1, haba 50
2.007710 ARP, Reply 10.1.2.4 is-at 00:00:00:00:00:06, length 50
2.007803 IP 10.1.1.1.49153 > 10.1.2.4.9: UDP, haba 1024
2.013815 ARP, Humiling kung sino ang may 10.1.2.1 (ff:ff:ff:ff:ff:ff) sabihin sa 10.1.2.4, haba 50
2.013828 ARP, Reply 10.1.2.1 is-at 00:00:00:00:00:03, length 50
2.013921 IP 10.1.2.4.9 > 10.1.1.1.49153: UDP, haba 1024
Tulad ng nakikita mo, ang uri ng link ay "Ethernet" na ngayon. May bagong lumitaw, bagaman. Ang
pangangailangan ng network ng bus arp, ang Address Resolution Protocol. Alam ng isang node na kailangan nitong ipadala
ang packet sa IP address 10.1.2.4, ngunit hindi nito alam ang MAC address ng
kaukulang node. Nagbo-broadcast ito sa network ng CSMA (ff:ff:ff:ff:ff:ff) na humihingi ng
device na mayroong IP address 10.1.2.4. Sa kasong ito, ang pinakakanang node ay tumutugon na nagsasabi nito
ay nasa MAC address 00:00:00:00:00:06. Tandaan na ang node two ay hindi direktang kasangkot dito
exchange, ngunit sinisinghot ang network at iniuulat ang lahat ng trapikong nakikita nito.
Ang palitan na ito ay makikita sa mga sumusunod na linya,
2.007698 ARP, Humiling kung sino ang may 10.1.2.4 (ff:ff:ff:ff:ff:ff) sabihin sa 10.1.2.1, haba 50
2.007710 ARP, Reply 10.1.2.4 is-at 00:00:00:00:00:06, length 50
Pagkatapos node one, device one nagpapatuloy at ipapadala ang echo packet sa UDP echo server sa
IP address 10.1.2.4.
2.007803 IP 10.1.1.1.49153 > 10.1.2.4.9: UDP, haba 1024
Natatanggap ng server ang echo request at iniikot ang packet sa sinusubukang ipadala ito pabalik sa
ang pinagmulan. Alam ng server na ang address na ito ay nasa ibang network na naaabot nito sa pamamagitan ng
IP address 10.1.2.1. Ito ay dahil sinimulan namin ang pandaigdigang pagruruta at naisip na nito ang lahat
para sa atin ito. Ngunit, hindi alam ng echo server node ang MAC address ng una
CSMA node, kaya kailangan nitong mag-ARP para dito tulad ng kailangang gawin ng unang CSMA node.
2.013815 ARP, Humiling kung sino ang may 10.1.2.1 (ff:ff:ff:ff:ff:ff) sabihin sa 10.1.2.4, haba 50
2.013828 ARP, Reply 10.1.2.1 is-at 00:00:00:00:00:03, length 50
Pagkatapos ay ipapadala ng server ang echo pabalik sa forwarding node.
2.013921 IP 10.1.2.4.9 > 10.1.1.1.49153: UDP, haba 1024
Sa pagbabalik-tanaw sa pinakakanang node ng point-to-point na link,
$ tcpdump -nn -tt -r second-1-0.pcap
Makikita mo na ngayon ang echoed packet na babalik sa point-to-point na link bilang huli
linya ng trace dump.
pagbabasa mula sa file second-1-0.pcap, link-type na PPP (PPP)
2.003686 IP 10.1.1.1.49153 > 10.1.2.4.9: UDP, haba 1024
2.013921 IP 10.1.2.4.9 > 10.1.1.1.49153: UDP, haba 1024
Panghuli, maaari kang tumingin pabalik sa node na nagmula sa echo
$ tcpdump -nn -tt -r second-0-0.pcap
at makita na ang echoed packet ay bumalik sa pinagmulan sa 2.007602 segundo,
pagbabasa mula sa file second-0-0.pcap, link-type na PPP (PPP)
2.000000 IP 10.1.1.1.49153 > 10.1.2.4.9: UDP, haba 1024
2.017607 IP 10.1.2.4.9 > 10.1.1.1.49153: UDP, haba 1024
Sa wakas, tandaan na idinagdag namin ang kakayahang kontrolin ang bilang ng mga CSMA device sa
simulation sa pamamagitan ng command line argument. Maaari mong baguhin ang argumentong ito sa parehong paraan tulad ng kung kailan
tiningnan namin ang pagbabago ng bilang ng mga packet na echoed sa una.cc halimbawa. Subukan mong tumakbo
ang program na may bilang ng mga "dagdag" na device na nakatakda sa apat:
$ ./waf --run "scratch/mysecond --nCsma=4"
Dapat mong makita ngayon,
Waf: Pagpasok ng direktoryo `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Umalis sa direktoryo `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Matagumpay na natapos ang 'build' (0.405s)
Sa pagkakataong nagpadala ang 2s client ng 1024 bytes sa 10.1.2.5 port 9
Sa oras na nakatanggap ang 2.0118s server ng 1024 bytes mula sa 10.1.1.1 port 49153
Sa oras na nagpadala ang 2.0118s server ng 1024 bytes sa 10.1.1.1 port 49153
Sa oras na nakatanggap ang 2.02461s client ng 1024 bytes mula sa 10.1.2.5 port 9
Pansinin na ang echo server ay inilipat na ngayon sa pinakahuling mga node ng CSMA, na
10.1.2.5 sa halip na ang default na case, 10.1.2.4.
Posibleng hindi ka nasisiyahan sa isang trace file na nabuo ng isang bystander
ang CSMA network. Maaaring gusto mo talagang makakuha ng bakas mula sa isang device at maaaring hindi mo
maging interesado sa anumang iba pang trapiko sa network. Madali mo itong magagawa.
Tingnan natin scratch/mysecond.cc at idagdag ang code na iyon na nagbibigay-daan sa amin na maging higit pa
tiyak. ns-3 Ang mga katulong ay nagbibigay ng mga pamamaraan na kumukuha ng numero ng node at numero ng device bilang
mga parameter. Sige at palitan mo ang Paganahin angPcap mga tawag gamit ang mga tawag sa ibaba.
pointToPoint.EnablePcap ("pangalawa", p2pNodes.Get (0)->GetId (), 0);
csma.EnablePcap ("pangalawa", csmaNodes.Get (nCsma)->GetId (), 0, false);
csma.EnablePcap ("pangalawa", csmaNodes.Get (nCsma-1)->GetId (), 0, false);
Alam namin na gusto naming lumikha ng isang pcap file na may base na pangalan na "pangalawa" at alam din namin
na ang device ng interes sa parehong mga kaso ay magiging zero, kaya ang mga parameter na iyon ay hindi
talagang nakakainteres.
Upang makuha ang numero ng node, mayroon kang dalawang pagpipilian: una, ang mga node ay binibilang sa a
monotonically pagtaas ng fashion simula sa zero sa pagkakasunud-sunod kung saan mo ginawa
sila. Ang isang paraan upang makakuha ng isang node number ay upang malaman ang numerong ito nang "manu-mano" sa pamamagitan ng
pinag-iisipan ang pagkakasunud-sunod ng paglikha ng node. Kung titingnan mo ang topology ng network
paglalarawan sa simula ng file, ginawa namin ito para sa iyo at makikita mo na ang
ang huling CSMA node ay magiging node number nCsma + 1. Ang diskarte na ito ay maaaring maging nakakainis
mahirap sa mas malalaking simulation.
Ang isang alternatibong paraan, na ginagamit namin dito, ay upang mapagtanto na ang Mga NodeContainer may
mga payo sa ns-3 Node Mga bagay. Ang Node Ang bagay ay may tinatawag na pamamaraan GetId kung saan ay
ibalik ang ID ng node na iyon, na siyang numero ng node na hinahanap namin. Tingnan natin ang
Doxygen para sa Node at hanapin ang paraang iyon, na nasa ibaba pa sa ns-3 pangunahing code
kaysa sa nakita natin sa ngayon; ngunit kung minsan kailangan mong maghanap ng masigasig para sa mga kapaki-pakinabang na bagay.
Pumunta sa dokumentasyon ng Doxygen para sa iyong paglabas (tandaan na mahahanap mo ito sa
web site ng proyekto). Makakapunta ka sa Node dokumentasyon sa pamamagitan ng pagtingin sa
"Mga Klase" na tab at pag-scroll pababa sa "Listahan ng Klase" hanggang sa mahanap mo ns3::Node. Piliin
ns3::Node at dadalhin ka sa dokumentasyon para sa Node klase. Kung ikaw ngayon
mag-scroll pababa sa GetId paraan at piliin ito, dadalhin ka sa detalyado
dokumentasyon para sa pamamaraan. Gamit ang GetId paraan ay maaaring gumawa ng pagtukoy ng mga numero ng node
mas madali sa mga kumplikadong topologies.
Alisin natin ang mga lumang trace file mula sa top-level na direktoryo upang maiwasan ang pagkalito tungkol sa
Ano ang nangyayari,
$ rm *.pcap
$ rm *.tr
Kung bubuo ka ng bagong script at patakbuhin ang setting ng simulation nCsma sa 100,
$ ./waf --run "scratch/mysecond --nCsma=100"
makikita mo ang sumusunod na output:
Waf: Pagpasok ng direktoryo `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Umalis sa direktoryo `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Matagumpay na natapos ang 'build' (0.407s)
Sa pagkakataong nagpadala ang 2s client ng 1024 bytes sa 10.1.2.101 port 9
Sa oras na nakatanggap ang 2.0068s server ng 1024 bytes mula sa 10.1.1.1 port 49153
Sa oras na nagpadala ang 2.0068s server ng 1024 bytes sa 10.1.1.1 port 49153
Sa oras na nakatanggap ang 2.01761s client ng 1024 bytes mula sa 10.1.2.101 port 9
Tandaan na ang echo server ay matatagpuan na ngayon sa 10.1.2.101 na tumutugma sa pagkakaroon ng 100
"dagdag" na mga CSMA node na may echo server sa huli. Kung ililista mo ang mga pcap file sa
ang pinakamataas na antas ng direktoryo na makikita mo,
second-0-0.pcap second-100-0.pcap second-101-0.pcap
Ang trace file pangalawa-0-0.pcap ay ang "pinakakaliwa" point-to-point na device na siyang echo
pinagmulan ng pakete. Ang file pangalawa-101-0.pcap tumutugma sa pinakakanang CSMA device na
ay kung saan naninirahan ang echo server. Maaaring napansin mo na ang panghuling parameter sa
Ang tawag upang paganahin ang pcap tracing sa echo server node ay mali. Nangangahulugan ito na ang bakas
natipon sa node na iyon ay nasa non-promiscuous mode.
Upang ilarawan ang pagkakaiba sa pagitan ng promiscuous at non-promiscuous traces, kami rin
ay humiling ng isang hindi promiscuous na bakas para sa susunod na huling node. Sige at tingnan mo
ang tcpdump para pangalawa-100-0.pcap.
$ tcpdump -nn -tt -r second-100-0.pcap
Makikita mo na ngayon na ang node 100 ay talagang isang bystander sa echo exchange. Ang nag-iisang
ang mga packet na natatanggap nito ay ang mga kahilingan sa ARP na ipinapalabas sa buong CSMA
network.
pagbabasa mula sa file second-100-0.pcap, link-type EN10MB (Ethernet)
2.006698 ARP, Humiling kung sino ang may 10.1.2.101 (ff:ff:ff:ff:ff:ff) sabihin sa 10.1.2.1, haba 50
2.013815 ARP, Humiling kung sino ang may 10.1.2.1 (ff:ff:ff:ff:ff:ff) sabihin sa 10.1.2.101, haba 50
Ngayon tingnan ang tcpdump para pangalawa-101-0.pcap.
$ tcpdump -nn -tt -r second-101-0.pcap
Makikita mo na ngayon na ang node 101 ay talagang kalahok sa echo exchange.
pagbabasa mula sa file second-101-0.pcap, link-type EN10MB (Ethernet)
2.006698 ARP, Humiling kung sino ang may 10.1.2.101 (ff:ff:ff:ff:ff:ff) sabihin sa 10.1.2.1, haba 50
2.006698 ARP, Reply 10.1.2.101 is-at 00:00:00:00:00:67, length 50
2.006803 IP 10.1.1.1.49153 > 10.1.2.101.9: UDP, haba 1024
2.013803 ARP, Humiling kung sino ang may 10.1.2.1 (ff:ff:ff:ff:ff:ff) sabihin sa 10.1.2.101, haba 50
2.013828 ARP, Reply 10.1.2.1 is-at 00:00:00:00:00:03, length 50
2.013828 IP 10.1.2.101.9 > 10.1.1.1.49153: UDP, haba 1024
Mga modelo, katangian at Katotohanan
Ito ay isang maginhawang lugar upang gumawa ng isang maliit na iskursiyon at gumawa ng isang mahalagang punto. Maaaring
o maaaring hindi halata sa iyo, ngunit sa tuwing ang isa ay gumagamit ng isang simulation, ito ay mahalaga na
maunawaan nang eksakto kung ano ang ginagawa at kung ano ang hindi. Ito ay nakatutukso, halimbawa, upang
isipin na parang totoo ang mga CSMA device at channel na ginamit sa nakaraang seksyon
Mga aparatong Ethernet; at asahan ang isang resulta ng simulation na direktang sumasalamin sa kung ano ang mangyayari
sa isang tunay na Ethernet. Hindi ito ang kaso.
Ang isang modelo ay, sa pamamagitan ng kahulugan, isang abstraction ng katotohanan. Ito ay sa huli ang responsibilidad
ng may-akda ng simulation script upang matukoy ang tinatawag na "saklaw ng katumpakan" at "domain
of applicability" ng simulation sa kabuuan, at samakatuwid ang mga bahaging bumubuo nito.
Sa ilang mga kaso, tulad ng Csma, maaari itong maging medyo madali upang matukoy kung ano ang hindi namodelo. Sa pamamagitan ng
pagbabasa ng paglalarawan ng modelo (csma.h) maaari mong makita na walang pagtuklas ng banggaan
sa modelo ng CSMA at magpasya kung gaano naaangkop ang paggamit nito sa iyong simulation o ano
mga caveat na maaaring gusto mong isama sa iyong mga resulta. Sa ibang mga kaso, maaari itong maging madali
upang i-configure ang mga pag-uugali na maaaring hindi sumasang-ayon sa anumang katotohanan na maaari kang lumabas at bumili. Ito
ay magpapatunay na kapaki-pakinabang na gumugol ng ilang oras sa pagsisiyasat ng ilang mga ganitong pagkakataon, at kung paano
madali kang makalihis sa labas ng mga hangganan ng katotohanan sa iyong mga simulation.
Tulad ng iyong nakita, ns-3 nagbibigay ng katangian na madaling itakda ng isang user upang baguhin ang modelo
pag-uugali. Isaalang-alang ang dalawa sa katangian ng CsmaNetDevice: Mtu at
EncapsulationMode. ang Mtu ipinahihiwatig ng attribute ang Maximum Transmission Unit sa
aparato. Ito ang laki ng pinakamalaking Protocol Data Unit (PDU) na kaya ng device
ipadala.
Nagde-default ang MTU sa 1500 bytes sa CsmaNetDevice. Ang default na ito ay tumutugma sa isang numero
matatagpuan sa RFC 894, "Isang Pamantayan para sa Pagpapadala ng mga IP Datagram sa Ethernet
Networks." Ang numero ay talagang hinango mula sa maximum na laki ng packet para sa 10Base5
(full-spec Ethernet) na mga network -- 1518 bytes. Kung ibawas mo ang DIX encapsulation
overhead para sa mga Ethernet packet (18 bytes) magkakaroon ka ng maximum na posibleng laki ng data
(MTU) ng 1500 bytes. Maaari ding mahanap ng isa na ang MTU para sa IEEE 802.3 network ay 1492
byte. Ito ay dahil ang LLC/SNAP encapsulation ay nagdaragdag ng dagdag na walong byte ng overhead sa
ang pakete. Sa parehong mga kaso, ang pinagbabatayan na hardware ay maaari lamang magpadala ng 1518 byte, ngunit ang data
iba ang sukat.
Upang maitakda ang encapsulation mode, ang CsmaNetDevice nagbibigay ng isang katangian tinatawag
EncapsulationMode na maaaring tumagal sa mga halaga Dix or LLC. Ang mga ito ay tumutugma sa Ethernet
at LLC/SNAP framing ayon sa pagkakabanggit.
Kung ang isa ay umalis sa Mtu sa 1500 bytes at binabago ang encapsulation mode sa LLC, ang resulta
ay magiging isang network na sumasaklaw sa 1500 byte na mga PDU na may LLC/SNAP framing na nagreresulta sa
mga packet na 1526 bytes, na magiging ilegal sa maraming network, dahil maaari silang magpadala ng a
maximum na 1518 bytes bawat packet. Ito ay malamang na magreresulta sa isang simulation na
medyo banayad na hindi sumasalamin sa katotohanan na maaari mong inaasahan.
Para lang gawing kumplikado ang larawan, mayroong mga jumbo frame (1500 < MTU <= 9000 bytes) at
super-jumbo (MTU > 9000 bytes) na mga frame na hindi opisyal na pinapahintulutan ng IEEE ngunit
magagamit sa ilang high-speed (Gigabit) network at NIC. Maaaring iwanan ng isa ang
nakatakda ang encapsulation mode sa Dix, at itakda ang Mtu katangian sa isang CsmaNetDevice sa 64000 bytes
-- kahit na isang nauugnay CsmaChannel DataRate ay nakatakda sa 10 megabits bawat segundo. Ito
ay mahalagang magmomodelo ng Ethernet switch na gawa sa vampire-tapped 1980s-style na 10Base5
mga network na sumusuporta sa super-jumbo datagrams. Ito ay tiyak na hindi isang bagay na noon
kailanman ginawa, o malamang na gagawin, ngunit medyo madali para sa iyo na i-configure.
Sa nakaraang halimbawa, ginamit mo ang command line para gumawa ng simulation na mayroong 100
Csma mga node. Madali kang gumawa ng simulation na may 500 node. kung ikaw
ay aktwal na nagmomodelo ng 10Base5 vampire-tap network na iyon, ang maximum na haba ng isang full-spec
Ang Ethernet cable ay 500 metro, na may minimum na tap spacing na 2.5 metro. Ibig sabihin doon
maaaring 200 tap lang sa totoong network. Madali kang nakagawa ng ilegal
network sa ganoong paraan din. Ito ay maaaring magresulta o hindi sa isang makabuluhang simulation
depende sa kung ano ang sinusubukan mong i-modelo.
Ang mga katulad na sitwasyon ay maaaring mangyari sa maraming lugar sa ns-3 at sa anumang simulator. Halimbawa,
maaari mong iposisyon ang mga node sa paraang sinasakop nila ang parehong espasyo sa
parehong oras, o maaari mong i-configure ang mga amplifier o mga antas ng ingay na lumalabag sa
pangunahing batas ng pisika.
ns-3 sa pangkalahatan ay pinapaboran ang kakayahang umangkop, at maraming mga modelo ang magbibigay-daan sa malayang pagtatakda katangian
nang hindi sinusubukang ipatupad ang anumang di-makatwirang pagkakapare-pareho o partikular na pinagbabatayan na detalye.
Ang bagay na maiuuwi mula rito ay iyon ns-3 ay magbibigay ng super-flexible na base
para mag-eksperimento ka. Nasa sa iyo na maunawaan kung ano ang iyong hinihiling sa sistema
gawin at siguraduhin na ang mga simulation na iyong nilikha ay may ilang kahulugan at ilang
koneksyon sa isang realidad na tinukoy mo.
gusali a wireless network topology
Sa bahaging ito ay higit nating palalawakin ang ating kaalaman sa ns-3 mga aparato sa network at
channel upang masakop ang isang halimbawa ng isang wireless network. ns-3 nagbibigay ng isang set ng 802.11 na mga modelo
na pagtatangkang magbigay ng tumpak na pagpapatupad sa antas ng MAC ng 802.11 na detalye
at isang "not-so-slow" na modelo sa antas ng PHY ng 802.11a na detalye.
Tulad ng nakita natin ang parehong point-to-point at CSMA topology helper object kapag
pagbuo ng point-to-point topologies, makikita natin ang katumbas WiFi topology helpers sa
ang seksyon na ito. Ang hitsura at operasyon ng mga katulong na ito ay dapat magmukhang pamilyar
iyo.
Nagbibigay kami ng halimbawang script sa aming mga halimbawa/tutorial direktoryo. Ang script na ito ay binuo
ang pangalawa.cc script at nagdagdag ng Wifi network. Sige at buksan mo
mga halimbawa/tutorial/third.cc sa iyong paboritong editor. Sapat na ang nakita mo
ns-3 code upang maunawaan ang karamihan sa kung ano ang nangyayari sa halimbawang ito, ngunit may ilang mga bago
bagay, kaya tatalakayin natin ang buong script at susuriin ang ilan sa mga output.
Tulad ng sa pangalawa.cc halimbawa (at sa lahat ns-3 mga halimbawa) ang file ay nagsisimula sa isang emacs
mode line at ilang GPL boilerplate.
Tingnan ang ASCII art (reproduced sa ibaba) na nagpapakita ng default na topology ng network
binuo sa halimbawa. Makikita mo na mas palalawakin pa namin ang aming halimbawa
sa pamamagitan ng pagsasabit ng wireless network sa kaliwang bahagi. Pansinin na ito ay isang default na network
topology dahil maaari mong aktwal na pag-iba-iba ang bilang ng mga node na nilikha sa wired at wireless
mga network. Tulad ng sa pangalawa.cc kaso ng script, kung babaguhin mo nCsma, ito ay magbibigay sa iyo ng isang
bilang ng mga "dagdag" na CSMA node. Katulad nito, maaari mong itakda nWifi para makontrol kung ilan STA
(istasyon) node ay nilikha sa simulation. Laging magkakaroon ng isa AP (access point)
node sa wireless network. Bilang default, mayroong tatlong "dagdag" na CSMA node at tatlo
wireless STA mga node.
Nagsisimula ang code sa pamamagitan ng pag-load ng module kasama ang mga file tulad ng ginawa sa pangalawa.cc Halimbawa.
Mayroong ilang mga bagong kasama na naaayon sa Wifi module at sa mobility
modyul na tatalakayin natin sa ibaba.
#include "ns3/core-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/network-module.h"
#include "ns3/applications-module.h"
#include "ns3/wifi-module.h"
#include "ns3/mobility-module.h"
#include "ns3/csma-module.h"
#include "ns3/internet-module.h"
Ang paglalarawan ng topolohiya ng network ay sumusunod:
// Default na Topology ng Network
//
// Wifi 10.1.3.0
// AP
// * * * *
// | | | | 10.1.1.0
// n5 n6 n7 n0 -------------- n1 n2 n3 n4
// point-to-point | | | |
// =================
// LAN 10.1.2.0
Makikita mo na nagdaragdag kami ng bagong network device sa node sa kaliwang bahagi ng
point-to-point na link na nagiging access point para sa wireless network. Ang isang bilang ng
Ang mga wireless STA node ay nilikha upang punan ang bagong 10.1.3.0 network tulad ng ipinapakita sa kaliwa
gilid ng ilustrasyon.
Pagkatapos ng ilustrasyon, ang ns-3 namespace ay ginamit at isang bahagi ng pag-log ay tinukoy.
Dapat ay pamilyar na ang lahat sa ngayon.
gamit ang namespace ns3;
NS_LOG_COMPONENT_DEFINE ("ThirdScriptExample");
Ang pangunahing programa ay nagsisimula tulad ng pangalawa.cc sa pamamagitan ng pagdaragdag ng ilang mga parameter ng command line para sa
pagpapagana o hindi pagpapagana ng mga bahagi ng pag-log at para sa pagbabago ng bilang ng mga device na ginawa.
bool verbose = totoo;
uint32_t nCsma = 3;
uint32_t nWifi = 3;
CommandLine cmd;
cmd.AddValue ("nCsma", "Bilang ng \"dagdag\" CSMA node/device", nCsma);
cmd.AddValue ("nWifi", "Bilang ng wifi STA device", nWifi);
cmd.AddValue ("verbose", "Sabihin ang mga echo application na mag-log kung totoo", verbose);
cmd.Parse (argc,argv);
kung (verbose)
{
LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO);
LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO);
}
Tulad ng sa lahat ng mga naunang halimbawa, ang susunod na hakbang ay ang lumikha ng dalawang node na gagawin natin
kumonekta sa pamamagitan ng point-to-point na link.
NodeContainer p2pNodes;
p2pNodes.Create (2);
Susunod, nakita namin ang isang matandang kaibigan. Namin instantiate a PointToPointHelper at itakda ang nauugnay
default katangian upang lumikha kami ng limang megabit bawat segundo na transmiter sa mga device
ginawa gamit ang helper at dalawang millisecond na pagkaantala sa mga channel na ginawa ng helper.
Kami pagkatapos Intall ang mga device sa mga node at ang channel sa pagitan ng mga ito.
PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
NetDeviceContainer p2pDevices;
p2pDevices = pointToPoint.Install (p2pNodes);
Susunod, idineklara namin ang isa pa NodeContainer upang hawakan ang mga node na magiging bahagi ng bus
(CSMA) network.
NodeContainer csmaNodes;
csmaNodes.Add (p2pNodes.Get (1));
csmaNodes.Create (nCsma);
Ang susunod na linya ng code Ay nakakakuha ang unang node (tulad ng pagkakaroon ng index ng isa) mula sa
point-to-point na lalagyan ng node at idagdag ito sa lalagyan ng mga node na makakakuha ng CSMA
mga device. Ang node na pinag-uusapan ay magtatapos sa isang point-to-point na device at isang CSMA
aparato. Pagkatapos ay lumikha kami ng isang bilang ng mga "dagdag" na node na bumubuo sa natitira sa CSMA
network.
Pagkatapos ay i-instantiate namin a CsmaHelper at itakda ang katangian tulad ng ginawa natin sa nakaraang halimbawa.
Lumilikha kami ng a NetDeviceContainer para masubaybayan ang mga nilikhang CSMA net device at pagkatapos ay kami
I-install Mga CSMA device sa mga napiling node.
CsmaHelper csma;
csma.SetChannelAttribute ("DataRate", StringValue ("100Mbps"));
csma.SetChannelAttribute ("Delay", TimeValue (NanoSeconds (6560)));
NetDeviceContainer csmaDevices;
csmaDevices = csma.Install (csmaNodes);
Susunod, gagawa kami ng mga node na magiging bahagi ng Wifi network. Tayo ay
lilikha ng isang bilang ng mga "istasyon" na node gaya ng tinukoy ng argumento ng command line, at
gagamitin natin ang "kaliwa" na node ng point-to-point na link bilang node para sa
access point.
NodeContainer wifiStaNodes;
wifiStaNodes.Create (nWifi);
NodeContainer wifiApNode = p2pNodes.Get (0);
Ang susunod na bit ng code ay bumubuo ng mga wifi device at ang interconnection channel sa pagitan
itong mga wifi node. Una, kino-configure namin ang PHY at mga channel helper:
YansWifiChannelHelper channel = YansWifiChannelHelper::Default ();
YansWifiPhyHelper phy = YansWifiPhyHelper::Default ();
Para sa pagiging simple, ginagamit ng code na ito ang default na configuration ng layer ng PHY at mga modelo ng channel
na nakadokumento sa dokumentasyon ng doxygen ng API para sa
YansWifiChannelHelper::Default at YansWifiPhyHelper::Default paraan. Kapag ang mga bagay na ito
ay nilikha, gumawa kami ng channel object at iniuugnay ito sa aming PHY layer object manager
upang matiyak na ang lahat ng mga bagay sa layer ng PHY na nilikha ng YansWifiPhyHelper ibahagi ang
parehong pinagbabatayan na channel, iyon ay, sila ay nagbabahagi ng parehong wireless medium at maaari
komunikasyon at makagambala:
phy.SetChannel (channel.Create ());
Kapag na-configure na ang helper ng PHY, maaari tayong tumuon sa layer ng MAC. Dito namin pinipiling magtrabaho
na may mga non-Qos MAC kaya gumagamit kami ng isang bagay na NqosWifiMacHelper upang magtakda ng mga parameter ng MAC.
WifiHelper wifi = WifiHelper::Default ();
wifi.SetRemoteStationManager ("ns3::AarfWifiManager");
NqosWifiMacHelper mac = NqosWifiMacHelper::Default ();
Ang SetRemoteStationManager paraan ay nagsasabi sa helper ang uri ng rate control algorithm sa
gamitin. Dito, hinihiling nito sa katulong na gamitin ang AARF algorithm --- ang mga detalye, siyempre,
magagamit sa Doxygen.
Susunod, i-configure namin ang uri ng MAC, ang SSID ng network ng imprastraktura na gusto namin
setup at tiyaking hindi nagsasagawa ng aktibong probing ang aming mga istasyon:
Ssid ssid = Ssid ("ns-3-ssid");
mac.SetType ("ns3::StaWifiMac",
"Ssid", SsidValue (ssid),
"ActiveProbing", BooleanValue (false));
Ang code na ito ay unang gumagawa ng 802.11 service set identifier (SSID) object na gagamitin
upang itakda ang halaga ng "Ssid" katangian ng pagpapatupad ng MAC layer. Ang partikular
uri ng MAC layer na gagawin ng helper ay tinukoy ng katangian bilang ng
ang uri ng "ns3::StaWifiMac". Ang gamit ng NqosWifiMacHelper titiyakin na ang
"QosSupported" katangian para sa mga nilikhang MAC object ay nakatakdang false. Ang kumbinasyon ng mga ito
nangangahulugan ang dalawang configuration na ang MAC instance na susunod na gagawin ay isang non-QoS non-AP
istasyon (STA) sa isang imprastraktura BSS (ibig sabihin, isang BSS na may AP). Sa wakas, ang
"ActiveProbing" katangian ay nakatakda sa false. Nangangahulugan ito na ang mga kahilingan sa pagsisiyasat ay hindi magiging
ipinadala ng mga MAC na nilikha ng katulong na ito.
Kapag ganap nang na-configure ang lahat ng mga parameter na partikular sa istasyon, pareho sa MAC at PHY
layers, maaari naming tawagan ang aming pamilyar na ngayon I-install paraan upang lumikha ng mga wifi device ng mga ito
mga istasyon:
NetDeviceContainer staDevices;
staDevices = wifi.Install (phy, mac, wifiStaNodes);
Na-configure namin ang Wifi para sa lahat ng aming mga STA node, at ngayon kailangan naming i-configure ang AP
(access point) node. Sinisimulan namin ang prosesong ito sa pamamagitan ng pagbabago ng default katangian ng
NqosWifiMacHelper upang ipakita ang mga kinakailangan ng AP.
mac.SetType ("ns3::ApWifiMac",
"Ssid", SsidValue (ssid));
Sa kasong ito, ang NqosWifiMacHelper ay gagawa ng mga MAC layer ng "ns3::ApWifiMac",
ang huli ay tumutukoy na ang isang MAC instance na na-configure bilang isang AP ay dapat gawin, na may
uri ng helper na nagpapahiwatig na ang "QosSupported" katangian dapat itakda sa false - hindi pagpapagana
802.11e/WMM-style QoS support sa mga ginawang AP.
Ang mga susunod na linya ay lumikha ng nag-iisang AP na nagbabahagi ng parehong hanay ng antas ng PHY katangian (At
channel) bilang mga istasyon:
NetDeviceContainer apDevices;
apDevices = wifi.Install (phy, mac, wifiApNode);
Ngayon, magdaragdag kami ng mga modelo ng kadaliang kumilos. Gusto naming maging mobile ang mga STA node, gumagala
sa loob ng isang bounding box, at gusto naming gawing nakatigil ang AP node. Ginagamit namin ang
MobilityHelper para maging madali ito para sa atin. Una, i-instantiate namin a MobilityHelper bagay
at magtakda ng ilan katangian pagkontrol sa functionality na "position allocator".
MobilityHelper mobility;
mobility.SetPositionAllocator ("ns3::GridPositionAllocator",
"MinX", DoubleValue (0.0),
"MinY", DoubleValue (0.0),
"DeltaX", DoubleValue (5.0),
"DeltaY", DoubleValue (10.0),
"GridWidth", UintegerValue (3),
"LayoutType", StringValue ("RowFirst"));
Ang code na ito ay nagsasabi sa mobility helper na gumamit ng two-dimensional grid upang unang ilagay ang
Mga STA node. Huwag mag-atubiling galugarin ang Doxygen para sa klase ns3::GridPositionAllocator upang makita
eksakto kung ano ang ginagawa.
Inayos namin ang aming mga node sa isang paunang grid, ngunit ngayon kailangan naming sabihin sa kanila kung paano lumipat.
Pinipili namin ang RandomWalk2dMobilityModel na kung saan ang mga node ay gumagalaw sa isang random na direksyon sa
isang random na bilis sa paligid sa loob ng isang bounding box.
mobility.SetMobilityModel ("ns3::RandomWalk2dMobilityModel",
"Bounds", RectangleValue (Rectangle (-50, 50, -50, 50)));
Sinasabi namin ngayon ang MobilityHelper upang i-install ang mga modelo ng kadaliang kumilos sa mga STA node.
mobility.Install (wifiStaNodes);
Gusto naming manatili ang access point sa isang nakapirming posisyon sa panahon ng simulation. Kami
magawa ito sa pamamagitan ng pagtatakda ng modelo ng kadaliang kumilos para sa node na ito na maging ang
ns3::ConstantPositionMobilityModel:
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (wifiApNode);
Nagawa na namin ang aming mga node, device at channel, at mga modelo ng mobility na napili para sa
Mga Wifi node, ngunit wala kaming mga protocol stack. Gaya ng marami na nating nagawa dati
beses, gagamitin natin ang InternetStackHelper upang i-install ang mga stack na ito.
InternetStackHelper stack;
stack.Install (csmaNodes);
stack.Install (wifiApNode);
stack.Install (wifiStaNodes);
Tulad ng sa pangalawa.cc halimbawa ng script, gagamitin namin ang IPv4AddressHelper sa
magtalaga ng mga IP address sa aming mga interface ng device. Una, ginagamit namin ang network 10.1.1.0 upang lumikha
ang dalawang address na kailangan para sa aming dalawang point-to-point na device. Pagkatapos ay ginagamit namin ang network 10.1.2.0
upang magtalaga ng mga address sa network ng CSMA at pagkatapos ay magtalaga kami ng mga address mula sa network 10.1.3.0
sa parehong mga STA device at ang AP sa wireless network.
Ipv4AddressHelper address;
address.SetBase ("10.1.1.0", "255.255.255.0");
Ipv4InterfaceContainer p2pInterfaces;
p2pInterfaces = address.Italaga (p2pDevices);
address.SetBase ("10.1.2.0", "255.255.255.0");
Ipv4InterfaceContainer csmaInterfaces;
csmaInterfaces = address.Assign (csmaDevices);
address.SetBase ("10.1.3.0", "255.255.255.0");
address.Italaga (staDevices);
address.Magtalaga (apDevices);
Inilalagay namin ang echo server sa "pinakakanan" na node sa ilustrasyon sa simula ng
file. Nagawa na namin ito dati.
UdpEchoServerHelper echoServer (9);
ApplicationContainer serverApps = echoServer.Install (csmaNodes.Get (nCsma));
serverApps.Start (Second (1.0));
serverApps.Stop (Secons (10.0));
At inilagay namin ang echo client sa huling STA node na ginawa namin, itinuro ito sa server na naka-on
ang CSMA network. Nakakita na rin tayo ng mga katulad na operasyon noon.
UdpEchoClientHelper echoClient (csmaInterfaces.GetAddress (nCsma), 9);
echoClient.SetAttribute ("MaxPackets", UintegerValue (1));
echoClient.SetAttribute ("Interval", TimeValue (Second (1.0)));
echoClient.SetAttribute ("PacketSize", UintegerValue (1024));
ApplicationContainer clientApps =
echoClient.Install (wifiStaNodes.Get (nWifi - 1));
clientApps.Start (Second (2.0));
clientApps.Stop (Second (10.0));
Dahil nakagawa kami ng isang internetwork dito, kailangan naming paganahin ang pagruruta ng internetwork tulad ng
ginawa namin sa pangalawa.cc halimbawa ng script.
Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
Ang isang bagay na maaaring sorpresa sa ilang mga gumagamit ay ang katotohanan na ang simulation na ginawa namin
hindi kailanman "natural" na titigil. Ito ay dahil tinanong namin ang wireless access point
bumuo ng mga beacon. Bubuo ito ng mga beacon magpakailanman, at magreresulta ito sa simulator
mga kaganapang nakaiskedyul sa hinaharap nang walang katiyakan, kaya dapat nating sabihin sa simulator na huminto
kahit na maaaring mayroon itong mga kaganapan sa pagbuo ng beacon na naka-iskedyul. Ang sumusunod na linya ng code
nagsasabi sa simulator na huminto upang hindi natin gayahin ang mga beacon magpakailanman at ilagay kung ano ang
mahalagang isang walang katapusang loop.
Simulator::Stop (Segundo (10.0));
Lumilikha kami ng sapat na pagsubaybay upang masakop ang lahat ng tatlong network:
pointToPoint.EnablePcapAll ("ikatlo");
phy.EnablePcap ("ikatlo", apDevices.Get (0));
csma.EnablePcap ("ikatlo", csmaDevices.Get (0), true);
Ang tatlong linya ng code na ito ay magsisimula ng pcap tracing sa parehong point-to-point na mga node na iyon
nagsisilbing aming backbone, magsisimula ng promiscuous (monitor) mode trace sa Wifi network,
at magsisimula ng promiscuous trace sa CSMA network. Ito ay magbibigay-daan sa amin na makita ang lahat ng
trapiko na may pinakamababang bilang ng mga trace file.
Sa wakas, talagang pinapatakbo namin ang simulation, linisin at pagkatapos ay lumabas sa programa.
Simulator::Run ();
Simulator:: Wasakin ();
0 bumalik;
}
Upang patakbuhin ang halimbawang ito, kailangan mong kopyahin ang pangatlo.cc halimbawa ng script sa
scratch directory at gamitin ang Waf upang bumuo tulad ng ginawa mo sa pangalawa.cc halimbawa. kung ikaw
ay nasa top-level na direktoryo ng repositoryo na iyong ita-type,
$ cp examples/tutorial/third.cc scratch/mythird.cc
$ ./waf
$ ./waf --run scratch/mythird
Muli, dahil nai-set up namin ang mga aplikasyon ng UDP echo tulad ng ginawa namin sa pangalawa.cc
script, makikita mo ang katulad na output.
Waf: Pagpasok ng direktoryo `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Umalis sa direktoryo `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Matagumpay na natapos ang 'build' (0.407s)
Sa pagkakataong nagpadala ang 2s client ng 1024 bytes sa 10.1.2.4 port 9
Sa oras na nakatanggap ang 2.01796s server ng 1024 bytes mula sa 10.1.3.3 port 49153
Sa oras na nagpadala ang 2.01796s server ng 1024 bytes sa 10.1.3.3 port 49153
Sa oras na nakatanggap ang 2.03364s client ng 1024 bytes mula sa 10.1.2.4 port 9
Alalahanin na ang unang mensahe, Ipinadala 1024 bytes sa 10.1.2.4," ay ang UDP echo client
pagpapadala ng packet sa server. Sa kasong ito, ang kliyente ay nasa wireless network
(10.1.3.0). Ang pangalawang mensahe, "Natanggap 1024 bytes mula 10.1.3.3," ay mula sa UDP echo
server, na nabuo kapag natanggap nito ang echo packet. Ang huling mensahe, "Natanggap 1024
bytes mula 10.1.2.4," ay mula sa echo client, na nagpapahiwatig na natanggap nito ang echo nito
pabalik mula sa server.
Kung pupunta ka ngayon at titingin sa direktoryo sa pinakamataas na antas, makakahanap ka ng apat na trace file mula sa
ang simulation na ito, dalawa mula sa node zero at dalawa mula sa node isa:
third-0-0.pcap third-0-1.pcap third-1-0.pcap third-1-1.pcap
Ang file na "third-0-0.pcap" ay tumutugma sa point-to-point na device sa node zero -- ang
kaliwang bahagi ng "backbone". Ang file na "third-1-0.pcap" ay tumutugma sa point-to-point
device sa node one -- ang kanang bahagi ng "backbone". Ang file na "third-0-1.pcap" ay magiging
ang promiscuous (monitor mode) trace mula sa Wifi network at ang file na "third-1-1.pcap"
ang magiging promiscuous trace mula sa CSMA network. Maaari mo bang i-verify ito sa pamamagitan ng pag-inspeksyon
ang code?
Dahil ang echo client ay nasa Wifi network, magsimula tayo doon. Tingnan natin ang
promiscuous (monitor mode) trace na nakunan namin sa network na iyon.
$ tcpdump -nn -tt -r third-0-1.pcap
Dapat kang makakita ng ilang content na mukhang wifi na hindi mo pa nakikita dito dati:
pagbabasa mula sa file third-0-1.pcap, link-type na IEEE802_11 (802.11)
0.000025 Beacon (ns-3-ssid) [6.0* 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit] IBSS
0.000308 Assoc Request (ns-3-ssid) [6.0 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit]
0.000324 Acknowledgment RA:00:00:00:00:00:08
0.000402 Assoc Response AID(0) :: Matagumpay
0.000546 Acknowledgment RA:00:00:00:00:00:0a
0.000721 Assoc Request (ns-3-ssid) [6.0 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit]
0.000737 Acknowledgment RA:00:00:00:00:00:07
0.000824 Assoc Response AID(0) :: Matagumpay
0.000968 Acknowledgment RA:00:00:00:00:00:0a
0.001134 Assoc Request (ns-3-ssid) [6.0 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit]
0.001150 Acknowledgment RA:00:00:00:00:00:09
0.001273 Assoc Response AID(0) :: Matagumpay
0.001417 Acknowledgment RA:00:00:00:00:00:0a
0.102400 Beacon (ns-3-ssid) [6.0* 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit] IBSS
0.204800 Beacon (ns-3-ssid) [6.0* 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit] IBSS
0.307200 Beacon (ns-3-ssid) [6.0* 9.0 12.0 18.0 24.0 36.0 48.0 54.0 Mbit] IBSS
Makikita mo na ang uri ng link ay 802.11 na gaya ng inaasahan mo. Malamang kaya mo
maunawaan kung ano ang nangyayari at hanapin ang IP echo request at response packets dito
bakas. Iniiwan namin ito bilang isang ehersisyo upang ganap na ma-parse ang trace dump.
Ngayon, tingnan ang pcap file sa kanang bahagi ng point-to-point na link,
$ tcpdump -nn -tt -r third-0-0.pcap
Muli, dapat mong makita ang ilang pamilyar na hitsura ng mga nilalaman:
pagbabasa mula sa file third-0-0.pcap, link-type na PPP (PPP)
2.008151 IP 10.1.3.3.49153 > 10.1.2.4.9: UDP, haba 1024
2.026758 IP 10.1.2.4.9 > 10.1.3.3.49153: UDP, haba 1024
Ito ang echo packet mula kaliwa pakanan (mula Wifi hanggang CSMA) at pabalik sa kabila
ang point-to-point na link.
Ngayon, tingnan ang pcap file sa kanang bahagi ng point-to-point na link,
$ tcpdump -nn -tt -r third-1-0.pcap
Muli, dapat mong makita ang ilang pamilyar na hitsura ng mga nilalaman:
pagbabasa mula sa file third-1-0.pcap, link-type na PPP (PPP)
2.011837 IP 10.1.3.3.49153 > 10.1.2.4.9: UDP, haba 1024
2.023072 IP 10.1.2.4.9 > 10.1.3.3.49153: UDP, haba 1024
Ito rin ang echo packet mula kaliwa hanggang kanan (mula Wifi hanggang CSMA) at pabalik muli
sa kabuuan ng point-to-point na link na may bahagyang magkakaibang mga timing gaya ng maaari mong asahan.
Ang echo server ay nasa CSMA network, tingnan natin ang promiscuous trace doon:
$ tcpdump -nn -tt -r third-1-1.pcap
Dapat mong makita ang ilang pamilyar na hitsura ng nilalaman:
pagbabasa mula sa file third-1-1.pcap, link-type EN10MB (Ethernet)
2.017837 ARP, Humiling kung sino ang may 10.1.2.4 (ff:ff:ff:ff:ff:ff) sabihin sa 10.1.2.1, haba 50
2.017861 ARP, Reply 10.1.2.4 is-at 00:00:00:00:00:06, length 50
2.017861 IP 10.1.3.3.49153 > 10.1.2.4.9: UDP, haba 1024
2.022966 ARP, Humiling kung sino ang may 10.1.2.1 (ff:ff:ff:ff:ff:ff) sabihin sa 10.1.2.4, haba 50
2.022966 ARP, Reply 10.1.2.1 is-at 00:00:00:00:00:03, length 50
2.023072 IP 10.1.2.4.9 > 10.1.3.3.49153: UDP, haba 1024
Ito ay dapat na madaling maunawaan. Kung nakalimutan mo, bumalik at tingnan ang talakayan
in pangalawa.cc. Ito ay ang parehong pagkakasunod-sunod.
Ngayon, gumugol kami ng maraming oras sa pag-set up ng mga modelo ng kadaliang kumilos para sa wireless network at gayon din
nakakahiyang tapusin nang hindi man lang ipinapakita na ang mga STA node ay talagang gumagalaw
sa paligid sa panahon ng simulation. Gawin natin ito sa pamamagitan ng pag-hook sa MobilityModel kurso
baguhin ang trace source. Ito ay isang sneak peek lamang sa detalyadong tracing section which is
paparating na, ngunit ito ay tila isang napakagandang lugar upang makakuha ng isang halimbawa.
Gaya ng nabanggit sa seksyong "Tweaking ns-3", ang ns-3 ang sistema ng pagsubaybay ay nahahati sa bakas
pinagmumulan at trace sinks, at nagbibigay kami ng mga function para ikonekta ang dalawa. Gagamitin natin ang
modelo ng kadaliang kumilos paunang-natukoy na kurso baguhin ang pinagmulan ng bakas upang magmula sa mga kaganapang bakas. Kami
kakailanganing magsulat ng trace sink para kumonekta sa source na iyon na magpapakita ng medyo maganda
impormasyon para sa atin. Sa kabila ng reputasyon nito bilang mahirap, ito ay talagang medyo simple.
Bago ang pangunahing programa ng scratch/mythird.cc script (ibig sabihin, pagkatapos lamang ng
NS_LOG_COMPONENT_DEFINE statement), idagdag ang sumusunod na function:
walang bisa
CourseChange (std::string context, Ptr modelo)
{
Posisyon ng vector = modelo->GetPosition ();
NS_LOG_UNCOND (konteksto <
" x = " << posisyon.x << ", y = " << posisyon.y);
}
Kinukuha lang ng code na ito ang impormasyon ng posisyon mula sa modelo ng kadaliang kumilos at nang walang kondisyon
nag-log sa x at y na posisyon ng node. Aayusin natin ang function na ito
tinatawag tuwing nagbabago ang posisyon ng wireless node na may echo client. Ginagawa namin ito
gamit ang Config::Kumonekta function. Idagdag ang mga sumusunod na linya ng code sa script lang
bago ang Simulator::Tumakbo tawagan
std::ostringstream oss;
oss <
"/NodeList/" << wifiStaNodes.Get (nWifi - 1)->GetId () <
"/$ns3::MobilityModel/CourseChange";
Config::Connect (oss.str (), MakeCallback (&CourseChange));
Ang ginagawa namin dito ay gumawa ng string na naglalaman ng tracing namespace path ng event
kung saan gusto naming kumonekta. Una, kailangan nating malaman kung aling node ang gusto nating gamitin
ang GetId pamamaraan tulad ng inilarawan kanina. Sa kaso ng default na numero ng CSMA at
wireless node, ito pala ay node seven at ang tracing namespace path sa
mobility model ang magiging hitsura,
/NodeList/7/$ns3::MobilityModel/CourseChange
Batay sa talakayan sa seksyon ng pagsubaybay, maaari mong ipahiwatig na ang trace path na ito
tumutukoy sa ikapitong node sa pandaigdigang NodeList. Tinutukoy nito ang tinatawag na an
pinagsama-samang bagay ng uri ns3::MobilityModel. Ang dollar sign prefix ay nagpapahiwatig na ang
Ang MobilityModel ay pinagsama-sama sa node seven. Ang huling bahagi ng landas ay nangangahulugan na tayo
ay nakikisali sa kaganapang "CourseChange" ng modelong iyon.
Gumagawa kami ng koneksyon sa pagitan ng trace source sa node seven sa aming trace sink sa pamamagitan ng pagtawag
Config::Kumonekta at pagpasa sa namespace path na ito. Kapag ito ay tapos na, ang bawat kurso ay nagbabago
Ang kaganapan sa node pito ay mai-hook sa aming trace sink, na siya namang magpi-print ng
bagong posisyon.
Kung pinapatakbo mo na ngayon ang simulation, makikita mo ang mga pagbabago sa kurso na ipinapakita habang nangyayari ang mga ito.
Matagumpay na natapos ang 'build' (5.989s)
/NodeList/7/$ns3::MobilityModel/CourseChange x = 10, y = 0
/NodeList/7/$ns3::MobilityModel/CourseChange x = 10.3841, y = 0.923277
/NodeList/7/$ns3::MobilityModel/CourseChange x = 10.2049, y = 1.90708
/NodeList/7/$ns3::MobilityModel/CourseChange x = 10.8136, y = 1.11368
/NodeList/7/$ns3::MobilityModel/CourseChange x = 10.8452, y = 2.11318
/NodeList/7/$ns3::MobilityModel/CourseChange x = 10.9797, y = 3.10409
Sa pagkakataong nagpadala ang 2s client ng 1024 bytes sa 10.1.2.4 port 9
Sa oras na nakatanggap ang 2.01796s server ng 1024 bytes mula sa 10.1.3.3 port 49153
Sa oras na nagpadala ang 2.01796s server ng 1024 bytes sa 10.1.3.3 port 49153
Sa oras na nakatanggap ang 2.03364s client ng 1024 bytes mula sa 10.1.2.4 port 9
/NodeList/7/$ns3::MobilityModel/CourseChange x = 11.3273, y = 4.04175
/NodeList/7/$ns3::MobilityModel/CourseChange x = 12.013, y = 4.76955
/NodeList/7/$ns3::MobilityModel/CourseChange x = 12.4317, y = 5.67771
/NodeList/7/$ns3::MobilityModel/CourseChange x = 11.4607, y = 5.91681
/NodeList/7/$ns3::MobilityModel/CourseChange x = 12.0155, y = 6.74878
/NodeList/7/$ns3::MobilityModel/CourseChange x = 13.0076, y = 6.62336
/NodeList/7/$ns3::MobilityModel/CourseChange x = 12.6285, y = 5.698
/NodeList/7/$ns3::MobilityModel/CourseChange x = 13.32, y = 4.97559
/NodeList/7/$ns3::MobilityModel/CourseChange x = 13.1134, y = 3.99715
/NodeList/7/$ns3::MobilityModel/CourseChange x = 13.8359, y = 4.68851
/NodeList/7/$ns3::MobilityModel/CourseChange x = 13.5953, y = 3.71789
/NodeList/7/$ns3::MobilityModel/CourseChange x = 12.7595, y = 4.26688
/NodeList/7/$ns3::MobilityModel/CourseChange x = 11.7629, y = 4.34913
/NodeList/7/$ns3::MobilityModel/CourseChange x = 11.2292, y = 5.19485
/NodeList/7/$ns3::MobilityModel/CourseChange x = 10.2344, y = 5.09394
/NodeList/7/$ns3::MobilityModel/CourseChange x = 9.3601, y = 4.60846
/NodeList/7/$ns3::MobilityModel/CourseChange x = 8.40025, y = 4.32795
/NodeList/7/$ns3::MobilityModel/CourseChange x = 9.14292, y = 4.99761
/NodeList/7/$ns3::MobilityModel/CourseChange x = 9.08299, y = 5.99581
/NodeList/7/$ns3::MobilityModel/CourseChange x = 8.26068, y = 5.42677
/NodeList/7/$ns3::MobilityModel/CourseChange x = 8.35917, y = 6.42191
/NodeList/7/$ns3::MobilityModel/CourseChange x = 7.66805, y = 7.14466
/NodeList/7/$ns3::MobilityModel/CourseChange x = 6.71414, y = 6.84456
/NodeList/7/$ns3::MobilityModel/CourseChange x = 6.42489, y = 7.80181
TRACING
likuran
Tulad ng nabanggit sa UsingTracingSystem, ang buong punto ng pagpapatakbo ng isang ns-3 kunwa ay upang
makabuo ng output para sa pag-aaral. Mayroon kang dalawang pangunahing diskarte upang makakuha ng output mula sa ns-3:
gamit ang mga generic na paunang natukoy na mga mekanismo ng bulk output at pag-parse ng kanilang nilalaman upang i-extract
Nakamamangha na impormasyon; o kahit papaano ay bumubuo ng isang mekanismo ng output na nagbibigay ng eksakto
(at marahil lamang) ang nais na impormasyon.
Ang paggamit ng mga paunang natukoy na mekanismo ng bulk output ay may kalamangan na hindi nangangailangan ng anumang mga pagbabago sa
ns-3, ngunit maaaring mangailangan ng pagsusulat ng mga script para i-parse at i-filter para sa data ng interes. Madalas,
PCAP o NS_LOG ang mga output na mensahe ay nakukuha habang tumatakbo ang simulation at hiwalay na tumatakbo
sa pamamagitan ng mga script na gumagamit grep, uhaw or ang awkward para i-parse ang mga mensahe at bawasan at ibahin ang anyo
ang data sa isang mapapamahalaang form. Dapat isulat ang mga programa upang gawin ang pagbabago, kaya ito
ay hindi darating nang libre. NS_LOG ang output ay hindi itinuturing na bahagi ng ns-3 API, at maaari
baguhin nang walang babala sa pagitan ng mga release. At saka, NS_LOG ang output ay magagamit lamang sa
nabubuo ang debug, kaya ang pag-asa dito ay nagpapataw ng parusa sa pagganap. Siyempre, kung ang
impormasyon ng interes ay hindi umiiral sa alinman sa mga paunang natukoy na mekanismo ng output, ito
nabigo ang diskarte.
Kung kailangan mong magdagdag ng kaunting impormasyon sa paunang natukoy na maramihang mekanismo, maaari itong
tiyak na gagawin; at kung gagamit ka ng isa sa mga ns-3 mekanismo, maaari mong maidagdag ang iyong code
bilang kontribusyon.
ns-3 ay nagbibigay ng isa pang mekanismo, na tinatawag na Pagsubaybay, na umiiwas sa ilan sa mga likas na problema
sa mga mekanismo ng bulk output. Ito ay may ilang mahahalagang pakinabang. Una, kaya mo
bawasan ang dami ng data na kailangan mong pamahalaan sa pamamagitan lamang ng pagsubaybay sa mga kaganapang kinaiinteresan mo
(para sa malalaking simulation, ang pagtatapon ng lahat sa disk para sa post-processing ay maaaring lumikha ng I/O
mga bottleneck). Pangalawa, kung gagamitin mo ang pamamaraang ito, maaari mong kontrolin ang format ng output
direkta upang maiwasan mo ang postprocessing hakbang sa uhaw, ang awkward, perlas or python mga script. Kung
gusto mo, ang iyong output ay maaaring direktang i-format sa isang form na katanggap-tanggap ng gnuplot, para sa
halimbawa (tingnan din ang GnuplotHelper). Maaari kang magdagdag ng mga kawit sa core na maaaring pagkatapos
naa-access ng ibang mga user, ngunit hindi maglalabas ng impormasyon maliban kung tahasang hihilingin
gawin mo. Para sa mga kadahilanang ito, naniniwala kami na ang ns-3 ang sistema ng pagsubaybay ay ang pinakamahusay na paraan upang makuha
impormasyon mula sa isang simulation at samakatuwid ay isa rin sa pinakamahalagang mekanismo
upang maunawaan sa ns-3.
pudpod Instruments
Mayroong maraming mga paraan upang makakuha ng impormasyon mula sa isang programa. Ang pinakatuwirang paraan ay
upang direktang i-print ang impormasyon sa karaniwang output, tulad ng sa:
# isama
...
walang bisa
SomeFunction (walang bisa)
{
uint32_t x = SOME_INTERESTING_VALUE;
...
std::cout << "Ang halaga ng x ay " << x << std::endl;
...
}
Walang sinuman ang pipigil sa iyo na pumunta sa kaibuturan ng ns-3 at pagdaragdag ng print
mga pahayag. Ito ay napakadaling gawin at, pagkatapos ng lahat, mayroon kang ganap na kontrol sa iyong
sarili ns-3 sangay. Ito ay malamang na hindi magiging lubhang kasiya-siya sa mahabang panahon
termino, bagaman.
Habang dumarami ang bilang ng mga naka-print na pahayag sa iyong mga programa, ang gawain ng pagharap sa
ang malaking bilang ng mga output ay magiging mas kumplikado. Sa kalaunan, maaari mong maramdaman
ang pangangailangang kontrolin kung anong impormasyon ang ini-print sa ilang paraan, marahil sa pamamagitan ng pag-on
at sa ilang partikular na kategorya ng mga print, o pagtaas o pagbaba ng halaga ng
impormasyong gusto mo. Kung magpapatuloy ka sa landas na ito maaari mong matuklasan na mayroon ka
muling ipinatupad ang NS_LOG mekanismo (tingnan ang UsingLogging). Upang maiwasan iyon, isa sa
ang mga unang bagay na maaari mong isaalang-alang ay ang paggamit NS_LOG mismo.
Nabanggit namin sa itaas ang isang paraan upang makakuha ng impormasyon ns-3 ay upang i-parse ang umiiral na NS_LOG
output para sa kawili-wiling impormasyon. Kung matuklasan mo na ang ilang maliit na impormasyon sa iyo
kailangan ay hindi naroroon sa umiiral na log output, maaari mong i-edit ang core ng ns-3 at idagdag lang
ang iyong kawili-wiling impormasyon sa output stream. Ngayon, ito ay tiyak na mas mahusay kaysa sa
pagdaragdag ng iyong sariling mga pahayag sa pag-print dahil sumusunod ito ns-3 coding convention at maaari
potensyal na maging kapaki-pakinabang sa ibang mga tao bilang isang patch sa kasalukuyang core.
Pumili tayo ng random na halimbawa. Kung gusto mong magdagdag ng higit pang pag-log sa ns-3 TCP socket
(tcp-socket-base.cc) maaari ka lamang magdagdag ng bagong mensahe sa pagpapatupad. Pansinin
na sa TcpSocketBase::ReceivedAck() walang log message para sa walang ACK case. Ikaw
maaari lamang magdagdag ng isa, pagpapalit ng code. Narito ang orihinal:
/** Iproseso ang bagong natanggap na ACK */
walang bisa
TcpSocketBase::ReceivedAck (Ptr packet, const TcpHeader& tcpHeader)
{
NS_LOG_FUNCTION (ito << tcpHeader);
// Nakatanggap ng ACK. Ikumpara ang ACK number sa pinakamataas na unacked seqno
if (0 == (tcpHeader.GetFlags () & TcpHeader::ACK))
{ // Huwag pansinin kung walang flag ng ACK
}
...
Upang i-log ang walang ACK case, maaari kang magdagdag ng bago NS_LOG_LOGIC nasa if katawan ng pahayag:
/** Iproseso ang bagong natanggap na ACK */
walang bisa
TcpSocketBase::ReceivedAck (Ptr packet, const TcpHeader& tcpHeader)
{
NS_LOG_FUNCTION (ito << tcpHeader);
// Nakatanggap ng ACK. Ikumpara ang ACK number sa pinakamataas na unacked seqno
if (0 == (tcpHeader.GetFlags () & TcpHeader::ACK))
{ // Huwag pansinin kung walang flag ng ACK
NS_LOG_LOGIC ("TcpSocketBase " << ito << " walang ACK flag");
}
...
Ito ay maaaring mukhang medyo simple at kasiya-siya sa unang tingin, ngunit isang bagay na dapat isaalang-alang
na susulat ka ng code na idaragdag NS_LOG mga pahayag at kailangan mo ring magsulat
code (tulad ng sa grep, uhaw or ang awkward scripts) upang i-parse ang output ng log upang ihiwalay ang iyong
impormasyon. Ito ay dahil kahit na mayroon kang ilang kontrol sa kung ano ang output ng
logging system, mayroon ka lamang kontrol hanggang sa antas ng bahagi ng log, na karaniwan ay
isang buong source code file.
Kung nagdaragdag ka ng code sa isang umiiral na module, kakailanganin mo ring mabuhay kasama ang output
na nakita ng bawat iba pang developer na kawili-wili. Maaari mong mahanap iyon upang makuha ang
maliit na halaga ng impormasyon na kailangan mo, maaaring kailanganin mong lumakad sa malaking halaga ng
mga extraneous na mensahe na hindi interesado sa iyo. Maaaring mapilitan kang mag-save ng malaking log
mga file sa disk at iproseso ang mga ito hanggang sa ilang linya sa tuwing gusto mong gawin ang anuman.
Dahil walang mga garantiya sa ns-3 tungkol sa katatagan ng NS_LOG output, maaari mo rin
matuklasan na ang mga piraso ng log output na kung saan ay umaasa sa mawala o nagbabago sa pagitan
naglalabas. Kung nakasalalay ka sa istraktura ng output, maaari mong makita ang iba pang mga mensahe
idinagdag o tinanggal na maaaring makaapekto sa iyong parsing code.
Sa wakas, NS_LOG magagamit lang ang output sa mga build ng debug, hindi ka makakakuha ng output ng log mula sa
mga na-optimize na build, na tumatakbo nang halos dalawang beses nang mas mabilis. Umaasa sa NS_LOG nagpapataw ng isang pagganap
parusa
Para sa mga kadahilanang ito, isinasaalang-alang namin ang mga pag-print sa std::labas at NS_LOG mga mensahe upang maging mabilis at
maruming paraan para makakuha ng karagdagang impormasyon ns-3, ngunit hindi angkop para sa seryosong trabaho.
Ito ay kanais-nais na magkaroon ng isang matatag na pasilidad gamit ang mga matatag na API na nagpapahintulot sa isa na maabot
ang pangunahing sistema at makuha lamang ang kinakailangang impormasyon. Ito ay kanais-nais na magagawa
ito nang hindi kinakailangang baguhin at i-compile ang pangunahing sistema. Mas mabuti pang maging a
system na nag-notify ng user code kapag nagbago ang isang item ng interes o isang kawili-wiling kaganapan
nangyari kaya hindi na kailangang aktibong sumipot ang user sa system na hinahanap
bagay na ito.
Ang ns-3 Ang sistema ng pagsubaybay ay idinisenyo upang gumana sa mga linyang iyon at mahusay na isinama sa
ang Katangian at config mga subsystem na nagbibigay-daan para sa medyo simpleng mga senaryo ng paggamit.
Pangkalahatang-ideya
Ang ns-3 Ang sistema ng pagsubaybay ay binuo sa mga konsepto ng mga independiyenteng pinagmumulan ng pagsubaybay at
pagsubaybay sa mga lababo, kasama ang isang pare-parehong mekanismo para sa pagkonekta ng mga mapagkukunan sa mga lababo.
Ang mga trace source ay mga entity na maaaring magpahiwatig ng mga kaganapang nangyayari sa isang simulation at magbigay
access sa kawili-wiling pinagbabatayan ng data. Halimbawa, maaaring ipahiwatig ng isang trace source kung kailan a
packet ay natanggap ng isang net device at nagbibigay ng access sa mga nilalaman ng packet para sa
interesadong trace sinks. Ang isang bakas na pinagmulan ay maaari ring magpahiwatig kung kailan isang kawili-wiling estado
ang pagbabago ay nangyayari sa isang modelo. Halimbawa, ang congestion window ng isang TCP model ay isang prime
kandidato para sa isang bakas na pinagmulan. Sa tuwing nagbabago ang congestion window ng konektadong bakas
ang mga lababo ay inaabisuhan ng luma at bagong halaga.
Ang mga pinagmumulan ng bakas ay hindi kapaki-pakinabang sa kanilang sarili; sila ay dapat na konektado sa iba pang mga piraso ng code
na talagang gumagawa ng isang bagay na kapaki-pakinabang sa impormasyong ibinigay ng pinagmulan. Ang
Ang mga entity na kumukonsumo ng trace information ay tinatawag na trace sinks. Ang mga pinagmumulan ng bakas ay
ang mga generator ng data at trace sink ay mga mamimili. Ang tahasang paghahati na ito ay nagbibigay-daan para sa malaki
bilang ng mga bakas na pinagmumulan na makakalat sa paligid ng system sa mga lugar kung saan modelo ang mga may-akda
naniniwala na maaaring maging kapaki-pakinabang. Ang pagpasok ng mga trace source ay nagpapakilala ng napakaliit na pagpapatupad
sa itaas.
Maaaring mayroong zero o higit pang mga consumer ng trace event na nabuo ng isang trace source. Maaari isa
isipin ang isang trace source bilang isang uri ng point-to-multipoint na link ng impormasyon. Ang iyong code
naghahanap ng mga bakas na kaganapan mula sa isang partikular na piraso ng core code ay maaaring masayang kasama
ibang code na gumagawa ng isang bagay na ganap na naiiba sa parehong impormasyon.
Maliban kung ikinonekta ng isang user ang isang trace sink sa isa sa mga pinagmumulan na ito, walang output. Sa pamamagitan ng paggamit
ang sistema ng pagsubaybay, ikaw at ang iba pang mga taong naka-hook sa parehong pinagmumulan ng bakas ay nakukuha
kung ano mismo ang gusto nila at kung ano lang ang gusto nila sa labas ng system. Wala ni isa sa inyo
nakakaapekto sa sinumang ibang user sa pamamagitan ng pagbabago kung anong impormasyon ang ilalabas ng system. kung ikaw
mangyari na magdagdag ng trace source, ang iyong trabaho bilang isang mabuting open-source na mamamayan ay maaaring payagan ang iba
mga gumagamit na magbigay ng mga bagong kagamitan na marahil ay lubhang kapaki-pakinabang sa pangkalahatan, nang hindi gumagawa ng anuman
mga pagbabago sa ns-3 core.
Simple halimbawa
Maglaan tayo ng ilang minuto at maglakad sa isang simpleng halimbawa ng pagsubaybay. Kakailanganin natin
isang maliit na background sa Callbacks upang maunawaan kung ano ang nangyayari sa halimbawa, kaya namin
kailangang lumihis kaagad ng maliit.
Mga Callback
Ang layunin ng Callback system sa ns-3 ay upang payagan ang isang piraso ng code na tumawag sa isang function
(o pamamaraan sa C++) nang walang anumang partikular na inter-module dependency. Ang ibig sabihin nito sa huli
kailangan mo ng ilang uri ng indidirection -- tinatrato mo ang address ng tinatawag na function bilang a
variable. Ang variable na ito ay tinatawag na pointer-to-function variable. Ang relasyon
sa pagitan ng function at pointer-to-function ay talagang hindi naiiba sa object at
pointer-to-object.
Sa C ang canonical na halimbawa ng isang pointer-to-function ay a
pointer-to-function-returning-integer (PFI). Para sa pagkuha ng PFI int parameter, ito
maaaring ideklara tulad ng,
int (*pfi)(int arg) = 0;
(Ngunit basahin ang C++-FAQ seksyon 33 bago magsulat ng code na ganito!) Ano ang makukuha mo dito
ay isang variable na pinangalanang simple pfi na pinasimulan sa halagang 0. Kung gusto mo
simulan ang pointer na ito sa isang bagay na makabuluhan, kailangan mong magkaroon ng isang function na may a
magkatugmang lagda. Sa kasong ito, maaari kang magbigay ng isang function na mukhang:
int MyFunction (int arg) {}
Kung mayroon kang target na ito, maaari mong simulan ang variable upang tumuro sa iyong function:
pfi = MyFunction;
Maaari mong tawagan ang MyFunction nang hindi direkta gamit ang mas nagpapahiwatig na paraan ng tawag:
int resulta = (*pfi) (1234);
Ito ay nagmumungkahi dahil mukhang di-reference mo lang ang function pointer
tulad ng gusto mong i-dereference ang anumang pointer. Kadalasan, gayunpaman, sinasamantala ng mga tao ang
katotohanan na alam ng compiler kung ano ang nangyayari at gagamit lang ng mas maikling form:
int resulta = pfi (1234);
Mukhang tumatawag ka sa isang function na pinangalanan pfi, ngunit ang compiler ay sapat na matalino upang
alam na tumawag sa pamamagitan ng variable pfi hindi direkta sa pag-andar MyFunction.
Conceptually, ito ay halos eksakto kung paano gumagana ang tracing system. Talaga, isang bakas
lababo is isang callback. Kapag ang isang trace sink ay nagpahayag ng interes sa pagtanggap ng mga trace na kaganapan, ito
idinaragdag ang sarili bilang isang Callback sa isang listahan ng mga Callback na panloob na hawak ng trace source.
Kapag nangyari ang isang kawili-wiling kaganapan, ang pinagmumulan ng bakas ay humihiling nito operator(...) pagbibigay
zero o higit pang mga argumento. Ang operator(...) kalaunan ay gumagala sa sistema at
gumagawa ng isang bagay na kapansin-pansing tulad ng hindi direktang tawag na nakita mo lang, na nagbibigay ng zero o higit pa
mga parameter, tulad ng tawag sa pfi sa itaas ay nagpasa ng isang parameter sa target na function
MyFunction.
Ang mahalagang pagkakaiba na idinaragdag ng tracing system ay para sa bawat trace source doon
ay isang panloob na listahan ng Mga Callback. Sa halip na gumawa lamang ng isang hindi direktang tawag, isang bakas
maaaring mag-invoke ng maraming Callback ang source. Kapag ang isang bakas na lababo ay nagpahayag ng interes sa
mga abiso mula sa isang trace source, ito ay karaniwang nag-aayos lamang upang magdagdag ng sarili nitong function sa
ang listahan ng callback.
Kung interesado ka sa higit pang mga detalye tungkol sa kung paano ito aktwal na inaayos ns-3, pakiramdam
malayang basahin ang seksyong Callback ng ns-3 Manu-manong.
Walkthrough: pang-apat.cc
Nagbigay kami ng ilang code para ipatupad kung ano talaga ang pinakasimpleng halimbawa ng pagsubaybay
na maaaring tipunin. Mahahanap mo ang code na ito sa direktoryo ng tutorial bilang pang-apat.cc.
Maglakad tayo sa pamamagitan nito:
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Ang program na ito ay libreng software; maaari mo itong muling ipamahagi at/o baguhin
* ito sa ilalim ng mga tuntunin ng GNU General Public License bersyon 2 bilang
* inilathala ng Free Software Foundation;
*
* Ang programang ito ay ipinamahagi sa pag-asa na ito ay magiging kapaki-pakinabang,
* ngunit WALANG ANUMANG WARRANTY; nang walang kahit na ipinahiwatig na warranty ng
* MERCHANTABILITY o FITNESS PARA SA ISANG PARTIKULAR NA LAYUNIN. Tingnan ang
* GNU General Public License para sa higit pang mga detalye.
*
* Dapat ay nakatanggap ka ng kopya ng GNU General Public License
* kasama ng programang ito; kung hindi, sumulat sa Libreng Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "ns3/object.h"
#include "ns3/uintger.h"
#include "ns3/traced-value.h"
#include "ns3/trace-source-accessor.h"
# isama
gamit ang namespace ns3;
Karamihan sa code na ito ay dapat na pamilyar sa iyo. Tulad ng nabanggit sa itaas, ang trace system
gumagawa ng matinding paggamit ng mga Object at Attribute system, kaya kakailanganin mong isama ang mga ito.
Ang unang dalawang kasama sa itaas ay nagdadala ng mga deklarasyon para sa mga system na iyon nang tahasan. Ikaw
Maaaring gamitin ang header ng pangunahing module upang makuha ang lahat nang sabay-sabay, ngunit ginagawa namin ang kasama
tahasan dito upang ilarawan kung gaano kasimple ang lahat.
Ang file, traced-value.h nagdadala ng mga kinakailangang deklarasyon para sa pagsubaybay sa data na iyon
sumusunod sa value semantics. Sa pangkalahatan, ang value semantics ay nangangahulugan lamang na maaari mong ipasa ang
bagay mismo sa paligid, sa halip na ipasa ang address ng bagay. Ano ba talaga ang lahat ng ito
ibig sabihin ay masusubaybayan mo ang lahat ng pagbabagong ginawa sa isang TracedValue sa isang talagang
simpleng paraan.
Dahil ang sistema ng pagsubaybay ay isinama sa Mga Katangian, at gumagana ang Mga Katangian sa Mga Bagay,
dapat mayroong isang ns-3 Bagay para mabuhay ang trace source. Ang susunod na code snippet
ipinapahayag at tinukoy ang isang simpleng Bagay na maaari nating gawin.
klase MyObject : pampublikong Bagay
{
pampublikong:
static na TypeId GetTypeId (walang bisa)
{
static TypeId tid = TypeId ("MyObject")
.SetParent (Object::GetTypeId ())
.AddConstructor ()
.AddTraceSource ("MyInteger",
"Isang integer na halaga upang masubaybayan.",
MakeTraceSourceAccessor (&MyObject::m_myInt),
"ns3::Traced::Value::Int32Callback")
;
return tid;
}
MyObject () {}
TracedValue m_myInt;
};
Ang dalawang mahalagang linya ng code, sa itaas, tungkol sa pagsubaybay ay ang .AddTraceSource
at ang TracedValue deklarasyon ng m_myInt.
Ang .AddTraceSource nagbibigay ng "mga kawit" na ginagamit para sa pagkonekta sa pinagmumulan ng bakas sa
labas ng mundo sa pamamagitan ng Config system. Ang unang argumento ay isang pangalan para sa bakas na ito
source, na ginagawa itong nakikita sa Config system. Ang pangalawang argumento ay isang help string.
Ngayon tingnan ang ikatlong argumento, sa katunayan ay tumutok sa argumento ng ikatlong argumento:
&MyObject::m_myInt. Ito ang TracedValue na idinaragdag sa klase; ito ay
palaging miyembro ng data ng klase. (Ang huling argumento ay ang pangalan ng a typedef para sa
Uri ng TracedValue, bilang isang string. Ito ay ginagamit upang makabuo ng dokumentasyon para sa tama
Signature ng function ng callback, na kapaki-pakinabang lalo na para sa mas pangkalahatang mga uri ng
Mga callback.)
Ang TracedValue<> ang deklarasyon ay nagbibigay ng imprastraktura na nagtutulak sa callback
proseso. Anumang oras na mababago ang pinagbabatayan na halaga, ibibigay ng mekanismo ng TracedValue
pareho ang luma at ang bagong halaga ng variable na iyon, sa kasong ito an int32_t halaga. Ang bakas
Ang sink function para sa TracedValue na ito ay mangangailangan ng lagda
void (* TracedValueCallback)(const int32_t oldValue, const int32_t newValue);
Lahat ng trace sink na nakakabit sa trace source na ito ay dapat may ganitong lagda. Tatalakayin natin sa ibaba
kung paano mo matutukoy ang kinakailangang pirma ng callback sa ibang mga kaso.
Oo naman, nagpapatuloy pang-apat.cc Nakikita namin:
walang bisa
IntTrace (int32_t oldValue, int32_t newValue)
{
std::cout << "Traced " << oldValue << " to " << newValue << std::endl;
}
Ito ang kahulugan ng isang katugmang trace sink. Direktang tumutugma ito sa callback
pirma ng function. Sa sandaling ito ay konektado, ang function na ito ay tatawagin sa tuwing ang
TracedValue mga pagbabago.
Nakita na natin ngayon ang trace source at ang trace sink. Ang natitira ay code para ikonekta ang
pinagmulan sa lababo, na nangyayari sa pangunahin:
int
pangunahing (int argc, char *argv[])
{
Ptr myObject = CreateObject ();
myObject->TraceConnectWithoutContext ("MyInteger", MakeCallback(&IntTrace));
myObject->m_myInt = 1234;
}
Dito muna namin ginawa ang MyObject instance kung saan nabubuhay ang trace source.
Ang susunod na hakbang, ang TraceConnectWithoutContext, bumubuo ng koneksyon sa pagitan ng bakas
pinagmulan at ang trace sink. Ang unang argumento ay ang trace source name lang na "MyInteger"
nakita namin sa itaas. Pansinin ang Gumawa ngCallback function ng template. Ginagawa ng function na ito ang magic
kinakailangan upang lumikha ng pinagbabatayan ns-3 Callback object at iugnay ito sa function
IntTrace. TraceConnect gumagawa ng kaugnayan sa pagitan ng iyong ibinigay na function at
labis na karga operator() sa traced variable na tinutukoy ng "MyInteger" Attribute.
Pagkatapos gawin ang pag-uugnay na ito, "papagana" ng trace source ang iyong ibinigay na callback
function.
Ang code para mangyari ang lahat ng ito ay, siyempre, hindi mahalaga, ngunit ang kakanyahan ay iyon
nag-aayos ka para sa isang bagay na kamukha ng pfi() halimbawa sa itaas na tatawagin
sa pamamagitan ng trace source. Ang deklarasyon ng TracedValue m_myInt; sa Bagay
mismo ang gumaganap ng magic na kailangan para maibigay ang mga overloaded na assignment operator na gagawin
gamitin ang operator() upang aktwal na i-invoke ang Callback gamit ang mga gustong parameter. Ang
.AddTraceSource nagsasagawa ng mahika upang ikonekta ang Callback sa Config system, at
TraceConnectWithoutContext gumaganap ng magic upang ikonekta ang iyong function sa bakas
pinagmulan, na tinukoy ng pangalan ng Attribute.
Huwag pansinin ang kaunti tungkol sa konteksto sa ngayon.
Panghuli, ang linyang nagtatalaga ng halaga sa m_myInt:
myObject->m_myInt = 1234;
dapat bigyang-kahulugan bilang isang panawagan ng operator= sa variable ng miyembro m_myInt sa
ang integer 1234 ipinasa bilang isang parameter.
Dahil sa m_myInt ay isang TracedValue, tinukoy ang operator na ito upang magsagawa ng callback na iyon
nagbabalik ng walang bisa at kumukuha ng dalawang integer na halaga bilang mga parameter --- isang lumang halaga at isang bagong halaga
para sa integer na pinag-uusapan. Iyan ang eksaktong function signature para sa callback
function na ibinigay namin --- IntTrace.
Upang ibuod, ang isang trace source ay, sa esensya, isang variable na naglalaman ng isang listahan ng mga callback. A
Ang trace sink ay isang function na ginagamit bilang target ng isang callback. Ang Katangian at uri ng bagay
Ang mga sistema ng impormasyon ay ginagamit upang magbigay ng isang paraan upang ikonekta ang mga pinagmumulan ng bakas sa mga bakas na lababo.
Ang pagkilos ng "pagtama" sa isang trace source ay nagpapatupad ng isang operator sa trace source na kung saan
nagpapagana ng mga callback. Nagreresulta ito sa mga trace sink callback na nagrerehistro ng interes sa
source na tinatawag na may mga parameter na ibinigay ng source.
Kung bubuo at patakbuhin mo na ang halimbawang ito,
$ ./waf --run pang-apat
makikita mo ang output mula sa IntTrace function na execute sa sandaling ang trace source ay
hit:
Na-trace mula 0 hanggang 1234
Nang isagawa namin ang code, myObject->m_myInt = 1234;, ang trace source ay nagpaputok at
awtomatikong ibinigay ang bago at pagkatapos ng mga halaga sa trace sink. Ang function
IntTrace pagkatapos ay i-print ito sa karaniwang output.
Ikabit sa config
Ang TraceConnectWithoutContext tawag na ipinapakita sa itaas sa simpleng halimbawa ay talagang napaka
bihirang ginagamit sa system. Mas karaniwan, ang config subsystem ay ginagamit upang pumili ng isang bakas
pinagmulan sa sistema gamit ang tinatawag na a config landas. Nakita namin ang isang halimbawa nito sa
nakaraang seksyon kung saan na-hook namin ang kaganapang "CourseChange" noong nag-eeksperimento kami
pangatlo.cc.
Alalahanin na tinukoy namin ang isang trace sink upang mag-print ng impormasyon sa pagbabago ng kurso mula sa mobility
mga modelo ng aming simulation. Dapat ay mas malinaw na sa iyo ngayon kung ano ang function na ito
ginagawa:
walang bisa
CourseChange (std::string context, Ptr modelo)
{
Posisyon ng vector = modelo->GetPosition ();
NS_LOG_UNCOND (konteksto <
" x = " << posisyon.x << ", y = " << posisyon.y);
}
Kapag ikinonekta namin ang trace source na "CourseChange" sa trace sink sa itaas, gumamit kami ng a
I-configure ang path upang tukuyin ang pinagmulan kapag nag-ayos kami ng koneksyon sa pagitan ng paunang natukoy
trace source at ang bagong trace sink:
std::ostringstream oss;
oss << "/NodeList/"
<< wifiStaNodes.Get (nWifi - 1)->GetId ()
<< "/$ns3::MobilityModel/CourseChange";
Config::Connect (oss.str (), MakeCallback (&CourseChange));
Subukan natin at bigyan ng kaunting kahulugan ang kung minsan ay itinuturing na medyo mahiwagang code.
Para sa mga layunin ng talakayan, ipagpalagay na ang numero ng Node ay ibinalik ng GetId() is
"7". Sa kasong ito, ang landas sa itaas ay lumalabas na
"/NodeList/7/$ns3::MobilityModel/CourseChange"
Ang huling segment ng isang config path ay dapat na isang katangian ng Bagay. Sa katunayan, kung mayroon ka
isang pointer sa Bagay na mayroong "CourseChange" katangian madaling gamitin, maaari mong isulat ito
tulad ng ginawa natin sa nakaraang halimbawa. Alam mo na sa ngayon na karaniwang nag-iimbak kami
mga payo sa aming Node sa isang NodeContainer. Nasa pangatlo.cc halimbawa, ang mga Node ng interes
ay naka-imbak sa wifiStaNodes NodeContainer. Sa katunayan, habang pinagsasama-sama ang landas,
ginamit namin ang lalagyang ito upang makakuha ng a Ptr na dati naming tinatawag GetId(). maaari tayong magkaroon
ginamit ito Ptr para direktang tumawag sa paraan ng Connect:
Ptr theObject = wifiStaNodes.Get (nWifi - 1);
theObject->TraceConnectWithoutContext ("CourseChange", MakeCallback (&CourseChange));
Sa pangatlo.cc halimbawa, gusto talaga namin ng karagdagang "konteksto" na maihatid
gamit ang mga parameter ng Callback (na ipapaliwanag sa ibaba) para talagang magamit namin ang
sumusunod na katumbas na code:
Ptr theObject = wifiStaNodes.Get (nWifi - 1);
theObject->TraceConnect ("CourseChange", MakeCallback (&CourseChange));
Ito ay lumiliko na ang panloob na code para sa Config::ConnectWithoutContext at Config::Kumonekta
talagang hanapin a Ptr at tawagan ang nararapat TraceConnect pamamaraan sa pinakamababa
antas.
Ang config ang mga function ay kumukuha ng landas na kumakatawan sa isang chain ng Bagay mga payo. Bawat segment
ng isang landas ay tumutugma sa isang Object Attribute. Ang huling segment ay ang Katangian ng
interes, at dapat na i-type ang mga naunang segment upang maglaman o makahanap ng Mga Bagay. Ang config code
nag-parse at "lumakad" sa landas na ito hanggang sa makarating ito sa huling bahagi ng landas. Pagkatapos nito
binibigyang-kahulugan ang huling bahagi bilang isang katangian sa huling Bagay na natagpuan nito habang naglalakad ang
landas. Ang config function pagkatapos ay tawagan ang naaangkop TraceConnect or
TraceConnectWithoutContext paraan sa panghuling Bagay. Tingnan natin kung ano ang mangyayari sa ilang sandali
higit pang detalye kapag tinatahak ang landas sa itaas.
Ang nangungunang "/" na character sa path ay tumutukoy sa isang tinatawag na namespace. Isa sa mga
Ang mga paunang natukoy na namespace sa config system ay "NodeList" na isang listahan ng lahat ng
mga node sa simulation. Ang mga item sa listahan ay tinutukoy ng mga indeks sa listahan, kaya
Ang "/NodeList/7" ay tumutukoy sa ikawalong Node sa listahan ng mga node na nilikha sa panahon ng simulation
(nagsisimula ang mga indeks ng recall sa 0'). ito sanggunian is talaga a ``Ptr ` at gayon din ang a
subclass ng isang ns3::Bagay.
Gaya ng inilarawan sa seksyong Object Model ng ns-3 Manual, malawakan naming ginagamit
pagsasama-sama ng bagay. Ito ay nagpapahintulot sa amin na bumuo ng isang kaugnayan sa pagitan ng iba't ibang mga Bagay
nang hindi nagtatayo ng isang kumplikadong punong pamana o nagdedesisyon kung anong mga bagay ang magiging bahagi
ng isang Node. Ang bawat Bagay sa isang Pagsasama-sama ay maaaring maabot mula sa iba pang mga Bagay.
Sa aming halimbawa ang susunod na bahagi ng path na nilalakaran ay nagsisimula sa "$" na character. Ito
ay nagpapahiwatig sa config system na ang segment ay ang pangalan ng isang uri ng bagay, kaya a
GetObject Dapat tumawag sa paghahanap para sa ganoong uri. Lumalabas na ang MobilityHelper
ginamit sa pangatlo.cc nag-aayos sa Aggregate, o associate, isang mobility model sa bawat isa sa
wireless Node. Kapag idinagdag mo ang "$" humihingi ka ng isa pang Bagay na mayroon
marahil ay dating pinagsama-sama. Maaari mong isipin ito bilang pagpapalit ng mga pointer mula sa
ang orihinal na Ptr gaya ng tinukoy ng "/NodeList/7" sa nauugnay nitong modelo ng mobility ---
na may uri ns3::MobilityModel. Kung pamilyar ka sa GetObject, tanong namin
sistema upang gawin ang mga sumusunod:
Si Ptr mobilityModel = node->GetObject ()
Nasa huling Bagay na tayo ngayon sa landas, kaya ibinaling natin ang ating atensyon sa Mga Katangian ng
na Bagay. Ang MobilityModel Tinutukoy ng klase ang isang Attribute na tinatawag na "CourseChange". Kaya mo
tingnan ito sa pamamagitan ng pagtingin sa source code sa src/mobility/model/mobility-model.cc at
naghahanap ng "CourseChange" sa iyong paboritong editor. Dapat mong mahanap
.AddTraceSource ("CourseChange",
"Nagbago ang halaga ng posisyon at/o bilis ng vector",
MakeTraceSourceAccessor (&MobilityModel::m_courseChangeTrace),
"ns3::MobilityModel::CourseChangeCallback")
na dapat mukhang napakapamilyar sa puntong ito.
Kung hahanapin mo ang kaukulang deklarasyon ng pinagbabatayan na traced variable sa
mobility-model.h makikita mo
TracedCallback > m_courseChangeTrace;
Ang uri ng deklarasyon TracedCallback Kinikilala m_courseChangeTrace bilang isang espesyal na listahan ng
Mga callback na maaaring ma-hook gamit ang mga function ng Config na inilarawan sa itaas. Ang typedef para
ang pirma ng callback function ay tinukoy din sa header file:
typedef void (* CourseChangeCallback)(Ptr * modelo);
Ang MobilityModel class ay idinisenyo upang maging isang base class na nagbibigay ng isang karaniwang interface para sa
lahat ng mga partikular na subclass. Kung hahanapin mo hanggang sa dulo ng file, makikita mo ang a
pamamaraan na tinukoy na tinatawag NotifyCourseChange():
walang bisa
MobilityModel::NotifyCourseChange (walang bisa) const
{
m_courseChangeTrace(ito);
}
Ang mga nagmula na klase ay tatawag sa paraang ito sa tuwing gagawa sila ng pagbabago ng kurso upang suportahan
pagsubaybay. Ang pamamaraang ito ay humihiling operator() sa pinagbabatayan m_courseChangeTrace, Na
ay, sa turn, ay tatawagin ang lahat ng mga nakarehistrong Callback, na tinatawag ang lahat ng mga bakas na lumubog iyon
may nakarehistrong interes sa trace source sa pamamagitan ng pagtawag sa isang Config function.
Kaya, sa pangatlo.cc halimbawa na aming tiningnan, sa tuwing may gagawing pagbabago ng kurso sa isa sa
RandomWalk2dMobilityModel mga pagkakataong naka-install, magkakaroon ng a NotifyCourseChange() tawag
na tumatawag sa MobilityModel batayang klase. Gaya ng nakikita sa itaas, ito ay humihiling operator()
on m_courseChangeTrace, na kung saan ay tumatawag sa anumang nakarehistrong trace sink. Sa halimbawa,
ang tanging code na nagrerehistro ng interes ay ang code na nagbigay ng Config path.
Samakatuwid, ang Pagbabago ng Kurso function na na-hook mula sa Node number seven ay ang
Callback lang ang tumatawag.
Ang huling piraso ng palaisipan ay ang "konteksto". Alalahanin na nakakita kami ng isang output na naghahanap
isang bagay tulad ng sumusunod mula sa pangatlo.cc:
/NodeList/7/$ns3::MobilityModel/CourseChange x = 7.27897, y =
2.22677
Ang unang bahagi ng output ay ang konteksto. Ito ay simpleng landas kung saan ang
config code na matatagpuan ang trace source. Sa kaso na aming tinitingnan ay maaaring mayroon
anumang bilang ng mga trace source sa system na tumutugma sa anumang bilang ng mga node na may
mga modelo ng kadaliang mapakilos. Kailangang mayroong ilang paraan upang matukoy kung aling trace source ang aktwal
ang nagpaputok ng Callback. Ang madaling paraan ay ang kumonekta sa Config::Kumonekta, sa halip
of Config::ConnectWithoutContext.
Pagkatuklas Pinagmumulan ng
Ang unang tanong na hindi maiiwasang lumabas para sa mga bagong user ng Tracing system ay, "Sige,
I kilala na doon dapat be kopyahin o sipiin sa pamamagitan ng pag-aninag pinagkukunan in ang kapanggapan core, pero paano do I mahanap Palabas Ano
kopyahin o sipiin sa pamamagitan ng pag-aninag pinagkukunan ay magagamit sa ako? "
Ang pangalawang tanong ay, "Sige, I natagpuan a kopyahin o sipiin sa pamamagitan ng pag-aninag mapagkukunan, paano do I malaman Palabas ang config landas
sa gamitin kailan I ikabit sa ito?"
Ang pangatlong tanong ay, "Sige, I natagpuan a kopyahin o sipiin sa pamamagitan ng pag-aninag pinagmulan at ang config landas, paano do I malaman
Palabas Ano ang pagbabalik uri at pormal argumento of my callback tungkulin kailangan sa maging?"
Ang ikaapat na tanong ay, "Sige, I nag-type na lahat in at Nakakuha ito hindi kapani-paniwala kakaiba mali
mensahe, Ano in ang mundo ang it ibig sabihin? "
Tatalakayin natin ang bawat isa sa mga ito.
Magagamit Pinagmumulan ng
Sige, I kilala na doon dapat be kopyahin o sipiin sa pamamagitan ng pag-aninag pinagkukunan in ang kapanggapan core, pero paano do I mahanap
Palabas Ano kopyahin o sipiin sa pamamagitan ng pag-aninag pinagkukunan ay magagamit sa Ako?
Ang sagot sa unang tanong ay matatagpuan sa ns-3 Dokumentasyon ng API. Kung pupunta ka sa
web site ng proyekto, ns-3 proyekto, makakahanap ka ng link sa "Dokumentasyon" sa nabigasyon
bar. Kung pipiliin mo ang link na ito, dadalhin ka sa aming pahina ng dokumentasyon. Meron isang
link sa "Latest Release" na magdadala sa iyo sa dokumentasyon para sa pinakabagong stable
release ng ns-3. Kung pipiliin mo ang link na "API Documentation," dadalhin ka sa
ns-3 Pahina ng dokumentasyon ng API.
Sa sidebar dapat mong makita ang isang hierachy na magsisimula
· ns-3
· ns-3 Dokumentasyon
· Lahat ng TraceSources
· Lahat ng Katangian
· Lahat ng GlobalValues
Ang listahan ng mga interes sa amin dito ay "All TraceSources". Sige at piliin ang link na iyon.
Makakakita ka, marahil hindi masyadong nakakagulat, isang listahan ng lahat ng mga bakas na mapagkukunan na magagamit
in ns-3.
Bilang halimbawa, mag-scroll pababa sa ns3::MobilityModel. Makakakita ka ng entry para sa
CourseChange: Ang halaga ng posisyon at/o velocity vector ay nagbago
Dapat mong kilalanin ito bilang trace source na ginamit namin sa pangatlo.cc halimbawa. Nagmamasid
makatutulong ang listahang ito.
config Landas
Sige, I natagpuan a kopyahin o sipiin sa pamamagitan ng pag-aninag mapagkukunan, paano do I malaman Palabas ang config landas sa gamitin kailan I ikabit sa
ito?
Kung alam mo kung saang bagay ka interesado, ang seksyong "Detalyadong Paglalarawan" para sa
ililista ng klase ang lahat ng available na trace source. Halimbawa, simula sa listahan ng "Lahat
TraceSources," mag-click sa ns3::MobilityModel link, na magdadala sa iyo sa
dokumentasyon para sa MobilityModel klase. Halos sa tuktok ng pahina ay isang linya
maikling paglalarawan ng klase, na nagtatapos sa isang link na "Higit pa...". Mag-click sa link na ito upang laktawan
ang buod ng API at pumunta sa "Detalyadong Paglalarawan" ng klase. Sa dulo ng
ang paglalarawan ay magiging (hanggang sa) tatlong listahan:
· config Landas: isang listahan ng mga tipikal na Config path para sa klase na ito.
· katangian: isang listahan ng lahat ng attribute na ibinigay ng klase na ito.
· TraceSources: isang listahan ng lahat ng TraceSources na makukuha mula sa klase na ito.
Tatalakayin muna natin ang mga path ng Config.
Ipagpalagay natin na kakahanap mo lang ng "CourseChange" trace source sa "All
TraceSources" at gusto mong malaman kung paano kumonekta dito. Alam mo na ikaw iyon
gamit (muli, mula sa pangatlo.cc halimbawa) isang ns3::RandomWalk2dMobilityModel. Kaya alinman
mag-click sa pangalan ng klase sa listahan ng "Lahat ng TraceSources," o hanapin
ns3::RandomWalk2dMobilityModel sa "Listahan ng Klase". Alinmang paraan dapat ay naghahanap ka na ngayon
sa pahina ng "ns3::RandomWalk2dMobilityModel Class Reference".
Kung mag-scroll ka na ngayon pababa sa seksyong "Detalyadong Paglalarawan", pagkatapos ng listahan ng buod ng
mga pamamaraan at katangian ng klase (o i-click lamang ang link na "Higit pa..." sa dulo ng klase
maikling paglalarawan sa tuktok ng pahina) makikita mo ang pangkalahatang dokumentasyon para sa
klase. Sa patuloy na pag-scroll pababa, hanapin ang listahan ng "Config Paths":
config Landas
ns3::RandomWalk2dMobilityModel ay naa-access sa pamamagitan ng mga sumusunod na landas na may
Config::Itakda at Config::Kumonekta:
· "/NodeList/[i]/$ns3::MobilityModel/$ns3::RandomWalk2dMobilityModel"
Sinasabi sa iyo ng dokumentasyon kung paano makarating sa RandomWalk2dMobilityModel bagay. Ikumpara
ang string sa itaas kasama ang string na aktwal naming ginamit sa halimbawang code:
"/NodeList/7/$ns3::MobilityModel"
Ang pagkakaiba ay dahil sa katotohanan na dalawa GetObject ang mga tawag ay ipinahiwatig sa string na natagpuan
sa dokumentasyon. Ang una, para sa $ns3::MobilityModel itatanong ang pagsasama-sama para sa
ang batayang klase. Ipinahiwatig ng pangalawa GetObject tawag, para $ns3::RandomWalk2dMobilityModel,
ay ginagamit upang ihagis ang batayang klase sa kongkretong klase ng pagpapatupad. Ang dokumentasyon
ipinapakita ang parehong mga pagpapatakbong ito para sa iyo. Lumalabas na ikaw ang aktwal na pinagmumulan ng bakas
hinahanap ay matatagpuan sa base class.
Tumingin pa sa ibaba sa seksyong "Detalyadong Paglalarawan" para sa listahan ng mga pinagmumulan ng bakas.
Mahahanap mo
Walang TraceSources ang tinukoy para sa ganitong uri.
TraceSources tinukoy in magulang klase ``ns3::MobilityModel``
· Pagbabago ng Kurso: Nagbago ang halaga ng posisyon at/o velocity vector.
Lagda ng callback: ns3::MobilityModel::CourseChangeCallback
Ito mismo ang kailangan mong malaman. Ang bakas na pinagmulan ng interes ay matatagpuan sa
ns3::MobilityModel (na alam mo pa rin). Ang kagiliw-giliw na bagay na ito bit ng API
Sinasabi sa iyo ng dokumentasyon na hindi mo kailangan ang dagdag na cast na iyon sa config path sa itaas
pumunta sa kongkretong klase, dahil ang trace source ay talagang nasa base class.
Samakatuwid ang karagdagang GetObject ay hindi kinakailangan at ginagamit mo lang ang landas:
"/NodeList/[i]/$ns3::MobilityModel"
na perpektong tumutugma sa halimbawang landas:
"/NodeList/7/$ns3::MobilityModel"
Bilang isang tabi, ang isa pang paraan upang mahanap ang path ng Config ay ang grep sa paligid ng ns-3 codebase
para sa isang taong nakaisip na nito. Dapat mong subukang kumopya palagi ng iba
gumaganang code bago ka magsimulang magsulat ng iyong sarili. Subukan ang isang bagay tulad ng:
$ hanapin . -pangalan '*.cc' | xargs grep CourseChange | grep Connect
at maaari mong mahanap ang iyong sagot kasama ng gumaganang code. Halimbawa, sa kasong ito,
src/mobility/examples/main-random-topology.cc may naghihintay lang na gamitin mo:
Config::Connect ("/NodeList/*/$ns3::MobilityModel/CourseChange",
MakeCallback (&CourseChange));
Babalik tayo sa halimbawang ito sa ilang sandali.
Callback Mga lagda
Sige, I natagpuan a kopyahin o sipiin sa pamamagitan ng pag-aninag pinagmulan at ang config landas, paano do I malaman Palabas Ano ang pagbabalik uri
at pormal argumento of my callback tungkulin kailangan sa maging?
Ang pinakamadaling paraan ay suriin ang callback signature typedef, na ibinibigay sa
"Callback signature" ng trace source sa "Detalyadong Paglalarawan" para sa klase, bilang
Naipakita sa taas.
Inuulit ang "CourseChange" trace source entry mula sa ns3::RandomWalk2dMobilityModel we
mayroon:
· Pagbabago ng Kurso: Nagbago ang halaga ng posisyon at/o velocity vector.
Lagda ng callback: ns3::MobilityModel::CourseChangeCallback
Ang pirma ng callback ay ibinibigay bilang isang link sa nauugnay typedef, kung saan tayo matatagpuan
typedef walang bisa (* CourseChangeCallback)(const std::string konteksto, Ptr
MobilityModel> * modelo);
TracedCallback lagda para sa mga abiso sa pagbabago ng kurso.
Kung nakakonekta ang callback gamit ang ConnectWithoutContext alisin ang kaugnay na kahulugan argumento mula sa
ang pirma.
parameter:
[sa] konteksto Ang string ng konteksto na ibinigay ng pinagmulan ng Trace.
[sa] modelo Ang MobilityModel na nagbabago ng kurso.
Gaya ng nasa itaas, para makita itong ginagamit grep sa paligid ng ns-3 codebase para sa isang halimbawa. Ang halimbawa
sa itaas, mula sa src/mobility/examples/main-random-topology.cc, nag-uugnay sa "CourseChange"
bakas ang pinagmulan sa Pagbabago ng Kurso function sa parehong file:
static na walang bisa
CourseChange (std::string context, Ptr modelo)
{
...
}
Pansinin na ang function na ito:
· Kumuha ng argumentong string na "konteksto", na ilalarawan namin sa isang minuto. (Kung ang callback
ay konektado gamit ang ConnectWithoutContext gumana ang kaugnay na kahulugan magiging argumento
tinanggal.)
· Ay mayroong MobilityModel ibinibigay bilang huling argumento (o argumento lamang kung
ConnectWithoutContext Ginagamit).
· Pagbabalik walang bisa.
Kung, kung nagkataon, ang pirma ng callback ay hindi naidokumento, at walang mga halimbawa para dito
magtrabaho mula sa, ang pagtukoy sa tamang pirma ng function ng callback ay maaaring, mabuti, mahirap gawin
talagang malaman mula sa source code.
Bago magsimula sa isang walkthrough ng code, magpapakabait ako at sasabihin ko lang sa iyo ang isang simpleng paraan
para malaman ito: Ang ibabalik na halaga ng iyong callback ay palaging magiging walang bisa. Ang pormal
listahan ng parameter para sa a TracedCallback ay matatagpuan mula sa listahan ng parameter ng template sa
deklarasyon. Alalahanin na para sa aming kasalukuyang halimbawa, ito ay nasa mobility-model.h, kung saan tayo
dati nang natagpuan:
TracedCallback > m_courseChangeTrace;
Mayroong isa-sa-isang pagsusulatan sa pagitan ng listahan ng parameter ng template sa
deklarasyon at ang mga pormal na argumento ng callback function. Narito, mayroong isa
parameter ng template, na isang Ptr MobilityModel>. Sinasabi nito sa iyo na kailangan mo ng isang
function na nagbabalik ng walang bisa at tumatagal ng a Ptr MobilityModel>. Halimbawa:
walang bisa
Pagbabago ng Kurso (Ptr modelo)
{
...
}
Iyon lang ang kailangan mo kung gusto mo Config::ConnectWithoutContext. Kung gusto mo ng konteksto,
kailangan mong i- Config::Kumonekta at gumamit ng Callback function na kumukuha ng string context, pagkatapos
ang mga argumento ng template:
walang bisa
CourseChange (const std::string context, Ptr modelo)
{
...
}
Kung nais mong matiyak na ang iyong CourseChangeCallback ang function ay makikita lamang sa iyong
lokal na file, maaari mong idagdag ang keyword statik at makabuo ng:
static na walang bisa
CourseChange (const std::string path, Ptr modelo)
{
...
}
na kung ano mismo ang ginamit namin sa pangatlo.cc Halimbawa.
Pagsasakatuparan
Ang seksyong ito ay ganap na opsyonal. Ito ay magiging isang malubak na biyahe, lalo na para sa mga iyon
hindi pamilyar sa mga detalye ng mga template. Gayunpaman, kung malalampasan mo ito, magkakaroon ka
isang napakahusay na hawakan sa marami sa ns-3 mababang antas ng mga idyoma.
Kaya, muli, alamin natin kung anong lagda ng callback function ang kinakailangan para sa
"CourseChange" trace source. Ito ay magiging masakit, ngunit kailangan mo lamang gawin ito
minsan. Pagkatapos mong malampasan ito, mapapatingin ka lang sa a TracedCallback at
intindihin mo.
Ang unang bagay na kailangan nating tingnan ay ang deklarasyon ng trace source. Tandaan mo yan
ito ay nasa mobility-model.h, kung saan dati naming nakita:
TracedCallback > m_courseChangeTrace;
Ang deklarasyon na ito ay para sa isang template. Ang parameter ng template ay nasa loob ng mga anggulo-bracket,
kaya talagang interesado kaming malaman kung ano iyon TracedCallback<> ay. Kung mayroon kang
ganap na walang ideya kung saan ito mahahanap, grep ang iyong kaibigan.
Marahil kami ay magiging interesado sa ilang uri ng deklarasyon sa ns-3 pinagmulan, kaya
unang pagbabago sa SRC direktoryo. Pagkatapos, alam nating kakailanganin ng deklarasyon na ito
nasa ilang uri ng header file, kaya lang grep para dito gamit ang:
$ hanapin . -pangalan '*.h' | xargs grep TracedCallback
Makakakita ka ng 303 na linya na lumipad (Ipinasa ko ito wc upang makita kung gaano ito kasama). Bagaman
na maaaring mukhang tulad ng isang pulutong, na hindi talaga marami. I-pipe lang ang output mas marami pang at
simulan ang pag-scan sa pamamagitan nito. Sa unang pahina, makikita mo ang ilan na napakahinala
bagay na mukhang template.
TracedCallback<T1,T2,T3,T4,T5,T6,T7,T8>::TracedCallback ()
TracedCallback<T1,T2,T3,T4,T5,T6,T7,T8>::ConnectWithoutContext (c ...
TracedCallback<T1,T2,T3,T4,T5,T6,T7,T8>::Connect (const CallbackB ...
TracedCallback<T1,T2,T3,T4,T5,T6,T7,T8>::DisconnectWithoutContext ...
TracedCallback<T1,T2,T3,T4,T5,T6,T7,T8>::Disconnect (const Callba ...
TracedCallback<T1,T2,T3,T4,T5,T6,T7,T8>::operator() (void) const ...
TracedCallback<T1,T2,T3,T4,T5,T6,T7,T8>::operator() (T1 a1) const ...
TracedCallback<T1,T2,T3,T4,T5,T6,T7,T8>::operator() (T1 a1, T2 a2 ...
TracedCallback<T1,T2,T3,T4,T5,T6,T7,T8>::operator() (T1 a1, T2 a2 ...
TracedCallback<T1,T2,T3,T4,T5,T6,T7,T8>::operator() (T1 a1, T2 a2 ...
TracedCallback<T1,T2,T3,T4,T5,T6,T7,T8>::operator() (T1 a1, T2 a2 ...
TracedCallback<T1,T2,T3,T4,T5,T6,T7,T8>::operator() (T1 a1, T2 a2 ...
TracedCallback<T1,T2,T3,T4,T5,T6,T7,T8>::operator() (T1 a1, T2 a2 ...
Lumalabas na ang lahat ng ito ay nagmula sa header file traced-callback.h na tunog
napaka-promising. Pagkatapos ay maaari mong tingnan mobility-model.h at makita na may linya
na nagpapatunay sa haka-haka na ito:
#include "ns3/traced-callback.h"
Siyempre, maaari kang pumunta dito mula sa kabilang direksyon at nagsimula sa pamamagitan ng pagtingin
ang kasama sa mobility-model.h at mapansin ang kasama ng traced-callback.h at
inferring na ito dapat ang file na gusto mo.
Sa alinmang kaso, ang susunod na hakbang ay tingnan src/core/model/traced-callback.h in
ang iyong paboritong editor upang makita kung ano ang nangyayari.
Makakakita ka ng komento sa itaas ng file na dapat ay nakaaaliw:
Ang isang ns3::TracedCallback ay may halos eksaktong parehong API tulad ng isang normal na ns3::Callback ngunit
sa halip na magpasa ng mga tawag sa iisang function (tulad ng karaniwang ginagawa ng ns3::Callback),
nagpapasa ito ng mga tawag sa isang chain ng ns3::Callback.
Ito ay dapat na pamilyar na pamilyar at ipaalam sa iyo na ikaw ay nasa tamang landas.
Pagkatapos lamang ng komentong ito, mahahanap mo
template
typename T3 = walang laman, typename T4 = walang laman,
typename T5 = walang laman, typename T6 = walang laman,
typename T7 = walang laman, typename T8 = walang laman>
klase TracedCallback
{
...
Sinasabi nito sa iyo na ang TracedCallback ay isang naka-template na klase. Mayroon itong walong posibleng uri
mga parameter na may mga default na halaga. Bumalik at ihambing ito sa deklarasyon na ikaw ay
sinusubukang maunawaan:
TracedCallback > m_courseChangeTrace;
Ang typename T1 sa template na deklarasyon ng klase ay tumutugma sa Ptr
MobilityModel> sa deklarasyon sa itaas. Ang lahat ng iba pang mga parameter ng uri ay naiwan bilang
mga default. Ang pagtingin sa tagabuo ay talagang hindi nagsasabi sa iyo ng marami. Ang isang lugar kung saan
nakakita ka ng koneksyon na ginawa sa pagitan ng iyong Callback function at ang tracing system ay
nasa Ikabit at ConnectWithoutContext mga function. Kung mag-scroll ka pababa, makikita mo ang isang
ConnectWithoutContext pamamaraan dito:
template
typename T3, typename T4,
typename T5, typename T6,
typename T7, typename T8>
walang bisa
TracedCallback<T1,T2,T3,T4,T5,T6,T7,T8>::ConnectWithoutContext ...
{
Callback<void,T1,T2,T3,T4,T5,T6,T7,T8> cb;
cb.Magtalaga (callback);
m_callbackList.push_back (cb);
}
Ikaw ngayon ay nasa tiyan ng halimaw. Kapag na-instantiate ang template para sa
deklarasyon sa itaas, papalitan ng compiler T1 sa Ptr MobilityModel>.
walang bisa
TracedCallback ::ConnectWithoutContext ... cb
{
Callback > cb;
cb.Magtalaga (callback);
m_callbackList.push_back (cb);
}
Makikita mo na ngayon ang pagpapatupad ng lahat ng pinag-uusapan natin. Ang code
lumilikha ng isang Callback ng tamang uri at itinalaga ang iyong function dito. Ito ang
katumbas ng pfi = MyFunction tinalakay natin sa simula ng bahaging ito. Ang code
pagkatapos ay idaragdag ang Callback sa listahan ng Mga Callback para sa pinagmulang ito. Ang tanging natitira ay
upang tingnan ang kahulugan ng Callback. Gamit ang pareho grep panlilinlang gaya ng dati nating hinahanap
TracedCallback, mahahanap mo na ang file ./core/callback.h ay ang tayo
kailangan tingnan.
Kung titingnan mo sa ibaba ang file, makikita mo ang maraming malamang na halos hindi maintindihan
template code. Makakarating ka sa ilang API Documentation para sa Callback
klase ng template, bagaman. Sa kabutihang palad, mayroong ilang Ingles:
Callback klase ng template.
Ang template ng klase na ito ay nagpapatupad ng Functor Design Pattern. Ito ay ginagamit upang ipahayag ang
uri ng a Callback:
· kinakatawan ng unang hindi opsyonal na argumento ng template ang uri ng pagbabalik ng callback.
· ang reminaining (opsyonal) na mga argumento ng template ay kumakatawan sa uri ng kasunod
mga argumento sa callback.
· hanggang siyam na argumento ang sinusuportahan.
Sinusubukan naming malaman kung ano ang
Callback > cb;
ibig sabihin ng deklarasyon. Ngayon ay nasa posisyon na tayo upang maunawaan na ang una (hindi opsyonal)
argumento ng template, walang bisa, ay kumakatawan sa uri ng pagbabalik ng Callback. Ang ikalawa
(opsyonal) template argumento, Ptr MobilityModel> kumakatawan sa uri ng una
argumento sa callback.
Ang Callback na pinag-uusapan ay ang iyong function upang matanggap ang mga trace na kaganapan. Mula dito magagawa mo
ipahiwatig na kailangan mo ng isang function na nagbabalik walang bisa at kumukuha ng a Ptr MobilityModel>.
Halimbawa,
walang bisa
CourseChangeCallback (Ptr modelo)
{
...
}
Iyon lang ang kailangan mo kung gusto mo Config::ConnectWithoutContext. Kung gusto mo ng konteksto,
kailangan mong i- Config::Kumonekta at gumamit ng Callback function na kumukuha ng konteksto ng string. Ito
ay dahil ang Ikabit ang function ay magbibigay ng konteksto para sa iyo. Kakailanganin mo:
walang bisa
CourseChangeCallback (std::konteksto ng string, Ptr modelo)
{
...
}
Kung nais mong matiyak na ang iyong CourseChangeCallback ay makikita lamang sa iyong lokal na file,
maaari mong idagdag ang keyword statik at makabuo ng:
static na walang bisa
CourseChangeCallback (std::string path, Ptr modelo)
{
...
}
na kung ano mismo ang ginamit namin sa pangatlo.cc halimbawa. Marahil ay dapat kang bumalik ngayon at
basahin muli ang nakaraang seksyon (Take My Word for It).
Kung interesado ka sa higit pang mga detalye tungkol sa pagpapatupad ng Mga Callback, huwag mag-atubiling
upang tingnan ang ns-3 manwal. Ang mga ito ay isa sa mga pinaka-madalas na ginagamit na mga konstruksyon sa
ang mababang antas ng mga bahagi ng ns-3. Ito ay, sa aking opinyon, isang medyo eleganteng bagay.
TracedValues
Mas maaga sa seksyong ito, ipinakita namin ang isang simpleng piraso ng code na gumamit ng a
TracedValue upang ipakita ang mga pangunahing kaalaman ng tracing code. Nag-gloss over lang kami
ang kung ano talaga ang isang TracedValue at kung paano hanapin ang uri ng pagbabalik at mga pormal na argumento para sa
ang callback.
Tulad ng nabanggit namin, ang file, traced-value.h nagdadala ng mga kinakailangang deklarasyon para sa pagsubaybay
ng data na sumusunod sa value semantics. Sa pangkalahatan, ang value semantics ay nangangahulugan lamang na kaya mo
ipasa ang mismong bagay sa paligid, sa halip na ipasa ang address ng bagay. Extend tayo
na kinakailangang isama ang buong hanay ng mga operator na may istilo ng pagtatalaga
paunang natukoy para sa mga uri ng plain-old-data (POD):
.
│operator= (assignment) │ │
├────────────────────────────────────────────────․․
│operator*= │ operator/= │
├────────────────────────────────────────────────․․
│operator+= │ operator-= │
├────────────────────────────────────────────────․․
│operator++ (parehong prefix at │ │
│postfix) │ │
├────────────────────────────────────────────────․․
│operator-- (parehong prefix at │ │
│postfix) │ │
├────────────────────────────────────────────────․․
│operator<<= │ operator>>= │
├────────────────────────────────────────────────․․
│operator&= │ operator|= │
├────────────────────────────────────────────────․․
│operator%= │ operator^= │
└────────────────────────────────────────────────‴‴─
Ang talagang ibig sabihin ng lahat ng ito ay masusubaybayan mo ang lahat ng pagbabagong ginawa gamit ang mga iyon
operator sa isang C++ object na may value semantics.
Ang TracedValue<> deklarasyon na nakita natin sa itaas ay nagbibigay ng imprastraktura na labis na karga sa
mga operator na binanggit sa itaas at nagtutulak sa proseso ng callback. Sa paggamit ng alinman sa mga operator
sa itaas na may a TracedValue ibibigay nito ang luma at bagong halaga ng variable na iyon,
sa kasong ito an int32_t halaga. Sa pamamagitan ng inspeksyon ng TracedValue deklarasyon, alam natin ang
Ang trace sink function ay magkakaroon ng mga argumento (const int32_t oldValue, const int32_t newValue).
Ang uri ng pagbabalik para sa a TracedValue Ang callback function ay palaging walang bisa, kaya ang inaasahan
Ang pirma ng callback ay:
void (* TracedValueCallback)(const int32_t oldValue, const int32_t newValue);
Ang .AddTraceSource nasa GetTypeId Ang pamamaraan ay nagbibigay ng "mga kawit" na ginagamit para sa pagkonekta sa
bakas ang pinagmulan sa labas ng mundo sa pamamagitan ng Config system. Napag-usapan na namin ang
unang tatlong agruments sa AddTraceSource: ang pangalan ng Attribute para sa Config system, isang tulong
string, at ang address ng TracedValue class data member.
Ang huling string argument, "ns3::Traced::Value::Int32" sa halimbawa, ay ang pangalan ng isang
typedef para sa pirma ng function ng callback. Kinakailangan naming tukuyin ang mga lagdang ito,
at ibigay ang ganap na kwalipikadong pangalan ng uri sa AddTraceSource, kaya magagawa ng dokumentasyon ng API
mag-link ng trace source sa function signature. Para sa TracedValue ang lagda ay
prangka; para sa TracedCallbacks nakita na namin na talagang nakakatulong ang mga doc ng API.
tunay halimbawa
Gumawa tayo ng isang halimbawang kinuha mula sa isa sa mga pinakakilalang aklat sa TCP sa paligid. "TCP/IP
Illustrated, Volume 1: The Protocols," by W. Richard Stevens is a classic. Binaliktad ko lang
binuksan ang aklat at tumakbo sa isang magandang plot ng parehong window ng congestion at sequence
mga numero laban sa oras sa pahina 366. Tinatawag ito ni Stevens, "Figure 21.10. Halaga ng cwnd at
send sequence number while data is being transmitted." Gawin na lang natin ang cwnd part
ng plot na iyon sa ns-3 gamit ang tracing system at gnplot.
Magagamit Pinagmumulan ng
Ang unang bagay na dapat isipin ay kung paano namin gustong ilabas ang data. Ano ba tayo
kailangan i-trace? Kaya tingnan natin ang listahan ng "All Trace Sources" para makita kung ano ang dapat nating gawin
kasama. Alalahanin na ito ay matatagpuan sa ns-3 Dokumentasyon ng API. Kung mag-scroll ka sa
listahan, makikita mo sa kalaunan:
ns3::TcpNewReno
· CongestionWindow: Ang window ng congestion ng TCP connection
· SlowStartThreshold: TCP mabagal na pagsisimula threshold (bytes)
Ito ay lumiliko out na ang ns-3 Ang pagpapatupad ng TCP ay nabubuhay (karamihan) sa file
src/internet/model/tcp-socket-base.cc habang ang mga variant ng congestion control ay nasa mga file tulad
as src/internet/model/tcp-newreno.cc. Kung hindi mo alam ito a priori, maaari mong gamitin ang
recursive grep panlilinlang:
$ hanapin . -pangalan '*.cc' | xargs grep -i tcp
Makakakita ka ng pahina pagkatapos ng pahina ng mga pagkakataon ng tcp na nagtuturo sa iyo sa file na iyon.
Pagpapalabas ng dokumentasyon ng klase para sa TcpNewReno at paglaktaw sa listahan ng
Mga TraceSources na makikita mo
TraceSources
· CongestionWindow: Ang window ng congestion ng koneksyon ng TCP
Lagda ng callback: ns3::Traced::Value::Uint322Callback
Pag-click sa callback typedef link na nakikita namin ang lagda na alam mo na ngayong aasahan:
typedef void(* ns3::Traced::Value::Int32Callback)(const int32_t oldValue, const int32_t newValue)
Dapat mo na ngayong lubos na maunawaan ang code na ito. Kung mayroon tayong pointer sa TcpNewReno,
magagawa namin TraceConnect sa trace source na "CongestionWindow" kung magbibigay kami ng naaangkop
target ng callback. Ito ang parehong uri ng trace source na nakita natin sa simpleng halimbawa
sa simula ng seksyong ito, maliban sa pinag-uusapan natin uint32_t sa halip ng
int32_t. At alam namin na kailangan naming magbigay ng callback function na may signature na iyon.
Pagkatuklas Mga halimbawa
Laging pinakamahusay na subukan at maghanap ng gumaganang code na nakalagay sa paligid na maaari mong baguhin, sa halip
kaysa magsimula sa simula. Kaya ang unang pagkakasunud-sunod ng negosyo ngayon ay ang paghahanap ng ilang code na iyon
na hook na ang "CongestionWindow" trace source at tingnan kung maaari naming baguhin ito. Gaya ng dati,
grep ay ang iyong kaibigan:
$ hanapin . -pangalan '*.cc' | xargs grep CongestionWindow
Ito ay magtuturo ng ilang mga promising na kandidato: mga halimbawa/tcp/tcp-large-transfer.cc
at src/test/ns3tcp/ns3tcp-cwnd-test-suite.cc.
Hindi pa namin nabisita ang alinman sa test code, kaya tingnan natin doon. gagawin mo
karaniwang nakikita na ang test code ay medyo minimal, kaya ito ay malamang na isang napakagandang taya.
Pagbubukas src/test/ns3tcp/ns3tcp-cwnd-test-suite.cc sa iyong paboritong editor at hanapin
"CongestionWindow". Mahahanap mo,
ns3TcpSocket->TraceConnectWithoutContext ("CongestionWindow",
MakeCallback (&Ns3TcpCwndTestCase1::CwndChange, ito));
Ito ay dapat mukhang napaka pamilyar sa iyo. Nabanggit namin sa itaas na kung mayroon kaming pointer sa
TcpNewReno, kaya namin TraceConnect sa "CongestionWindow" trace source. Ganyan talaga
kung ano ang mayroon tayo dito; kaya lumalabas na ginagawa ng linyang ito ng code ang eksaktong gusto natin.
Sige at kunin natin ang code na kailangan natin mula sa function na ito (Ns3TcpCwndTestCase1::DoRun
(walang bisa)). Kung titingnan mo ang function na ito, makikita mo na ito ay parang isang ns-3
iskrip. Ito ay lumabas na kung ano talaga ito. Ito ay isang script na pinapatakbo ng pagsubok
framework, para mabunot lang natin ito at ibalot pangunahin sa halip na sa DoRun. sa halip
kaysa sa paglalakad dito, hakbang-hakbang, ibinigay namin ang file na nagreresulta mula sa pag-port
ang pagsusulit na ito ay bumalik sa isang katutubo ns-3 script -- mga halimbawa/tutorial/fifth.cc.
Dynamic Kopyahin o sipiin sa pamamagitan ng pag-aninag Pinagmumulan ng
Ang ikalima.cc ang halimbawa ay nagpapakita ng isang napakahalagang tuntunin na dapat mong maunawaan
bago gumamit ng anumang uri ng trace source: dapat mong tiyakin na ang target ng a
Config::Kumonekta umiiral ang utos bago subukang gamitin ito. Ito ay walang pinagkaiba sa sinasabi
ang isang bagay ay dapat ma-instantiate bago subukang tawagan ito. Kahit na ito ay maaaring mukhang halata
kapag sinabi sa ganitong paraan, ito ay trip up ng maraming mga tao na sinusubukang gamitin ang system para sa unang
time.
Bumalik tayo sa pangunahing kaalaman sandali. Mayroong tatlong pangunahing yugto ng pagpapatupad na umiiral sa
anumang ns-3 iskrip. Ang unang yugto ay tinatawag na "Oras ng Pag-configure" o "Pag-setup
Oras," at umiiral sa panahon kung kailan ang pangunahin gumagana ang iyong script, ngunit
bago Simulator::Tumakbo ay tinatawag na. Ang pangalawang yugto ay tinatawag minsan na "Oras ng Simulation"
at umiiral sa panahon ng panahon kung kailan Simulator::Tumakbo ay aktibong nagsasagawa ng mga kaganapan nito.
Pagkatapos nitong makumpleto ang pagsasagawa ng simulation, Simulator::Tumakbo ibabalik ang kontrol pabalik sa
ang pangunahin function. Kapag nangyari ito, ipinapasok ng script ang matatawag na "Teardown
Phase," na kung saan ang mga istruktura at bagay na nilikha sa panahon ng pag-setup ay pinaghiwalay at
pinakawalan.
Marahil ang pinakakaraniwang pagkakamali sa pagsubok na gamitin ang sistema ng pagsubaybay ay ang pag-aakalang iyon
mga entity na dynamic na binuo sa panahon ng kapanggapan oras ay magagamit sa panahon ng pagsasaayos
oras. Sa partikular, isang ns-3 Saksakan ay isang dynamic na bagay na kadalasang nilikha ng aplikasyon sa
makipag-usap sa pagitan ng Node, Sa ns-3 application laging may "Oras ng Pagsisimula" at "Stop
Oras" na nauugnay dito. Sa karamihan ng mga kaso, isang application hindi magtatangka
upang lumikha ng isang dynamic na bagay hanggang sa StartApplication Ang pamamaraan ay tinatawag sa ilang "Start
Oras". Ito ay upang matiyak na ang simulation ay ganap na na-configure bago ang app
sumusubok na gumawa ng anuman (ano ang mangyayari kung sinubukan nitong kumonekta sa isang Node na wala
pa sa panahon ng pagsasaayos?). Bilang resulta, sa yugto ng pagsasaayos, hindi mo magagawa
ikonekta ang isang trace source sa isang trace sink kung ang isa sa mga ito ay dynamic na nilikha sa panahon ng
kunwa
Ang dalawang solusyon sa connundrum na ito ay
1. Lumikha ng isang kaganapan sa simulator na pinapatakbo pagkatapos gawin ang dynamic na bagay at i-hook ang
bakas kung kailan naisakatuparan ang kaganapang iyon; o
2. Lumikha ng dynamic na bagay sa oras ng pagsasaayos, i-hook ito pagkatapos, at ibigay ang bagay sa
ang sistemang gagamitin sa panahon ng simulation.
Kinuha namin ang pangalawang diskarte sa ikalima.cc halimbawa. Ang desisyong ito ay nangangailangan sa amin na lumikha
ang Aking App application, ang buong layunin nito ay kumuha ng a Saksakan bilang parameter.
Walkthrough: ikalima.cc
Ngayon, tingnan natin ang halimbawang programa na aming binuo sa pamamagitan ng pag-dissect sa kasikipan
pagsubok sa bintana. Bukas mga halimbawa/tutorial/fifth.cc sa iyong paboritong editor. Dapat mong makita
ilang pamilyar na mukhang code:
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Ang program na ito ay libreng software; maaari mo itong muling ipamahagi at/o baguhin
* ito sa ilalim ng mga tuntunin ng GNU General Public License bersyon 2 bilang
* inilathala ng Free Software Foundation;
*
* Ang programang ito ay ipinamahagi sa pag-asa na ito ay magiging kapaki-pakinabang,
* ngunit WALANG ANUMANG WARRANTY; nang walang kahit na ipinahiwatig na warranty ng
* MERCHANTABILITY o FITNESS PARA SA ISANG PARTIKULAR NA LAYUNIN. Tingnan ang
* GNU General Public License para sa higit pang mga detalye.
*
* Dapat ay nakatanggap ka ng kopya ng GNU General Public License
* kasama ng programang ito; kung hindi, sumulat sa Libreng Software
* Foundation, Include., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#isama
#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/internet-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/applications-module.h"
gamit ang namespace ns3;
NS_LOG_COMPONENT_DEFINE ("FifthScriptExample");
Natakpan na ang lahat ng ito, kaya hindi na namin ito uulitin. Ang mga susunod na linya ng pinagmulan ay ang
paglalarawan ng network at isang komentong tumutugon sa problemang inilarawan sa itaas gamit ang Saksakan.
// ================================================== ============================
//
// node 0 node 1
// +----------------+ +----------------+
// | ns-3 TCP | | ns-3 TCP |
// +----------------+ +----------------+
// | 10.1.1.1 | | 10.1.1.2 |
// +----------------+ +----------------+
// | point-to-point | | point-to-point |
// +----------------+ +----------------+
// | |
// +----------------------+
// 5 Mbps, 2 ms
//
//
// Gusto naming tingnan ang mga pagbabago sa ns-3 TCP congestion window. Kailangan namin
// para i-crank up ang isang flow at i-hook ang CongestionWindow attribute sa socket
// ng nagpadala. Karaniwan ang isa ay gagamit ng isang on-off na application upang makabuo ng isang
// daloy, ngunit mayroon itong ilang problema. Una, ang socket ng on-off
// Ang application ay hindi nilikha hanggang sa oras ng Pagsisimula ng Application, kaya hindi tayo magiging
// nakakabit sa socket (ngayon) sa oras ng pagsasaayos. Pangalawa, kahit tayo
// ay maaaring ayusin ang isang tawag pagkatapos ng oras ng pagsisimula, ang socket ay hindi pampubliko kaya namin
// hindi ko makuha.
//
// Kaya, maaari tayong magluto ng simpleng bersyon ng on-off na application na gumagawa ng kung ano
// gusto namin. Sa kalamangan, hindi namin kailangan ang lahat ng pagiging kumplikado ng on-off
// aplikasyon. Sa minus side, wala kaming katulong, kaya kailangan naming kumuha
// medyo kasangkot sa mga detalye, ngunit ito ay walang halaga.
//
// Kaya una, lumikha kami ng socket at gawin ang trace connect dito; tapos dumaan kami
// ang socket na ito sa constructor ng aming simpleng application na kung saan namin pagkatapos
// i-install sa source node.
// ================================================== ============================
//
Ito ay dapat ding maging maliwanag.
Ang susunod na bahagi ay ang deklarasyon ng Aking App application na pinagsama-sama natin upang payagan
ang Saksakan na gagawin sa oras ng pagsasaayos.
klase MyApp : pampublikong Aplikasyon
{
pampublikong:
MyApp ();
virtual ~MyApp();
void Setup (Ptr socket, Address address, uint32_t packetSize,
uint32_t nPackets, DataRate dataRate);
pribado:
virtual void StartApplication (walang bisa);
virtual void StopApplication (walang bisa);
walang bisa ScheduleTx (walang bisa);
walang bisa SendPacket (walang bisa);
Ptr m_socket;
Address m_peer;
uint32_t m_packetSize;
uint32_t m_nPackets;
DataRate m_dataRate;
EventId m_sendEvent;
bool m_running;
uint32_t m_packetsSent;
};
Makikita mo na ang klase na ito ay nagmana mula sa ns-3 application klase. Tingnan mo
src/network/model/application.h kung interesado ka sa kung ano ang minana. Ang Aking App
klase ay obligadong i-override ang StartApplication at StopApplication paraan. Ang mga ito
Ang mga pamamaraan ay awtomatikong tinatawag kapag Aking App ay kinakailangan upang simulan at ihinto ang pagpapadala ng data
sa panahon ng simulation.
Simula / Paghinto aplikasyon
Ito ay kapaki-pakinabang na gumugol ng kaunting oras na nagpapaliwanag kung paano aktwal na nagsimula ang mga kaganapan sa
sistema. Ito ay isa pang medyo malalim na paliwanag, at maaaring balewalain kung hindi
pagpaplano sa venturing down sa lakas ng loob ng sistema. Ito ay kapaki-pakinabang, gayunpaman, sa iyon
ang talakayan ay nakakaapekto sa kung paano ang ilang napakahalagang bahagi ng ns-3 trabaho at ilantad ang ilan
mahahalagang idyoma. Kung nagpaplano kang magpatupad ng mga bagong modelo, malamang na gusto mo
unawain ang seksyong ito.
Ang pinakakaraniwang paraan upang simulan ang mga kaganapan sa pumping ay upang simulan ang isang application. Ginagawa ito bilang
ang resulta ng mga sumusunod (sana) familar lines ng isang ns-3 script:
ApplicationContainer apps = ...
apps.Start (Secons (1.0));
apps.Stop (Secons (10.0));
Ang code ng container ng application (tingnan src/network/helper/application-container.h kung ikaw ay
interesado) umiikot sa mga nilalaman nitong aplikasyon at tawag,
app->SetStartTime (startTime);
bilang isang resulta ng apps.Start tawag at
app->SetStopTime (stopTime);
bilang isang resulta ng apps.Stop tawagan
Ang pinakahuling resulta ng mga tawag na ito ay gusto naming awtomatikong magkaroon ng simulator
tumawag sa aming aplikasyon para sabihin sa kanila kung kailan magsisimula at huminto. Sa kaso ng
Aking App, nagmana ito sa klase application at override StartApplication, at
StopApplication. Ito ang mga function na tatawagin ng simulator sa
tamang panahon. Sa kaso ng Aking App mahahanap mo yan MyApp::StartApplication ang
ang paunang Magbigkis, at Ikabit sa socket, at pagkatapos ay sisimulan ang pagdaloy ng data sa pamamagitan ng pagtawag
MyApp::SendPacket. MyApp::StopApplication hihinto sa pagbuo ng mga packet sa pamamagitan ng pagkansela ng anuman
nakabinbing magpadala ng mga kaganapan pagkatapos ay isasara ang socket.
Isa sa mga magagandang bagay tungkol sa ns-3 ay na maaari mong ganap na huwag pansinin ang pagpapatupad
mga detalye kung paano ang iyong application ay "awtomatikong" tinatawag ng simulator sa tama
oras. Pero dahil nakipagsapalaran na kami ng malalim ns-3 na, sige na.
Kung titingnan mo src/network/model/application.cc makikita mo na ang SetStartTime paraan
ng application nagtatakda lamang ng variable ng miyembro m_startTime at ang SetStopTime paraan
set lang m_stopTime. Mula doon, nang walang ilang pahiwatig, malamang na magtatapos ang landas.
Ang susi sa muling pagkuha sa trail ay ang malaman na mayroong isang pandaigdigang listahan ng lahat ng
mga node sa system. Sa tuwing gagawa ka ng node sa isang simulation, isang pointer sa Node na iyon
ay idinagdag sa global NodeList.
Bistahan src/network/model/node-list.cc at paghahanap para sa NodeList::Idagdag. Ang publiko
ang static na pagpapatupad ay tumatawag sa isang pribadong pagpapatupad na tinatawag NodeListPriv::Add. ito
ay isang medyo karaniwang idom sa ns-3. Kaya, tingnan mo NodeListPriv::Add. Ayan ka
hahanapin,
Simulator::ScheduleWithContext (index, TimeStep (0), &Node::Initialize, node);
Ito ay nagsasabi sa iyo na sa tuwing ang isang Node ay nilikha sa isang simulation, bilang isang side-effect, isang tawag
sa node na iyon magpasimula paraan ay naka-iskedyul para sa iyo na nangyayari sa oras na zero. huwag
basahin ang masyadong maraming sa pangalan na iyon, pa. Hindi ito nangangahulugan na ang Node ay magsisimulang gawin
anuman, maaari itong bigyang-kahulugan bilang isang tawag sa impormasyon sa Node na nagsasabi na ang
nagsimula na ang simulation, hindi isang tawag para sa aksyon na nagsasabi sa Node na magsimulang gumawa ng isang bagay.
Kaya NodeList::Idagdag hindi direktang nag-iskedyul ng tawag sa Node::Initialize sa oras na zero upang payuhan a
bagong Node na nagsimula na ang simulation. Kung titingnan mo src/network/model/node.h ikaw
ay, gayunpaman, ay hindi makakahanap ng isang pamamaraan na tinatawag Node::Initialize. Lumalabas na ang
magpasimula Ang pamamaraan ay minana mula sa klase Bagay. Ang lahat ng mga bagay sa system ay maaaring
aabisuhan kapag nagsimula ang simulation, at ang mga bagay ng class Node ay isang uri lamang ng mga iyon
mga bagay.
Bistahan src/core/model/object.cc susunod at hanapin Object::Initialize. Ang code na ito
ay hindi kasing diretso gaya ng inaasahan mo simula noon ns-3 bagay suportahan
pagsasama-sama. Ang code sa Object::Initialize pagkatapos ay i-loop sa lahat ng mga bagay na iyon
ay pinagsama-sama at tinatawag na kanilang DoInitialize paraan. Ito ay isa pang idyoma
na karaniwan sa ns-3, minsan tinatawag na "template design pattern.": isang publiko
non-virtual na paraan ng API, na nananatiling pare-pareho sa mga pagpapatupad, at tinatawag na a
pribadong virtual na paraan ng pagpapatupad na minana at ipinatupad ng mga subclass.
Ang mga pangalan ay karaniwang katulad MethodName para sa pampublikong API at DoMethodName para
ang pribadong API.
Sinasabi nito sa atin na dapat tayong maghanap ng a Node::DoInitialize pamamaraan sa
src/network/model/node.cc para sa pamamaraan na magpapatuloy sa ating landas. Kung mahahanap mo ang
code, makakahanap ka ng paraan na umiikot sa lahat ng device sa Node at pagkatapos
lahat ng mga application sa Node calling device->Initialize at application->Initialize
ayon sa pagkakabanggit.
Maaaring alam mo na ang mga klase Device at application parehong namamana sa klase Bagay
at kaya ang susunod na hakbang ay upang tingnan kung ano ang mangyayari kapag Application::DoInitialize is
tinawag. Tingnan mo src/network/model/application.cc at makikita mo:
walang bisa
Application::DoInitialize (walang bisa)
{
m_startEvent = Simulator::Iskedyul (m_startTime, &Application::StartApplication, ito);
kung (m_stopTime != TimeStep (0))
{
m_stopEvent = Simulator::Iskedyul (m_stopTime, &Application::StopApplication, ito);
}
Object::DoInitialize ();
}
Dito, sa wakas ay nakarating na kami sa dulo ng trail. Kung pinananatiling tuwid mo ang lahat, kapag ikaw
ipatupad ang isang ns-3 application, ang iyong bagong aplikasyon ay namamana mula sa klase application. Mo
override ang StartApplication at StopApplication pamamaraan at magbigay ng mga mekanismo para sa
pagsisimula at pagpapahinto sa daloy ng data mula sa iyong bago application. Kapag ang isang Node ay
nilikha sa simulation, ito ay idinagdag sa isang global NodeList. Ang pagkilos ng pagdaragdag ng isang Node sa
ito NodeList nagiging sanhi ng pag-iskedyul ng kaganapan sa simulator para sa time zero na tumatawag sa
Node::Initialize paraan ng bagong idinagdag na Node na tatawagin kapag nagsimula ang simulation.
Dahil ang isang Node ay nagmana mula sa Bagay, ito ay tinatawag na Object::Initialize pamamaraan sa Node
na, naman, ay tinatawag na DoInitialize pamamaraan sa lahat ng bagay pinagsama-sama sa
Node (isipin ang mga modelo ng kadaliang kumilos). Mula noong Node Bagay ay na-override DoInitialize, Na
Ang pamamaraan ay tinatawag kapag nagsimula ang simulation. Ang Node::DoInitialize tinatawag na pamamaraan ang
magpasimula pamamaraan ng lahat ng aplikasyon sa node. Since aplikasyon din ang mga
bagay, ito ay nadudulot Application::DoInitialize tatawagin. Kailan
Application::DoInitialize ay tinatawag na, ito ay nag-iskedyul ng mga kaganapan para sa StartApplication at
StopApplication tawag sa application. Ang mga tawag na ito ay idinisenyo upang simulan at ihinto ang
daloy ng datos mula sa application
Ito ay isa pang medyo mahabang paglalakbay, ngunit kailangan lang itong gawin nang isang beses, at ikaw na ngayon
maunawaan ang isa pang napakalalim na piraso ng ns-3.
Ang Aking App application
Ang Aking App application nangangailangan ng isang constructor at isang destructor, siyempre:
MyApp::MyApp ()
: m_socket (0),
m_peer (),
m_packetSize (0),
m_nPackets (0),
m_dataRate (0),
m_sendEvent (),
m_running (false),
m_packetsSent (0)
{
}
MyApp::~MyApp()
{
m_socket = 0;
}
Ang pagkakaroon ng susunod na bit ng code ay ang buong dahilan kung bakit namin ito isinulat application in
ang unang lugar.
walang bisa
MyApp::Setup (Ptr socket, Address address, uint32_t packetSize,
uint32_t nPackets, DataRate dataRate)
{
m_socket = socket;
m_peer = address;
m_packetSize = laki ng packet;
m_nPackets = nPackets;
m_dataRate = dataRate;
}
Ang code na ito ay dapat na medyo maliwanag. Sinisimulan lang namin ang mga variable ng miyembro.
Ang mahalaga mula sa pananaw ng pagsubaybay ay ang Ptr socket na tayo
kailangang ibigay sa application sa oras ng pagsasaayos. Tandaan na pupunta tayo
upang lumikha ng Saksakan bilang isang TcpSocket (na ipinatupad ng TcpNewReno) at i-hook nito
"CongestionWindow" trace source bago ipasa ito sa Setup pamamaraan.
walang bisa
MyApp::StartApplication (walang bisa)
{
m_running = totoo;
m_packetsSent = 0;
m_socket->Bind ();
m_socket->Connect (m_peer);
SendPacket ();
}
Ang code sa itaas ay ang overridden na pagpapatupad Application::StartApplication iyon ay
awtomatikong tinatawag ng simulator upang simulan ang aming application tumatakbo sa nararapat
oras. Maaari mong makita na ito ay a Saksakan Magbigkis operasyon. Kung pamilyar ka sa
Berkeley Sockets hindi ito dapat maging isang sorpresa. Ginagawa nito ang kinakailangang gawain sa lokal
gilid ng koneksyon tulad ng inaasahan mo. Ang mga sumusunod Ikabit gagawin kung ano ang
kinakailangan upang magtatag ng koneksyon sa TCP sa address m_peer. Dapat malinaw na ngayon
bakit kailangan nating ipagpaliban ang marami nito sa simulation time, dahil ang Ikabit ay kakailanganin
isang ganap na gumaganang network upang makumpleto. Pagkatapos ng Ikabit, ang application pagkatapos ay magsisimula
paglikha ng mga kaganapan sa simulation sa pamamagitan ng pagtawag SendPacket.
Ang susunod na bit ng code ay nagpapaliwanag sa application kung paano ihinto ang paggawa ng mga kaganapan sa simulation.
walang bisa
MyApp::StopApplication (walang bisa)
{
m_running = mali;
kung (m_sendEvent.IsRunning ())
{
Simulator::Kanselahin (m_sendEvent);
}
kung (m_socket)
{
m_socket->Isara ();
}
}
Sa tuwing may nakaiskedyul na kaganapan sa simulation, isang pangyayari ay nilikha. Kung ang pangyayari ay nakabinbin
pagpapatupad o pagpapatupad, ang pamamaraan nito Ay tumatakbo babalik totoo. Sa code na ito, kung
Ay tumatakbo() nagbabalik totoo, tayo kanselahin ang kaganapan na nag-aalis nito mula sa kaganapan ng simulator
pila. Sa paggawa nito, sinisira natin ang kadena ng mga kaganapan na ang application ay ginagamit upang panatilihin
nagpapadala nito Mga Packet at ang application tumahimik. Pagkatapos naming tahimik ang application we
Pagsasara ang socket na sumisira sa koneksyon ng TCP.
Ang socket ay talagang tinanggal sa destructor kapag ang m_socket = 0 ay pinaandar. Ito
inaalis ang huling sanggunian sa pinagbabatayan na Ptr na nagiging sanhi ng destructor ng
na Bagay na tatawagin.
Tandaan mo yan StartApplication tinatawag SendPacket upang simulan ang hanay ng mga pangyayari na naglalarawan
ang application pag-uugali.
walang bisa
MyApp::SendPacket (walang bisa)
{
Ptr packet = Lumikha (m_packetSize);
m_socket->Ipadala (packet);
kung (++m_packetsSent <m_nPackets)
{
ScheduleTx ();
}
}
Dito, nakikita mo iyon SendPacket ginagawa lang iyon. Lumilikha ito ng a Pakete at pagkatapos ay a magpadala
na, kung alam mo ang Berkeley Sockets, ay malamang na iyon lang ang inaasahan mong makita.
Ito ay pananagutan ng application upang mapanatili ang pag-iskedyul ng hanay ng mga kaganapan, kaya ang
tawag sa mga susunod na linya ScheduleTx upang mag-iskedyul ng isa pang kaganapan sa pagpapadala (a SendPacket) hanggang sa
application nagpasya na ito ay nagpadala ng sapat.
walang bisa
MyApp::ScheduleTx (walang bisa)
{
kung (m_running)
{
Oras tSusunod (Segundo (m_packetSize * 8 / static_cast (m_dataRate.GetBitRate ())));
m_sendEvent = Simulator::Iskedyul (tNext, &MyApp::SendPacket, ito);
}
}
Dito, nakikita mo iyon ScheduleTx ginagawa iyon nang eksakto. Kung ang application ay tumatakbo (kung
StopApplication ay hindi natawag) ito ay mag-iskedyul ng isang bagong kaganapan, na tumatawag SendPacket
muli. Ang alerto na mambabasa ay makakakita ng isang bagay na nakaka-trip din sa mga bagong user. Ang rate ng data
ng application yun lang. Wala itong kinalaman sa rate ng data ng isang pinagbabatayan
channel. Ito ang rate kung saan ang application gumagawa ng mga bits. Hindi nito pinapasok
isaalang-alang ang anumang overhead para sa iba't ibang mga protocol o channel na ginagamit nito upang dalhin ang
datos. Kung itatakda mo ang rate ng data ng isang application sa parehong rate ng data gaya ng iyong pinagbabatayan
channel sa kalaunan ay makakakuha ka ng buffer overflow.
Kopyahin o sipiin sa pamamagitan ng pag-aninag Sinks
Ang buong punto ng pagsasanay na ito ay upang makakuha ng mga trace callback mula sa TCP na nagpapahiwatig ng
na-update ang congestion window. Ang susunod na piraso ng code ay nagpapatupad ng kaukulang
bakas ng lababo:
static na walang bisa
CwndChange (uint32_t oldCwnd, uint32_t newCwnd)
{
NS_LOG_UNCOND (Simulator::Now ().GetSeconds () << "\t" << newCwnd);
}
Dapat ay napakapamilyar na nito sa iyo ngayon, kaya hindi na namin pag-uusapan ang mga detalye. Ang function na ito
nila-log lang ang kasalukuyang simulation time at ang bagong halaga ng congestion window bawat
oras na ito ay nagbago. Maaari mong isipin na maaari mong i-load ang resultang output
sa isang graphics program (gnuplot o Excel) at agad na makakita ng magandang graph ng
pag-uugali ng window ng kasikipan sa paglipas ng panahon.
Nagdagdag kami ng bagong trace sink para ipakita kung saan ibinabagsak ang mga packet. Magdaragdag kami ng error
modelo sa code na ito din, kaya gusto naming ipakita ito gumagana.
static na walang bisa
RxDrop (Ptr p)
{
NS_LOG_UNCOND ("RxDrop at " << Simulator::Now ().GetSeconds ());
}
Ang trace sink na ito ay ikokonekta sa "PhyRxDrop" trace source ng point-to-point
NetDevice. Ang trace source na ito ay gumagana kapag ang isang packet ay nalaglag ng pisikal na layer ng a
NetDevice. Kung liliko ka sa pinanggalingan
(src/point-to-point/model/point-to-point-net-device.cc) makikita mo na ang bakas na ito
tinutukoy ng pinagmulan PointToPointNetDevice::m_phyRxDropTrace. Kung titingnan mo
src/point-to-point/model/point-to-point-net-device.h para sa variable na miyembro na ito, gagawin mo
hanapin na ito ay idineklara bilang a TracedCallback Packet> >. Dapat itong sabihin sa iyo
na ang target ng callback ay dapat na isang function na nagbabalik ng walang bisa at tumatagal ng isang solong
parameter na a Ptr Packet> (ipagpalagay na ginagamit namin ConnectWithoutContext) -- lang
kung ano ang mayroon tayo sa itaas.
Pangunahin Programa
Ang sumusunod na code ay dapat na pamilyar sa iyo sa ngayon:
int
pangunahing (int argc, char *argv[])
{
NodeContainer node;
nodes.Lumikha (2);
PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
Mga aparatong NetDeviceContainer;
mga device = pointToPoint.Install (nodes);
Lumilikha ito ng dalawang node na may point-to-point na channel sa pagitan ng mga ito, tulad ng ipinapakita sa
paglalarawan sa simula ng file.
Ang susunod na ilang linya ng code ay nagpapakita ng bago. Kung masusubaybayan natin ang isang koneksyon na kumikilos
perpekto, hahantong tayo sa isang monotonically na pagtaas ng congestion window. Upang makita ang anuman
kagiliw-giliw na pag-uugali, talagang gusto naming ipakilala ang mga error sa link na mag-drop ng mga packet,
magdulot ng mga duplicate na ACK at mag-trigger ng mga mas kawili-wiling gawi ng window ng congestion.
ns-3 nagbibigay ng ErrorModel mga bagay na maaaring ikabit Channel. Ginagamit namin ang
RateErrorModel na nagpapahintulot sa amin na magpakilala ng mga error sa a channel sa isang ibinigay singil.
Ptr em = CreateObject ();
em->SetAttribute ("ErrorRate", DoubleValue (0.00001));
device.Get (1)->SetAttribute ("ReceiveErrorModel", PointerValue (em));
Ang code sa itaas ay nagpapatunay ng a RateErrorModel Bagay, at itinakda namin ang "ErrorRate" katangian
sa nais na halaga. Pagkatapos ay itinakda namin ang nagresultang instantiated RateErrorModel bilang pagkakamali
modelong ginamit ng point-to-point NetDevice. Magbibigay ito sa amin ng ilang muling pagpapadala at
gawing mas kawili-wili ang aming plot.
InternetStackHelper stack;
stack.Install (nodes);
Ipv4AddressHelper address;
address.SetBase ("10.1.1.0", "255.255.255.252");
Mga interface ng Ipv4InterfaceContainer = address.Magtalaga (mga device);
Ang code sa itaas ay dapat na pamilyar. Nag-i-install ito ng mga internet stack sa aming dalawang node at
lumilikha ng mga interface at nagtatalaga ng mga IP address para sa mga point-to-point na device.
Dahil gumagamit kami ng TCP, kailangan namin ng isang bagay sa destination Node upang makatanggap ng TCP
mga koneksyon at data. Ang PacketSink application ay karaniwang ginagamit sa ns-3 para doon
layunin.
uint16_t sinkPort = 8080;
Address sinkAddress (InetSocketAddress(interfaces.GetAddress (1), sinkPort));
PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory",
InetSocketAddress (Ipv4Address::GetAny (), sinkPort));
ApplicationContainer sinkApps = packetSinkHelper.Install (nodes.Get (1));
sinkApps.Start (Second (0.));
sinkApps.Stop (Secons (20.));
Dapat itong lahat ay pamilyar, maliban sa,
PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory",
InetSocketAddress (Ipv4Address::GetAny (), sinkPort));
Ang code na ito ay nagpapakita ng a PacketSinkHelper at sasabihin dito na lumikha ng mga socket gamit ang klase
ns3::TcpSocketFactory. Ang klase na ito ay nagpapatupad ng pattern ng disenyo na tinatawag na "pabrika ng bagay"
na isang karaniwang ginagamit na mekanismo para sa pagtukoy ng isang klase na ginagamit upang lumikha ng mga bagay sa isang
abstract na paraan. Dito, sa halip na likhain ang mga bagay mismo, ibibigay mo ang
PacketSinkHelper isang string na tumutukoy sa a TypeId string na ginamit upang lumikha ng isang bagay na
ay maaaring gamitin, sa turn, upang lumikha ng mga pagkakataon ng Mga Bagay na nilikha ng pabrika.
Ang natitirang parameter ay nagsasabi sa application kung aling address at port ito dapat Magbigkis sa.
Ang susunod na dalawang linya ng code ay gagawa ng socket at ikonekta ang trace source.
Ptr ns3TcpSocket = Socket::CreateSocket (nodes.Get (0),
TcpSocketFactory::GetTypeId ());
ns3TcpSocket->TraceConnectWithoutContext ("CongestionWindow",
MakeCallback (&CwndChange));
Tinatawag ng unang pahayag ang static na function ng miyembro Socket::Gumawa ngSocket at nagbibigay ng a
Node at isang tahasang TypeId para sa object factory na ginamit upang lumikha ng socket. Ito ay
bahagyang mas mababang antas ng tawag kaysa sa PacketSinkHelper tumawag sa itaas, at gumagamit ng isang tahasang C++
uri sa halip na isang tinutukoy ng isang string. Kung hindi, ito ay pareho sa konsepto
bagay.
Kapag ang TcpSocket ay nilikha at naka-attach sa Node, maaari naming gamitin
TraceConnectWithoutContext upang ikonekta ang trace source ng CongestionWindow sa aming trace sink.
Alalahanin na nag-code kami ng isang application para kunin natin iyon Saksakan ginawa lang namin (sa panahon ng
oras ng pagsasaayos) at gamitin ito sa oras ng simulation. Kailangan na nating i-instantiate iyon
application. Hindi kami nagkaproblema para gumawa ng katulong para pamahalaan ang application so
kailangan nating likhain at i-install ito nang "manu-mano". Ito ay talagang medyo madali:
Ptr app = CreateObject ();
app->Setup (ns3TcpSocket, sinkAddress, 1040, 1000, DataRate ("1Mbps"));
nodes.Get (0) -> AddApplication (app);
app->Start (Segundo (1.));
app->Stop (Segundo (20.));
Ang unang linya ay lumilikha ng isang Bagay ng uri Aking App -- aming application. Ang ikalawang linya ay nagsasabi
ang application Ano Saksakan gagamitin, saang address kumonekta, kung magkano ang data na ipapadala
bawat pagpapadala ng kaganapan, kung gaano karaming magpadala ng mga kaganapan upang bumuo at ang rate kung saan upang makagawa ng data
mula sa mga pangyayaring iyon.
Susunod, manu-mano naming idagdag ang Aking App application sa pinagmulang Node at tahasang tawagan ang
simula at Itigil mga pamamaraan sa application upang sabihin dito kung kailan magsisimula at itigil ang paggawa nito
bagay.
Kailangan talaga nating gawin ang pagkonekta mula sa receiver point-to-point NetDevice kaganapan sa pagbagsak
sa aming RxDrop callback ngayon.
mga device.Get (1)->TraceConnectWithoutContext("PhyRxDrop", MakeCallback (&RxDrop));
Dapat na malinaw na ngayon na nakakakuha tayo ng reference sa pagtanggap Node NetDevice
mula sa lalagyan nito at pagkonekta sa trace source na tinukoy ng attribute na "PhyRxDrop" sa
ang device na iyon sa trace sink RxDrop.
Sa wakas, sinasabi namin sa simulator na i-override ang anuman aplikasyon at itigil lamang ang pagproseso
mga kaganapan sa 20 segundo sa simulation.
Simulator::Tumigil (Segundo(20));
Simulator::Run ();
Simulator:: Wasakin ();
0 bumalik;
}
Tandaan na sa lalong madaling panahon Simulator::Tumakbo ay tinatawag, nagtatapos ang oras ng pagsasaayos, at simulation
nagsisimula ang oras. Lahat ng gawaing inayos namin sa pamamagitan ng paglikha ng application at itinuro ito
kung paano kumonekta at magpadala ng data ay aktwal na nangyayari sa panahon ng tawag sa function na ito.
Sa oras Simulator::Tumakbo bumalik, kumpleto na ang simulation at ipasok namin ang teardown
yugto. Sa kasong ito, Simulator:: Wasakin inaasikaso ang madugong mga detalye at babalik lang kami
isang success code pagkatapos nitong makumpleto.
Tumatakbo ikalima.cc
Dahil naibigay na namin ang file ikalima.cc para sa iyo, kung naitayo mo na ang iyong pamamahagi (sa
debug mode dahil ginagamit nito NS_LOG -- alalahanin na ang mga na-optimize na build ay nag-optimize NS_LOG) ito
maghihintay na tumakbo ka.
$ ./waf --run panglima
Waf: Pagpasok ng direktoryo `/home/craigdo/repos/ns-3-allinone-dev/ns-3-dev/build'
Waf: Umalis sa direktoryo `/home/craigdo/repos/ns-3-allinone-dev/ns-3-dev/build'
Matagumpay na natapos ang 'build' (0.684s)
1 536
1.0093 1072
1.01528 1608
1.02167 2144
...
1.11319 8040
1.12151 8576
1.12983 9112
RxDrop sa 1.13696
...
Malamang na makikita mo kaagad ang isang downside ng paggamit ng mga print ng anumang uri sa iyong mga bakas.
Nai-print namin ang mga extraneous na waf na mensaheng iyon sa kabuuan ng aming kawili-wiling impormasyon
gamit ang mga RxDrop na mensahe. Aayusin natin iyon sa lalong madaling panahon, ngunit sigurado ako na hindi ka makapaghintay na makita
ang mga resulta ng lahat ng gawaing ito. I-redirect natin ang output na iyon sa isang file na tinatawag cwnd.dat:
$ ./waf --run panglima > cwnd.dat 2>&1
Ngayon ay i-edit ang "cwnd.dat" sa iyong paboritong editor at alisin ang waf build status at i-drop
mga linya, na nag-iiwan lamang ng sinusubaybayang data (maaari mo ring ikomento ang
TraceConnectWithoutContext("PhyRxDrop", Gumawa ngCallback (&RxDrop)); sa script para maalis
ng mga drop print na kasingdali.
Maaari mo na ngayong patakbuhin ang gnuplot (kung na-install mo ito) at sabihin ito upang makabuo ng medyo maganda
mga larawan:
$ gnuplot
gnuplot> itakda ang terminal png laki na 640,480
gnuplot> itakda ang output "cwnd.png"
gnuplot> plot "cwnd.dat" gamit ang 1:2 na pamagat na 'Congestion Window' na may mga linespoint
gnuplot> lumabas
Dapat ay mayroon ka na ngayong graph ng window ng congestion kumpara sa oras na nakaupo sa file
"cwnd.png" loading="lazy" na mukhang:
[imahe]
paggamit Kalagitnaang lebel Mga tumutulong
Sa nakaraang seksyon, ipinakita namin kung paano mag-hook ng trace source at makakuha ng pag-asa
kawili-wiling impormasyon mula sa isang simulation. Marahil ay maaalala mo na tayo ay tumawag
pag-log sa karaniwang output gamit std::labas isang "mapurol na instrumento" mas maaga dito
kabanata. Sumulat din kami tungkol sa kung paano naging problema ang pag-parse ng output ng log sa pagkakasunud-sunod
upang ihiwalay ang mga kawili-wiling impormasyon. Baka naisip mo na gumastos lang tayo ng malaki
ng oras sa pagpapatupad ng isang halimbawa na nagpapakita ng lahat ng mga problema na inaakala naming ayusin
ang ns-3 sistema ng pagsubaybay! tama ka sana. Ngunit, tiisin mo kami. Hindi pa tayo tapos.
Isa sa mga pinakamahalagang bagay na gusto nating gawin ay ang magkaroon ng kakayahang madali
kontrolin ang dami ng output na lumalabas sa simulation; at gusto rin naming iligtas ang mga iyon
data sa isang file para ma-refer namin ito sa ibang pagkakataon. Magagamit natin ang mga mid-level na trace helper
ibinigay sa ns-3 upang gawin iyon at kumpletuhin ang larawan.
Nagbibigay kami ng script na nagsusulat ng cwnd change at drop na mga kaganapan na binuo sa halimbawa
ikalima.cc sa disk sa magkahiwalay na mga file. Ang mga pagbabago sa cwnd ay naka-imbak bilang isang tab-separated ASCII
file at ang mga drop event ay naka-store sa isang PCAP file. Ang mga pagbabago upang magawa ito ay
medyo maliit.
Walkthrough: ikaanim.cc
Tingnan natin ang mga pagbabagong kinakailangan upang pumunta mula sa ikalima.cc sa ikaanim.cc. Buksan
mga halimbawa/tutorial/sixth.cc sa iyong paboritong editor. Makikita mo ang unang pagbabago sa pamamagitan ng
naghahanap ng CwndChange. Malalaman mong binago namin ang mga pirma para sa bakas
lababo at nagdagdag ng isang linya sa bawat lababo na nagsusulat ng sinusubaybayang impormasyon sa a
stream na kumakatawan sa isang file.
static na walang bisa
CwndChange (Ptr stream, uint32_t oldCwnd, uint32_t newCwnd)
{
NS_LOG_UNCOND (Simulator::Now ().GetSeconds () << "\t" << newCwnd);
*stream->GetStream () << Simulator::Now ().GetSeconds () << "\t" << oldCwnd << "\t" << newCwnd << std::endl;
}
static na walang bisa
RxDrop (Ptr file, Ptr p)
{
NS_LOG_UNCOND ("RxDrop at " << Simulator::Now ().GetSeconds ());
file->Write(Simulator::Now(), p);
}
Nagdagdag kami ng parameter na "stream" sa CwndChange bakas lababo. Ito ay isang bagay na
humahawak (pinananatiling ligtas na buhay) isang C++ output stream. Ito ay lumiliko out na ito ay isang napaka-simple
object, ngunit isa na namamahala sa mga panghabambuhay na isyu para sa stream at nilulutas ang isang problema na kahit na
nakaranas ng mga user ng C++. Ito ay lumiliko out na ang kopya constructor para sa std::ostream
ay minarkahan ng pribado. Ibig sabihin nito std::ostreams huwag sundin ang halaga ng semantika at hindi maaaring
gamitin sa anumang mekanismo na nangangailangan ng stream na makopya. Kabilang dito ang ns-3
callback system, na kung maaalala mo, ay nangangailangan ng mga bagay na sumusunod sa value semantics.
Karagdagang paunawa na idinagdag namin ang sumusunod na linya sa CwndChange bakas lababo
pagpapatupad:
*stream->GetStream () << Simulator::Now ().GetSeconds () << "\t" << oldCwnd << "\t" << newCwnd << std::endl;
Ito ay magiging napakapamilyar na code kung papalitan mo *stream->GetStream () sa std::labasAng
sa:
std::cout << Simulator::Now ().GetSeconds () << "\t" << oldCwnd << "\t" << newCwnd << std::endl;
Ito ay naglalarawan na ang Ptr dala-dala lang talaga a
std::ofstream para sa iyo, at magagamit mo ito dito tulad ng iba pang stream ng output.
Ang isang katulad na sitwasyon ay nangyayari sa RxDrop maliban na ang bagay na ipinapasa sa paligid (a
Ptr) ay kumakatawan sa isang PCAP file. May isang one-liner sa trace sink sa
magsulat ng timestamp at ang mga nilalaman ng packet ay ibinabagsak sa PCAP file:
file->Write(Simulator::Now(), p);
Siyempre, kung mayroon kaming mga bagay na kumakatawan sa dalawang file, kailangan naming likhain ang mga ito sa isang lugar
at maging sanhi din ng mga ito na maipasa sa mga bakas na lababo. Kung titingnan mo sa pangunahin function,
makakahanap ka ng bagong code para gawin iyon:
AsciiTraceHelper asciiTraceHelper;
Ptr stream = asciiTraceHelper.CreateFileStream ("sixth.cwnd");
ns3TcpSocket->TraceConnectWithoutContext ("CongestionWindow", MakeBoundCallback (&CwndChange, stream));
...
PcapHelper pcapHelper;
Ptr file = pcapHelper.CreateFile ("sixth.pcap", std::ios::out, PcapHelper::DLT_PPP);
mga device.Get (1)->TraceConnectWithoutContext("PhyRxDrop", MakeBoundCallback (&RxDrop, file));
Sa unang seksyon ng code snippet sa itaas, ginagawa namin ang ASCII trace file,
paggawa ng object na responsable sa pamamahala nito at paggamit ng variant ng callback
function ng paglikha upang ayusin ang bagay na maipasa sa lababo. Ang aming ASCII trace
Ang mga katulong ay nagbibigay ng maraming hanay ng mga function upang gawing madali ang paggamit ng mga text (ASCII) na file. Tayo ay
pagpunta lamang upang ilarawan ang paggamit ng file stream ng paggawa ng function dito.
Ang Lumikha ngFileStream function ay karaniwang pagpunta sa instantiate a std::ofstream bagay at
lumikha ng isang bagong file (o putulin ang isang umiiral na file). Ito std::ofstream ay nakabalot sa isang
ns-3 object para sa panghabambuhay na pamamahala at kopyahin ang resolusyon ng isyu ng tagabuo.
Pagkatapos ay kunin namin ito ns-3 bagay na kumakatawan sa file at ipasa ito sa MakeBoundCallback().
Ang function na ito ay lumilikha ng isang callback tulad ng MakeCallback(), ngunit ito ay "nagbubuklod" ng isang bagong halaga sa
ang callback. Ang halagang ito ay idinaragdag bilang unang argumento sa callback bago ito
tinawag.
Mahalaga, MakeBoundCallback(&CwndChange, stream) nagiging dahilan upang idagdag ng trace source ang
karagdagang parameter na "stream" sa harap ng listahan ng pormal na parameter bago i-invoke
ang callback. Binabago nito ang kinakailangang lagda ng CwndChange lababo upang tumugma sa isa
ipinapakita sa itaas, na kinabibilangan ng "dagdag" na parameter Ptr daloy.
Sa pangalawang seksyon ng code sa snippet sa itaas, ginagawa namin ang a PcapHelper upang gawin ang
parehong bagay para sa aming PCAP trace file na ginawa namin sa AsciiTraceHelper. Ang linya ng
code,
Ptr file = pcapHelper.CreateFile ("sixth.pcap",
"w", PcapHelper::DLT_PPP);
lumilikha ng PCAP file na pinangalanang "sixth.pcap" na may file mode na "w". Nangangahulugan ito na ang bagong file
ay pinutol (tinanggal ang mga nilalaman) kung may nakitang umiiral na file na may ganoong pangalan. Ang final
Ang parameter ay ang "uri ng data link" ng bagong PCAP file. Ang mga ito ay pareho sa PCAP
tinukoy ang mga uri ng link ng data ng library sa bpf.h kung pamilyar ka sa PCAP. Sa kasong ito,
DLT_PPP ay nagpapahiwatig na ang PCAP file ay maglalaman ng mga packet na may prefix na point to
mga header ng punto. Totoo ito dahil ang mga packet ay nagmumula sa aming point-to-point na device
driver. Ang iba pang karaniwang uri ng link ng data ay DLT_EN10MB (10 MB Ethernet) na naaangkop para sa csma
mga device at DLT_IEEE802_11 (IEEE 802.11) na angkop para sa mga wifi device. Ang mga ito ay tinukoy
in src/network/helper/trace-helper.h kung interesado kang makita ang listahan. Ang
ang mga entry sa listahan ay tumutugma sa mga nasa bpf.h ngunit duplicate namin ang mga ito upang maiwasan ang pinagmulan ng PCAP
pagtitiwala.
A ns-3 bagay na kumakatawan sa PCAP file ay ibinalik mula sa CreateFile at ginamit sa isang bound
callback nang eksakto tulad ng nangyari sa ASCII case.
Isang mahalagang detour: Mahalagang mapansin na kahit na pareho ang mga bagay na ito
ipinahayag sa magkatulad na paraan,
Ptr file...
Ptr stream...
Ang mga pinagbabatayan na bagay ay ganap na naiiba. Halimbawa, ang Ptr ay isang
matalinong pagturo sa isang ns-3 Bagay na medyo mabigat na bagay na sumusuporta
Mga katangian at isinama sa Config system. Ang Ptr, Sa
sa kabilang banda, ay isang matalinong pointer sa isang reference na binibilang na bagay na napakagaan ng timbang
bagay. Tandaan na tingnan ang bagay na iyong tinutukoy bago gumawa ng anumang mga pagpapalagay
tungkol sa "mga kapangyarihan" na maaaring taglay ng bagay.
Halimbawa, tingnan src/network/utils/pcap-file-wrapper.h sa pamamahagi at
pansinin,
class PcapFileWrapper : pampublikong Bagay
yung klase PcapFileWrapper ay isang ns-3 Bagay sa bisa ng pamana nito. Pagkatapos ay tumingin sa
src/network/model/output-stream-wrapper.h at mapansin,
klase OutputStreamWrapper : pampubliko
SimpleRefCount
na ang bagay na ito ay hindi isang ns-3 Bagay sa lahat, ito ay "lamang" isang C++ na bagay na nangyayari sa
suportahan ang mapanghimasok na pagbibilang ng sanggunian.
Ang punto dito ay dahil nagbabasa ka lang Ptr hindi naman ibig sabihin nito
na isang bagay ay isang ns-3 Bagay na maaari mong ibitin ns-3 Mga katangian, halimbawa.
Ngayon, bumalik sa halimbawa. Kung bubuo at patakbuhin mo ang halimbawang ito,
$ ./waf --run pang-anim
makikita mo ang parehong mga mensahe na lilitaw tulad ng kapag nagpatakbo ka ng "ikalima", ngunit dalawang bagong file ang lalabas
lalabas sa top-level na direktoryo ng iyong ns-3 pamamahagi.
ikaanim.cwnd ikaanim.pcap
Dahil ang "sixth.cwnd" ay isang ASCII text file, maaari mo itong tingnan gamit ang pusa o ang iyong paboritong file
manonood
+1 0 536
+1.0093 536 1072
+1.01528 1072 1608
+1.02167 1608 2144
...
+9.69256 5149 5204
+9.89311 5204 5259
Mayroon kang tab na pinaghiwalay na file na may timestamp, lumang window ng congestion at bago
congestion window na angkop para sa direktang pag-import sa iyong plot program. Walang mga
extraneous prints sa file, walang pag-parse o pag-edit ang kailangan.
Dahil ang "sixth.pcap" ay isang PCAP file, maaari mo itong gamitin tcpdump.
pagbabasa mula sa file sixth.pcap, link-type na PPP (PPP)
1.136956 IP 10.1.1.1.49153 > 10.1.1.2.8080: Mga Flag [.], seq 17177:17681, ack 1, win 32768, mga opsyon [TS val 1133 ecr 1127,eol504], haba
1.403196 IP 10.1.1.1.49153 > 10.1.1.2.8080: Mga Flag [.], seq 33280:33784, ack 1, win 32768, mga opsyon [TS val 1399 ecr 1394,eol504], haba
...
7.426220 IP 10.1.1.1.49153 > 10.1.1.2.8080: Mga Flag [.], seq 785704:786240, ack 1, win 32768, mga opsyon [TS val 7423 ecr 7421,eol536], haba
9.630693 IP 10.1.1.1.49153 > 10.1.1.2.8080: Mga Flag [.], seq 882688:883224, ack 1, win 32768, mga opsyon [TS val 9620 ecr 9618,eol536], haba
Mayroon kang PCAP file na may mga packet na na-drop sa simulation. Walang mga
iba pang mga packet na naroroon sa file at walang ibang naroroon upang gumawa ng buhay
mahirap.
Ito ay isang mahabang paglalakbay, ngunit tayo ngayon ay nasa punto kung saan maaari nating pahalagahan ang ns-3
sistema ng pagsubaybay. Inalis namin ang mahahalagang kaganapan sa gitna ng pagpapatupad ng TCP
at isang device driver. Direktang inimbak namin ang mga kaganapang iyon sa mga file na magagamit sa karaniwang kilala
mga kasangkapan. Ginawa namin ito nang hindi binabago ang alinman sa mga pangunahing code na kasangkot, at ginawa namin ito sa
18 linya lang ng code:
static na walang bisa
CwndChange (Ptr stream, uint32_t oldCwnd, uint32_t newCwnd)
{
NS_LOG_UNCOND (Simulator::Now ().GetSeconds () << "\t" << newCwnd);
*stream->GetStream () << Simulator::Now ().GetSeconds () << "\t" << oldCwnd << "\t" << newCwnd << std::endl;
}
...
AsciiTraceHelper asciiTraceHelper;
Ptr stream = asciiTraceHelper.CreateFileStream ("sixth.cwnd");
ns3TcpSocket->TraceConnectWithoutContext ("CongestionWindow", MakeBoundCallback (&CwndChange, stream));
...
static na walang bisa
RxDrop (Ptr file, Ptr p)
{
NS_LOG_UNCOND ("RxDrop at " << Simulator::Now ().GetSeconds ());
file->Write(Simulator::Now(), p);
}
...
PcapHelper pcapHelper;
Ptr file = pcapHelper.CreateFile ("sixth.pcap", "w", PcapHelper::DLT_PPP);
mga device.Get (1)->TraceConnectWithoutContext("PhyRxDrop", MakeBoundCallback (&RxDrop, file));
Kopyahin o sipiin sa pamamagitan ng pag-aninag Mga tumutulong
Ang ns-3 Ang mga trace helper ay nagbibigay ng isang mayamang kapaligiran para sa pag-configure at pagpili ng iba
subaybayan ang mga kaganapan at isulat ang mga ito sa mga file. Sa mga nakaraang seksyon, pangunahin
BuildingTopologies, nakakita kami ng ilang uri ng mga pamamaraan ng trace helper na dinisenyo
para gamitin sa loob ng iba pang (device) na katulong.
Marahil ay maaalala mong nakita mo ang ilan sa mga pagkakaiba-iba na ito:
pointToPoint.EnablePcapAll ("pangalawa");
pointToPoint.EnablePcap ("pangalawa", p2pNodes.Get (0)->GetId (), 0);
csma.EnablePcap ("ikatlo", csmaDevices.Get (0), true);
pointToPoint.EnableAsciiAll (ascii.CreateFileStream ("myfirst.tr"));
Ang maaaring hindi halata, gayunpaman, ay mayroong pare-parehong modelo para sa lahat ng
mga pamamaraan na may kaugnayan sa bakas na matatagpuan sa system. Maglalaan tayo ngayon ng kaunting oras at titingnan
sa "malaking larawan".
Sa kasalukuyan ay may dalawang pangunahing kaso ng paggamit ng mga tracing helper sa ns-3: mga katulong ng device
at mga katulong sa protocol. Tinitingnan ng mga katulong ng device ang problema sa pagtukoy kung aling mga bakas
dapat na pinagana sa pamamagitan ng isang (node, device) na pares. Halimbawa, maaaring gusto mong tukuyin
na dapat paganahin ang pagsubaybay sa PCAP sa isang partikular na device sa isang partikular na node. Ito
sumusunod mula sa ns-3 konseptong modelo ng device, at gayundin ang mga konseptwal na modelo ng
iba't ibang device helpers. Natural na sumusunod dito, ang mga file na nilikha ay sumusunod sa a
- - kombensiyon ng pagbibigay ng pangalan.
Tinitingnan ng mga katulong ng protocol ang problema sa pagtukoy kung aling mga bakas ang dapat paganahin
isang pares ng protocol at interface. Ito ay sumusunod mula sa ns-3 protocol stack konseptwal
modelo, at gayundin ang mga konseptong modelo ng internet stack helpers. Natural, ang bakas
dapat sundin ang mga file a - - kombensiyon ng pagbibigay ng pangalan.
Ang mga trace helper samakatuwid ay natural na nahuhulog sa isang two-dimensional taxonomy. meron
mga subtleties na pumipigil sa lahat ng apat na klase na kumilos nang magkatulad, ngunit nagsusumikap kaming gawin ito
gawin silang lahat na gumana nang magkatulad hangga't maaari; at hangga't maaari ay may mga analogs para sa
lahat ng pamamaraan sa lahat ng klase.
┌────────────────┬──────┬────────
│ │ PCAP │ ASCII │
└────────────────┴──────┴────────
│Device Helper │ │ │
├────────────────┼──────┼────────
│Protocol Helper │ │ │
└────────────────┴──────┴────────
Gumagamit kami ng diskarte na tinatawag na a mixin upang magdagdag ng pag-andar ng pagsubaybay sa aming mga klase ng katulong. A
mixin ay isang klase na nagbibigay ng functionality kapag ito ay minana ng isang subclass.
Ang pagmamana mula sa isang mixin ay hindi itinuturing na isang anyo ng espesyalisasyon ngunit ito ay talagang isang paraan upang
mangolekta ng pag-andar.
Tingnan natin ang lahat ng apat sa mga kasong ito at ang kani-kanilang mga kaso mga halo.
Device Mga tumutulong
PCAP
Ang layunin ng mga katulong na ito ay gawing madali ang pagdaragdag ng pare-parehong pasilidad ng trace ng PCAP sa isang
ns-3 aparato. Gusto naming gumana nang pareho ang lahat ng iba't ibang lasa ng pagsubaybay sa PCAP
lahat ng device, kaya ang mga pamamaraan ng mga katulong na ito ay minana ng mga device helper. Tingnan mo
at src/network/helper/trace-helper.h kung gusto mong sundan ang usapan habang tumitingin
totoong code.
Ang klase PcapHelperForDevice ay isang mixin nagbibigay ng mataas na antas ng pag-andar para sa paggamit
Pagsubaybay sa PCAP sa isang ns-3 aparato. Ang bawat aparato ay dapat magpatupad ng isang virtual na pamamaraan
minana sa klase na ito.
virtual void EnablePcapInternal (std::string prefix, Ptr nd, bool promiscuous, bool explicitFilename) = 0;
Ang lagda ng paraang ito ay sumasalamin sa device-centric na pagtingin sa sitwasyon dito
antas. Lahat ng mga pampublikong pamamaraan na minana mula sa klase PcapUserHelperForDevice bawasan sa
tinatawag itong nag-iisang paraan ng pagpapatupad na umaasa sa device. Halimbawa, ang pinakamababang antas
paraan ng PCAP,
void EnablePcap (std::string prefix, Ptr nd, bool promiscuous = false, bool explicitFilename = false);
tatawagan ang pagpapatupad ng device ng EnablePcapInternal direkta. Lahat ng iba pang pampublikong PCAP
Ang mga pamamaraan ng pagsubaybay ay binuo sa pagpapatupad na ito upang magbigay ng karagdagang antas ng user
functionality. Ang ibig sabihin nito sa user ay gagawin ng lahat ng device helper sa system
magkaroon ng lahat ng paraan ng pagsubaybay sa PCAP; at ang mga pamamaraang ito ay gagana sa parehong paraan
paraan sa mga device kung ipapatupad ng device EnablePcapInternal tama.
Pamamaraan
void EnablePcap (std::string prefix, Ptr nd, bool promiscuous = false, bool explicitFilename = false);
void EnablePcap (std::string prefix, std::string ndName, bool promiscuous = false, bool explicitFilename = false);
void EnablePcap (std::string prefix, NetDeviceContainer d, bool promiscuous = false);
void EnablePcap (std::string prefix, NodeContainer n, bool promiscuous = false);
void EnablePcap (std::string prefix, uint32_t nodeid, uint32_t deviceid, bool promiscuous = false);
void EnablePcapAll (std::string prefix, bool promiscuous = false);
Sa bawat isa sa mga pamamaraan na ipinakita sa itaas, mayroong isang default na parameter na tinatawag mapanghimok na
default sa hindi totoo. Ang parameter na ito ay nagpapahiwatig na ang bakas ay hindi dapat tipunin
promiscuous mode. Kung gusto mong isama ng iyong mga bakas ang lahat ng trapikong nakikita ng device
(at kung sinusuportahan ng device ang isang promiscuous mode) magdagdag lang ng totoong parameter sa alinman sa
mga tawag sa itaas. Halimbawa,
Ptr nd;
...
helper.EnablePcap ("prefix", nd, true);
ay paganahin ang promiscuous mode captures sa NetDevice tinukoy ng nd.
Kasama rin sa unang dalawang pamamaraan ang isang default na parameter na tinatawag tahasang Filename iyan
tatalakayin sa ibaba.
Hinihikayat kang basahin ang API Documentation para sa klase PcapHelperForDevice upang mahanap
ang mga detalye ng mga pamamaraang ito; ngunit upang i-summarize ...
· Maaari mong paganahin ang pagsubaybay sa PCAP sa isang partikular na pares ng node/net-device sa pamamagitan ng pagbibigay ng a
Ptr sa isang Paganahin angPcap paraan Ang Ptr ay implicit mula noong net device
dapat ay nabibilang sa eksaktong isang Node. Halimbawa,
Ptr nd;
...
helper.EnablePcap ("prefix", nd);
· Maaari mong paganahin ang pagsubaybay sa PCAP sa isang partikular na pares ng node/net-device sa pamamagitan ng pagbibigay ng a
std::string kumakatawan sa isang object name service string sa isang Paganahin angPcap paraan Ang
Ptr ay tumingin mula sa string ng pangalan. Muli, ang ay implicit mula noon
ang pinangalanang net device ay dapat na kabilang sa eksaktong isang Node. Halimbawa,
Mga Pangalan::Add ("server" ...);
Mga Pangalan::Add ("server/eth0" ...);
...
helper.EnablePcap ("prefix", "server/ath0");
· Maaari mong paganahin ang pagsubaybay sa PCAP sa isang koleksyon ng mga pares ng node/net-device sa pamamagitan ng pagbibigay ng a
NetDeviceContainer. Para sa bawat isa NetDevice sa lalagyan ang uri ay nasuri. Para sa bawat isa
device na may tamang uri (kaparehong uri na pinamamahalaan ng device helper), ang pagsubaybay ay
pinagana. Muli, ang ay implicit dahil ang nahanap na net device ay dapat na pag-aari
eksaktong isang Node. Halimbawa,
NetDeviceContainer d = ...;
...
helper.EnablePcap ("prefix", d);
· Maaari mong paganahin ang pagsubaybay sa PCAP sa isang koleksyon ng mga pares ng node/net-device sa pamamagitan ng pagbibigay ng a
NodeContainer. Para sa bawat Node sa NodeContainer nakakabit nito Mga NetDevice ay inuulit.
Para sa bawat NetDevice naka-attach sa bawat Node sa container, ang uri ng device na iyon
sinuri. Para sa bawat device na may tamang uri (kaparehong uri na pinamamahalaan ng device
helper), pinagana ang pagsubaybay.
NodeContainer n;
...
helper.EnablePcap ("prefix", n);
· Maaari mong paganahin ang pagsubaybay sa PCAP batay sa Node ID at device ID pati na rin sa
malinaw Ptr. Ang bawat Node sa system ay may integer Node ID at bawat device ay konektado
sa isang Node ay mayroong integer device ID.
helper.EnablePcap ("prefix", 21, 1);
· Sa wakas, maaari mong paganahin ang PCAP tracing para sa lahat ng device sa system, na may parehong uri
gaya ng pinamamahalaan ng device helper.
helper.EnablePcapAll ("prefix");
Mga filename
Implicit sa paraan ng paglalarawan sa itaas ay ang pagbuo ng isang kumpletong filename sa pamamagitan ng
paraan ng pagpapatupad. Sa pamamagitan ng convention, ang PCAP traces sa ns-3 sistema ay nasa anyo
- id>- id>.pcap
Gaya ng naunang nabanggit, ang bawat Node sa system ay magkakaroon ng Node id na itinalaga ng system; at
bawat device ay magkakaroon ng interface index (tinatawag ding device id) na may kaugnayan sa node nito.
Bilang default, kung gayon, isang PCAP trace file ang ginawa bilang resulta ng pagpapagana ng pagsubaybay sa una
device ng Node 21 gamit ang prefix na "prefix" ay magiging prefix-21-1.pcap.
Maaari mong palaging gamitin ang ns-3 serbisyo ng pangalan ng bagay upang gawin itong mas malinaw. Halimbawa, kung
ginagamit mo ang serbisyo ng pangalan ng object upang italaga ang pangalan na "server" sa Node 21, ang resultang PCAP
Ang pangalan ng trace file ay awtomatikong magiging, prefix-server-1.pcap at kung itatalaga mo rin ang
pangalanan ang "eth0" sa device, awtomatikong kukunin ito ng iyong PCAP file name at magiging
tinatawag prefix-server-eth0.pcap.
Sa wakas, dalawa sa mga pamamaraan na ipinakita sa itaas,
void EnablePcap (std::string prefix, Ptr nd, bool promiscuous = false, bool explicitFilename = false);
void EnablePcap (std::string prefix, std::string ndName, bool promiscuous = false, bool explicitFilename = false);
magkaroon ng isang default na parameter na tinatawag tahasang Filename. Kapag nakatakda sa true, ang parameter na ito
hindi pinapagana ang mekanismo ng awtomatikong pagkumpleto ng filename at pinapayagan kang lumikha ng isang tahasang
filename. Ang opsyong ito ay magagamit lamang sa mga pamamaraan na nagbibigay-daan sa pagsubaybay ng PCAP sa a
solong aparato.
Halimbawa, upang maisaayos ang isang device helper na lumikha ng iisang promiscuous PCAP
pagkuha ng file ng isang tiyak na pangalan my-pcap-file.pcap sa isang partikular na device, maaaring:
Ptr nd;
...
helper.EnablePcap ("my-pcap-file.pcap", nd, true, true);
Ang unang totoo Ang parameter ay nagbibigay-daan sa mga bakas ng promiscuous mode at ang pangalawa ay nagsasabi sa katulong
upang bigyang kahulugan ang unlapi parameter bilang kumpletong filename.
ASCII
Ang pag-uugali ng trace helper ng ASCII mixin ay halos kapareho sa bersyon ng PCAP.
Bistahan src/network/helper/trace-helper.h kung gusto mong sundin ang talakayan
habang nakatingin sa totoong code.
Ang klase AsciiTraceHelperForDevice nagdaragdag ng mataas na antas ng pag-andar para sa paggamit ng ASCII
pagsubaybay sa isang klase ng helper ng device. Tulad ng sa PCAP case, ang bawat device ay dapat magpatupad ng a
nag-iisang virtual na pamamaraan na minana mula sa ASCII trace mixin.
virtual void EnableAsciiInternal (Ptr stream,
std::string prefix,
Ptr nd,
bool explicitFilename) = 0;
Ang lagda ng paraang ito ay sumasalamin sa device-centric na pagtingin sa sitwasyon dito
antas; at gayundin ang katotohanan na ang katulong ay maaaring sumusulat sa isang nakabahaging stream ng output. Lahat ng
ang pampublikong ASCII-trace-related na mga pamamaraan na minana mula sa klase AsciiTraceHelperForDevice
bawasan ang pagtawag sa isang paraan ng pagpapatupad na umaasa sa device na ito. Halimbawa, ang
pinakamababang antas ng mga pamamaraan ng pagsubaybay sa ascii,
void EnableAscii (std::string prefix, Ptr nd, bool explicitFilename = false);
void EnableAscii (Ptr stream, Ptr nd);
tatawagan ang pagpapatupad ng device ng EnableAsciiInternal direkta, na nagbibigay ng alinman sa a
wastong prefix o stream. Ang lahat ng iba pang pampublikong paraan ng pagsubaybay sa ASCII ay bubuo sa mga ito
mababang antas ng mga function upang magbigay ng karagdagang paggana sa antas ng user. Ano ang ibig sabihin nito
ang user ay ang lahat ng device helper sa system ay magkakaroon ng lahat ng ASCII trace method
magagamit; at lahat ng mga pamamaraang ito ay gagana sa parehong paraan sa mga device kung ang mga device
isakatuparan EnablAsciiInternal tama.
Pamamaraan
void EnableAscii (std::string prefix, Ptr nd, bool explicitFilename = false);
void EnableAscii (Ptr stream, Ptr nd);
void EnableAscii (std::string prefix, std::string ndName, bool explicitFilename = false);
void EnableAscii (Ptr stream, std::string ndName);
void EnableAscii (std::string prefix, NetDeviceContainer d);
void EnableAscii (Ptr stream, NetDeviceContainer d);
void EnableAscii (std::string prefix, NodeContainer n);
void EnableAscii (Ptr stream, NodeContainer n);
void EnableAsciiAll (std::string prefix);
void EnableAsciiAll (Ptr stream);
void EnableAscii (std::string prefix, uint32_t nodeid, uint32_t deviceid, bool explicitFilename);
void EnableAscii (Ptr stream, uint32_t nodeid, uint32_t deviceid);
Hinihikayat kang basahin ang API Documentation para sa klase AsciiTraceHelperForDevice sa
hanapin ang mga detalye ng mga pamamaraang ito; ngunit upang i-summarize ...
· Mayroong dalawang beses na mas maraming paraan na magagamit para sa ASCII tracing kaysa sa PCAP
pagsubaybay. Ito ay dahil, bilang karagdagan sa PCAP-style na modelo kung saan ang mga bakas mula sa bawat isa
ang natatanging pares ng node/device ay nakasulat sa isang natatanging file, sinusuportahan namin ang isang modelo kung saan ang trace
Ang impormasyon para sa maraming mga pares ng node/device ay isinulat sa isang karaniwang file. Nangangahulugan ito na ang
- - Ang mekanismo ng pagbuo ng pangalan ng file ay pinalitan ng isang mekanismo sa
sumangguni sa isang karaniwang file; at ang bilang ng mga pamamaraan ng API ay dinoble upang payagan ang lahat
mga kumbinasyon.
· Tulad ng sa PCAP tracing, maaari mong paganahin ang ASCII tracing sa isang partikular (node, net-device)
pares sa pamamagitan ng pagbibigay ng a Ptr sa isang EnableAscii paraan Ang Ptr ay implicit
dahil ang net device ay dapat na kabilang sa eksaktong isang Node. Halimbawa,
Ptr nd;
...
helper.EnableAscii ("prefix", nd);
· Kasama rin sa unang apat na paraan ang isang default na parameter na tinatawag tahasang Filename na
gumana katulad ng mga katumbas na parameter sa PCAP case.
Sa kasong ito, walang mga konteksto ng bakas na nakasulat sa ASCII trace file dahil magiging sila
kalabisan. Pipiliin ng system ang pangalan ng file na gagawin gamit ang parehong mga panuntunan tulad ng
inilarawan sa seksyong PCAP, maliban na ang file ay magkakaroon ng suffix .tr sa halip ng
.pcap.
· Kung gusto mong paganahin ang ASCII tracing sa higit sa isang net device at ipadala ang lahat ng bakas
sa isang file, magagawa mo rin iyon sa pamamagitan ng paggamit ng isang bagay upang sumangguni sa isang file.
Nakita na natin ito sa halimbawang "cwnd" sa itaas:
Ptr nd1;
Ptr nd2;
...
Ptr stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr");
...
helper.EnableAscii (stream, nd1);
helper.EnableAscii (stream, nd2);
Sa kasong ito, subaybayan ang mga konteksto ay nakasulat sa ASCII trace file dahil kinakailangan ang mga ito
upang i-dismbiguate ang mga bakas mula sa dalawang device. Tandaan na dahil ang gumagamit ay ganap na
pagtukoy sa pangalan ng file, ang string ay dapat isama ang ,tr panlapi para sa pagkakapare-pareho.
· Maaari mong paganahin ang ASCII tracing sa isang partikular na (node, net-device) na pares sa pamamagitan ng pagbibigay ng a
std::string kumakatawan sa isang object name service string sa isang Paganahin angPcap paraan Ang
Ptr ay tumingin mula sa string ng pangalan. Muli, ang ay implicit mula noon
ang pinangalanang net device ay dapat na kabilang sa eksaktong isang Node. Halimbawa,
Mga Pangalan::Add ("client" ...);
Mga Pangalan::Add ("client/eth0" ...);
Mga Pangalan::Add ("server" ...);
Mga Pangalan::Add ("server/eth0" ...);
...
helper.EnableAscii ("prefix", "client/eth0");
helper.EnableAscii ("prefix", "server/eth0");
Magreresulta ito sa dalawang file na pinangalanang ``prefix-client-eth0.tr`` at
``prefix-server-eth0.tr`` na may mga bakas para sa bawat device sa
kaukulang trace file. Dahil lahat ng ``EnableAscii`` function
ay overloaded upang kumuha ng stream wrapper, maaari mong gamitin ang form na iyon bilang
mabuti::
Mga Pangalan::Add ("client" ...);
Mga Pangalan::Add ("client/eth0" ...);
Mga Pangalan::Add ("server" ...);
Mga Pangalan::Add ("server/eth0" ...);
...
Ptr stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr");
...
helper.EnableAscii (stream, "client/eth0");
helper.EnableAscii (stream, "server/eth0");
Magreresulta ito sa isang solong trace file na tinatawag trace-file-name.tr na naglalaman ng lahat ng
ang mga trace event para sa parehong device. Ang mga kaganapan ay malilinawan sa pamamagitan ng bakas na konteksto
mga kuwerdas
· Maaari mong paganahin ang ASCII tracing sa isang koleksyon ng (node, net-device) na mga pares sa pamamagitan ng pagbibigay ng a
NetDeviceContainer. Para sa bawat isa NetDevice sa lalagyan ang uri ay nasuri. Para sa bawat isa
device na may tamang uri (kaparehong uri na pinamamahalaan ng device helper), ang pagsubaybay ay
pinagana. Muli, ang ay implicit dahil ang nahanap na net device ay dapat na pag-aari
eksaktong isang Node. Halimbawa,
NetDeviceContainer d = ...;
...
helper.EnableAscii ("prefix", d);
Magreresulta ito sa maraming ASCII trace file na malilikha,
ang bawat isa ay sumusunod sa `` - - .tr``
kombensyon.
Ang pagsasama-sama ng lahat ng mga bakas sa isang solong file ay nagagawa nang katulad sa mga halimbawa
sa itaas:
NetDeviceContainer d = ...;
...
Ptr stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr");
...
helper.EnableAscii (stream, d);
· Maaari mong paganahin ang ASCII tracing sa isang koleksyon ng (node, net-device) na mga pares sa pamamagitan ng pagbibigay ng a
NodeContainer. Para sa bawat Node sa NodeContainer nakakabit nito Mga NetDevice ay inuulit.
Para sa bawat NetDevice naka-attach sa bawat Node sa container, ang uri ng device na iyon
sinuri. Para sa bawat device na may tamang uri (kaparehong uri na pinamamahalaan ng device
helper), pinagana ang pagsubaybay.
NodeContainer n;
...
helper.EnableAscii ("prefix", n);
Ito ay magreresulta sa isang bilang ng mga ASCII trace file na malilikha, bawat isa ay sumusunod
ang - id>- id>.tr kumbensyon. Pinagsasama-sama ang lahat ng mga bakas sa a
ang isang file ay nagagawa nang katulad sa mga halimbawa sa itaas.
· Maaari mong paganahin ang pagsubaybay sa PCAP batay sa Node ID at device ID pati na rin sa
malinaw Ptr. Ang bawat Node sa system ay may integer Node ID at bawat device ay konektado
sa isang Node ay mayroong integer device ID.
helper.EnableAscii ("prefix", 21, 1);
Siyempre, ang mga bakas ay maaaring pagsamahin sa isang file tulad ng ipinapakita sa itaas.
· Sa wakas, maaari mong paganahin ang PCAP tracing para sa lahat ng device sa system, na may parehong uri
gaya ng pinamamahalaan ng device helper.
helper.EnableAsciiAll ("prefix");
Magreresulta ito sa maraming ASCII trace file na malilikha, isa para sa bawat device
sa sistema ng uri na pinamamahalaan ng katulong. Ang lahat ng mga file na ito ay susunod sa
- id>- id>.tr kumbensyon. Pinagsasama-sama ang lahat ng mga bakas sa isang solong
file ay nagagawa katulad ng mga halimbawa sa itaas.
Mga filename
Implicit sa prefix-style na paglalarawan ng paraan sa itaas ay ang pagbuo ng kumpleto
mga filename sa pamamagitan ng paraan ng pagpapatupad. Sa pamamagitan ng convention, ASCII traces sa ns-3 sistema
ay nasa anyo - id>- id>.tr
Gaya ng naunang nabanggit, ang bawat Node sa system ay magkakaroon ng Node id na itinalaga ng system; at
bawat device ay magkakaroon ng interface index (tinatawag ding device id) na may kaugnayan sa node nito.
Bilang default, kung gayon, isang ASCII trace file ang ginawa bilang resulta ng pagpapagana ng pagsubaybay sa una
device ng Node 21, gamit ang prefix na "prefix", ay magiging prefix-21-1.tr.
Maaari mong palaging gamitin ang ns-3 serbisyo ng pangalan ng bagay upang gawin itong mas malinaw. Halimbawa, kung
ginagamit mo ang serbisyo ng pangalan ng object upang italaga ang pangalan na "server" sa Node 21, ang resulta
Ang pangalan ng trace file ng ASCII ay awtomatikong magiging, prefix-server-1.tr at kung mag assign ka din
ang pangalang "eth0" sa device, awtomatikong kukunin ito ng iyong ASCII trace file name
at tatawagin prefix-server-eth0.tr.
Ang ilan sa mga pamamaraan ay may default na parameter na tinatawag tahasang Filename. Kapag nakatakda sa
totoo, hindi pinapagana ng parameter na ito ang mekanismo ng awtomatikong pagkumpleto ng filename at pinapayagan ka
upang lumikha ng isang tahasang filename. Ang pagpipiliang ito ay magagamit lamang sa mga pamamaraan na tumatagal ng a
prefix at paganahin ang pagsubaybay sa iisang device.
Protokol Mga tumutulong
PCAP
Ang layunin ng mga ito mga halo ay upang gawing madali ang pagdaragdag ng pare-parehong pasilidad ng bakas ng PCAP
mga protocol. Gusto naming gumana ang lahat ng iba't ibang lasa ng pagsubaybay sa PCAP sa lahat
protocol, kaya ang mga pamamaraan ng mga katulong na ito ay minana ng mga stack helper. Tingnan mo
src/network/helper/trace-helper.h kung gusto mong sundan ang usapan habang tumitingin
totoong code.
Sa seksyong ito ay ipapakita namin ang mga pamamaraan na inilapat sa protocol IPv4. Upang
tukuyin ang mga bakas sa mga katulad na protocol, palitan lamang ang naaangkop na uri. Halimbawa,
gumamit ng isang Ptr sa halip na isang Ptr at tawagan Paganahin angPcapIpv6 sa halip ng Paganahin angPcapIpv4.
Ang klase PcapHelperForIpv4 nagbibigay ng mataas na antas ng functionality para sa paggamit ng PCAP tracing
nasa IPv4 protocol. Ang bawat protocol helper na nagpapagana sa mga pamamaraang ito ay dapat magpatupad ng isa
virtual na pamamaraan na minana mula sa klase na ito. Magkakaroon ng hiwalay na pagpapatupad para sa
IPv6, halimbawa, ngunit ang pagkakaiba lamang ay nasa mga pangalan at lagda ng pamamaraan.
Iba't ibang mga pangalan ng pamamaraan ang kinakailangan upang i-dismbiguate ang klase IPv4 mula IPv6 na pareho
hango sa klase Bagay, at mga pamamaraan na may parehong lagda.
virtual void EnablePcapIpv4Internal (std::string prefix,
Ptr ipv4,
uint32_t interface,
bool explicitFilename) = 0;
Ang lagda ng pamamaraang ito ay sumasalamin sa protocol at interface-centric na view ng
sitwasyon sa antas na ito. Lahat ng mga pampublikong pamamaraan na minana mula sa klase PcapHelperForIpv4
bawasan ang pagtawag sa nag-iisang paraan ng pagpapatupad na umaasa sa device na ito. Halimbawa, ang
pinakamababang antas ng paraan ng PCAP,
void EnablePcapIpv4 (std::string prefix, Ptr ipv4, uint4_t interface, bool explicitFilename = false);
tatawagan ang pagpapatupad ng device ng Paganahin angPcapIpv4Internal direkta. Lahat ng iba pang publiko
Ang mga paraan ng pagsubaybay sa PCAP ay binuo sa pagpapatupad na ito upang magbigay ng karagdagang antas ng user
functionality. Ang ibig sabihin nito sa user ay ang lahat ng protocol helpers sa system
magkakaroon ng lahat ng paraan ng pagsubaybay sa PCAP; at ang mga pamamaraang ito ay gagana lahat sa
parehong paraan sa mga protocol kung ang katulong ay nagpapatupad Paganahin angPcapIpv4Internal tama.
Pamamaraan
Ang mga pamamaraang ito ay idinisenyo upang maging isa-sa-isang sulat sa Node- at
NetDevice- sentrik na mga bersyon ng mga bersyon ng device. Sa halip na Node at NetDevice pares
constraints, gumagamit kami ng protocol at interface constraints.
Tandaan na tulad ng sa bersyon ng device, mayroong anim na paraan:
void EnablePcapIpv4 (std::string prefix, Ptr ipv4, uint4_t interface, bool explicitFilename = false);
void EnablePcapIpv4 (std::string prefix, std::string ipv4Name, uint32_t interface, bool explicitFilename = false);
void EnablePcapIpv4 (std::string prefix, Ipv4InterfaceContainer c);
void EnablePcapIpv4 (std::string prefix, NodeContainer n);
void EnablePcapIpv4 (std::string prefix, uint32_t nodeid, uint32_t interface, bool explicitFilename);
void EnablePcapIpv4All (std::string prefix);
Hinihikayat kang basahin ang API Documentation para sa klase PcapHelperForIpv4 upang mahanap ang
mga detalye ng mga pamamaraang ito; ngunit upang i-summarize ...
· Maaari mong paganahin ang pagsubaybay sa PCAP sa isang partikular na pares ng protocol/interface sa pamamagitan ng pagbibigay ng a
Ptr at interface sa isang Paganahin angPcap paraan. Halimbawa,
Ptr ipv4 = node->GetObject ();
...
helper.EnablePcapIpv4 ("prefix", ipv4, 0);
· Maaari mong paganahin ang pagsubaybay sa PCAP sa isang partikular na pares ng node/net-device sa pamamagitan ng pagbibigay ng a
std::string kumakatawan sa isang object name service string sa isang Paganahin angPcap paraan Ang
Ptr ay tumingin mula sa string ng pangalan. Halimbawa,
Mga Pangalan::Add ("serverIPv4" ...);
...
helper.EnablePcapIpv4 ("prefix", "serverIpv4", 1);
· Maaari mong paganahin ang pagsubaybay sa PCAP sa isang koleksyon ng mga pares ng protocol/interface sa pamamagitan ng pagbibigay ng
IPv4InterfaceContainer. Para sa bawat isa IPv4 / interface pair sa lalagyan ang protocol
ang uri ay nasuri. Para sa bawat protocol ng wastong uri (kaparehong uri na pinamamahalaan ng
ang device helper), ang pagsubaybay ay pinagana para sa kaukulang interface. Halimbawa,
NodeContainer node;
...
NetDeviceContainer device = deviceHelper.Install (node);
...
Ipv4AddressHelper ipv4;
ipv4.SetBase ("10.1.1.0", "255.255.255.0");
Mga interface ng Ipv4InterfaceContainer = ipv4.Assign (mga device);
...
helper.EnablePcapIpv4 ("prefix", mga interface);
· Maaari mong paganahin ang pagsubaybay sa PCAP sa isang koleksyon ng mga pares ng protocol/interface sa pamamagitan ng pagbibigay ng a
NodeContainer. Para sa bawat Node sa NodeContainer matatagpuan ang naaangkop na protocol.
Para sa bawat protocol, ang mga interface nito ay binibilang at pinagana ang pagsubaybay sa resulta
magkapares. Halimbawa,
NodeContainer n;
...
helper.EnablePcapIpv4 ("prefix", n);
· Maaari mong paganahin ang pagsubaybay sa PCAP batay din sa Node ID at interface. Dito sa
kaso, ang node-id ay isinalin sa a Ptr at ang naaangkop na protocol ay hinahanap
sa node. Ang resultang protocol at interface ay ginagamit upang tukuyin ang resulta
bakas ang pinagmulan.
helper.EnablePcapIpv4 ("prefix", 21, 1);
· Sa wakas, maaari mong paganahin ang pagsubaybay sa PCAP para sa lahat ng mga interface sa system, na may nauugnay
protocol na pareho ang uri ng pinamamahalaan ng device helper.
helper.EnablePcapIpv4All ("prefix");
Mga filename
Implicit sa lahat ng paraan ng paglalarawan sa itaas ay ang pagbuo ng kumpleto
mga filename sa pamamagitan ng paraan ng pagpapatupad. Sa pamamagitan ng convention, kinuha ang mga bakas ng PCAP para sa mga device sa
ang ns-3 ang sistema ay nasa anyo" - - .pcap". Sa kaso ng
protocol traces, mayroong isa-sa-isang sulat sa pagitan ng mga protocol at Node. ito
ay dahil protocol bagay ay pinagsama-sama sa Node bagay. Dahil walang global
protocol id sa system, ginagamit namin ang kaukulang Node id sa pagpapangalan ng file. Samakatuwid
may posibilidad para sa mga banggaan ng pangalan ng file sa awtomatikong napiling mga pangalan ng trace file.
Para sa kadahilanang ito, ang file name convention ay binago para sa protocol traces.
Gaya ng naunang nabanggit, ang bawat Node sa system ay magkakaroon ng Node id na itinalaga ng system.
Dahil mayroong isa-sa-isang pagsusulatan sa pagitan ng mga instance ng protocol at mga instance ng Node
ginagamit namin ang Node id. Ang bawat interface ay may interface id na nauugnay sa protocol nito. Ginagamit namin
ang kumbensyon" -n -i .pcap" para sa pangalan ng trace file
mga katulong sa protocol.
Samakatuwid, bilang default, isang PCAP trace file ang ginawa bilang resulta ng pagpapagana ng pagsubaybay sa
interface 1 ng Ipv4 protocol ng Node 21 gamit ang prefix na "prefix" ay magiging
"prefix-n21-i1.pcap".
Maaari mong palaging gamitin ang ns-3 serbisyo ng pangalan ng bagay upang gawin itong mas malinaw. Halimbawa, kung
ginagamit mo ang serbisyo ng pangalan ng bagay upang italaga ang pangalan na "serverIpv4" sa Ptr sa Node
21, ang resultang PCAP trace file name ay awtomatikong magiging,
"prefix-nserverIpv4-i1.pcap".
Ang ilan sa mga pamamaraan ay may default na parameter na tinatawag tahasang Filename. Kapag nakatakda sa
totoo, hindi pinapagana ng parameter na ito ang mekanismo ng awtomatikong pagkumpleto ng filename at pinapayagan ka
upang lumikha ng isang tahasang filename. Ang pagpipiliang ito ay magagamit lamang sa mga pamamaraan na tumatagal ng a
prefix at paganahin ang pagsubaybay sa iisang device.
ASCII
Ang pag-uugali ng mga trace helper ng ASCII ay halos kapareho sa kaso ng PCAP. Kumuha ng a
tignan src/network/helper/trace-helper.h kung gusto mong sundan ang talakayan habang
tumitingin sa totoong code.
Sa seksyong ito ay ipapakita namin ang mga pamamaraan na inilapat sa protocol IPv4. Upang
tukuyin ang mga bakas sa mga katulad na protocol, palitan lamang ang naaangkop na uri. Halimbawa,
gumamit ng isang Ptr sa halip na isang Ptr at tawagan EnableAsciiIpv6 sa halip ng
EnableAsciiIpv4.
Ang klase AsciiTraceHelperForIpv4 nagdaragdag ng mataas na antas ng pag-andar para sa paggamit ng ASCII
pagsubaybay sa isang protocol helper. Ang bawat protocol na nagbibigay-daan sa mga pamamaraang ito ay dapat magpatupad ng a
nag-iisang virtual na pamamaraan na minana mula sa klase na ito.
virtual void EnableAsciiIpv4Internal (Ptr stream,
std::string prefix,
Ptr ipv4,
uint32_t interface,
bool explicitFilename) = 0;
Ang lagda ng pamamaraang ito ay sumasalamin sa protocol- at interface-centric na view ng
sitwasyon sa antas na ito; at gayundin ang katotohanan na ang katulong ay maaaring sumusulat sa isang nakabahagi
stream ng output. Lahat ng mga pampublikong pamamaraan na minana mula sa klase
PcapAndAsciiTraceHelperForIpv4 bawasan ang pagtawag sa nag-iisang device na umaasa
paraan ng pagpapatupad. Halimbawa, ang pinakamababang antas ng mga pamamaraan ng pagsubaybay sa ASCII,
void EnableAsciiIpv4 (std::string prefix, Ptr ipv4, uint4_t interface, bool explicitFilename = false);
void EnableAsciiIpv4 (Ptr stream, Ptr ipv4, uint4_t interface);
tatawagan ang pagpapatupad ng device ng EnableAsciiIpv4Internal direkta, nagbibigay ng alinman
ang unlapi o ang batis. Ang lahat ng iba pang pampublikong paraan ng pagsubaybay sa ASCII ay bubuo sa mga ito
mababang antas ng mga function upang magbigay ng karagdagang paggana sa antas ng user. Ano ang ibig sabihin nito
ang user ay ang lahat ng device helper sa system ay magkakaroon ng lahat ng ASCII trace method
magagamit; at ang mga pamamaraang ito ay gagana lahat sa parehong paraan sa mga protocol kung ang
ipinapatupad ang mga protocol EnablAsciiIpv4Internal tama.
Pamamaraan
void EnableAsciiIpv4 (std::string prefix, Ptr ipv4, uint4_t interface, bool explicitFilename = false);
void EnableAsciiIpv4 (Ptr stream, Ptr ipv4, uint4_t interface);
void EnableAsciiIpv4 (std::string prefix, std::string ipv4Name, uint32_t interface, bool explicitFilename = false);
void EnableAsciiIpv4 (Ptr stream, std::string ipv4Name, uint32_t interface);
void EnableAsciiIpv4 (std::string prefix, Ipv4InterfaceContainer c);
void EnableAsciiIpv4 (Ptr stream, Ipv4InterfaceContainer c);
void EnableAsciiIpv4 (std::string prefix, NodeContainer n);
void EnableAsciiIpv4 (Ptr stream, NodeContainer n);
void EnableAsciiIpv4All (std::string prefix);
void EnableAsciiIpv4All (Ptr stream);
void EnableAsciiIpv4 (std::string prefix, uint32_t nodeid, uint32_t deviceid, bool explicitFilename);
void EnableAsciiIpv4 (Ptr stream, uint32_t nodeid, uint32_t interface);
Hinihikayat kang basahin ang API Documentation para sa klase PcapAndAsciiHelperForIpv4 sa
hanapin ang mga detalye ng mga pamamaraang ito; ngunit upang i-summarize ...
· Mayroong dalawang beses na mas maraming paraan na magagamit para sa ASCII tracing kaysa sa PCAP
pagsubaybay. Ito ay dahil, bilang karagdagan sa PCAP-style na modelo kung saan ang mga bakas mula sa bawat isa
Ang natatanging pares ng protocol/interface ay isinulat sa isang natatanging file, sinusuportahan namin ang isang modelo kung saan
Ang bakas na impormasyon para sa maraming mga pares ng protocol/interface ay isinulat sa isang karaniwang file. Ito
nangangahulugan na ang -n - Ang mekanismo ng pagbuo ng pangalan ng file ay
pinalitan ng isang mekanismo upang sumangguni sa isang karaniwang file; at ang bilang ng mga pamamaraan ng API ay
dinoble upang payagan ang lahat ng kumbinasyon.
· Tulad ng sa PCAP tracing, maaari mong paganahin ang ASCII tracing sa isang partikular na protocol/interface
pares sa pamamagitan ng pagbibigay ng a Ptr at isang interface sa isang EnableAscii paraan. Halimbawa,
Ptr ipv4;
...
helper.EnableAsciiIpv4 ("prefix", ipv4, 1);
Sa kasong ito, walang mga konteksto ng bakas na nakasulat sa ASCII trace file dahil magiging sila
kalabisan. Pipiliin ng system ang pangalan ng file na gagawin gamit ang parehong mga panuntunan tulad ng
inilarawan sa seksyong PCAP, maliban na ang file ay magkakaroon ng suffix na ".tr" sa halip
ng ".pcap".
· Kung gusto mong paganahin ang pagsubaybay sa ASCII sa higit sa isang interface at ipadala ang lahat ng bakas
sa isang file, magagawa mo rin iyon sa pamamagitan ng paggamit ng isang bagay upang sumangguni sa isang file.
Mayroon na tayong katulad nito sa halimbawang "cwnd" sa itaas:
Ptr protocol4 = node1->GetObject ();
Ptr protocol4 = node2->GetObject ();
...
Ptr stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr");
...
helper.EnableAsciiIpv4 (stream, protocol1, 1);
helper.EnableAsciiIpv4 (stream, protocol2, 1);
Sa kasong ito, isinusulat ang mga konteksto ng trace sa ASCII trace file dahil kinakailangan ang mga ito
upang i-dismbiguate ang mga bakas mula sa dalawang interface. Tandaan na dahil ang gumagamit ay ganap na
pagtukoy sa pangalan ng file, ang string ay dapat isama ang ",tr" para sa pagkakapare-pareho.
· Maaari mong paganahin ang ASCII tracing sa isang partikular na protocol sa pamamagitan ng pagbibigay ng a std::string
kumakatawan sa isang object name service string sa isang Paganahin angPcap paraan Ang Ptr is
tumingala mula sa string ng pangalan. Ang sa mga nagresultang filename ay implicit since
mayroong isa-sa-isang pagsusulatan sa pagitan ng mga instance ng protocol at mga node, Halimbawa,
Mga Pangalan::Add ("node1Ipv4" ...);
Mga Pangalan::Add ("node2Ipv4" ...);
...
helper.EnableAsciiIpv4 ("prefix", "node1Ipv4", 1);
helper.EnableAsciiIpv4 ("prefix", "node2Ipv4", 1);
Magreresulta ito sa dalawang file na pinangalanang "prefix-nnode1Ipv4-i1.tr" at
"prefix-nnode2Ipv4-i1.tr" na may mga bakas para sa bawat interface sa kani-kanilang trace file.
Dahil overloaded ang lahat ng function ng EnableAscii para kumuha ng stream wrapper, magagawa mo
gamitin din ang form na iyon:
Mga Pangalan::Add ("node1Ipv4" ...);
Mga Pangalan::Add ("node2Ipv4" ...);
...
Ptr stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr");
...
helper.EnableAsciiIpv4 (stream, "node1Ipv4", 1);
helper.EnableAsciiIpv4 (stream, "node2Ipv4", 1);
Magreresulta ito sa isang trace file na tinatawag na "trace-file-name.tr" na naglalaman ng lahat
ng mga trace na kaganapan para sa parehong mga interface. Ang mga kaganapan ay malilinawan ng bakas
mga string ng konteksto.
· Maaari mong paganahin ang pagsubaybay sa ASCII sa isang koleksyon ng mga pares ng protocol/interface sa pamamagitan ng pagbibigay ng
IPv4InterfaceContainer. Para sa bawat protocol ng tamang uri (kaparehong uri tulad ng
pinamamahalaan ng device helper), pinagana ang pagsubaybay para sa kaukulang interface.
Muli, ang ay implicit dahil may isa-sa-isang sulat sa pagitan ng bawat isa
protocol at ang node nito. Halimbawa,
NodeContainer node;
...
NetDeviceContainer device = deviceHelper.Install (node);
...
Ipv4AddressHelper ipv4;
ipv4.SetBase ("10.1.1.0", "255.255.255.0");
Mga interface ng Ipv4InterfaceContainer = ipv4.Assign (mga device);
...
...
helper.EnableAsciiIpv4 ("prefix", mga interface);
Ito ay magreresulta sa isang bilang ng mga ASCII trace file na malilikha, bawat isa ay sumusunod
ang -n -i .tr convention. Pinagsasama-sama ang lahat ng mga bakas sa a
ang isang file ay nagagawa nang katulad sa mga halimbawa sa itaas:
NodeContainer node;
...
NetDeviceContainer device = deviceHelper.Install (node);
...
Ipv4AddressHelper ipv4;
ipv4.SetBase ("10.1.1.0", "255.255.255.0");
Mga interface ng Ipv4InterfaceContainer = ipv4.Assign (mga device);
...
Ptr stream = asciiTraceHelper.CreateFileStream ("trace-file-name.tr");
...
helper.EnableAsciiIpv4 (stream, mga interface);
· Maaari mong paganahin ang pagsubaybay sa ASCII sa isang koleksyon ng mga pares ng protocol/interface sa pamamagitan ng pagbibigay ng a
NodeContainer. Para sa bawat Node sa NodeContainer matatagpuan ang naaangkop na protocol.
Para sa bawat protocol, ang mga interface nito ay binibilang at pinagana ang pagsubaybay sa resulta
magkapares. Halimbawa,
NodeContainer n;
...
helper.EnableAsciiIpv4 ("prefix", n);
Ito ay magreresulta sa isang bilang ng mga ASCII trace file na malilikha, bawat isa ay sumusunod
ang - - .tr convention. Pinagsasama-sama ang lahat ng mga bakas sa a
ang isang file ay nagagawa nang katulad sa mga halimbawa sa itaas.
· Maaari mong paganahin ang pagsubaybay sa PCAP batay sa Node ID at device ID din. Dito sa
kaso, ang node-id ay isinalin sa a Ptr at ang naaangkop na protocol ay hinahanap
sa node. Ang resultang protocol at interface ay ginagamit upang tukuyin ang resulta
bakas ang pinagmulan.
helper.EnableAsciiIpv4 ("prefix", 21, 1);
Siyempre, ang mga bakas ay maaaring pagsamahin sa isang file tulad ng ipinapakita sa itaas.
· Sa wakas, maaari mong paganahin ang ASCII tracing para sa lahat ng mga interface sa system, na may nauugnay
protocol na pareho ang uri ng pinamamahalaan ng device helper.
helper.EnableAsciiIpv4All ("prefix");
Magreresulta ito sa maraming ASCII trace file na malilikha, isa para sa bawat isa
interface sa system na nauugnay sa isang protocol ng uri na pinamamahalaan ng helper. Lahat ng
susundan ng mga file na ito ang -n -i
lahat ng mga bakas sa isang solong file ay nagagawa nang katulad sa mga halimbawa sa itaas.
Mga filename
Implicit sa prefix-style na paglalarawan ng paraan sa itaas ay ang pagbuo ng kumpleto
mga filename sa pamamagitan ng paraan ng pagpapatupad. Sa pamamagitan ng convention, ASCII traces sa ns-3 sistema
ay nasa anyo" - - .tr"
Gaya ng naunang nabanggit, ang bawat Node sa system ay magkakaroon ng Node id na itinalaga ng system.
Dahil mayroong isa-sa-isang pagsusulatan sa pagitan ng mga protocol at node na ginagamit namin sa node-id
upang matukoy ang pagkakakilanlan ng protocol. Ang bawat interface sa isang ibinigay na protocol ay magkakaroon ng
interface index (tinatawag ding simpleng interface) na may kaugnayan sa protocol nito. Bilang default,
pagkatapos, isang ASCII trace file na ginawa bilang resulta ng pagpapagana ng pagsubaybay sa unang device ng
Ang node 21, gamit ang prefix na "prefix", ay magiging "prefix-n21-i1.tr". Gamitin ang prefix sa
i-disambiguate ang maramihang mga protocol sa bawat node.
Maaari mong palaging gamitin ang ns-3 serbisyo ng pangalan ng bagay upang gawin itong mas malinaw. Halimbawa, kung
ginagamit mo ang serbisyo ng pangalan ng object upang italaga ang pangalan na "serverIpv4" sa protocol sa Node
21, at tukuyin din ang interface ng isa, ang resultang ASCII trace file name ay awtomatikong
maging, "prefix-nserverIpv4-1.tr".
Ang ilan sa mga pamamaraan ay may default na parameter na tinatawag tahasang Filename. Kapag nakatakda sa
totoo, hindi pinapagana ng parameter na ito ang mekanismo ng awtomatikong pagkumpleto ng filename at pinapayagan ka
upang lumikha ng isang tahasang filename. Ang pagpipiliang ito ay magagamit lamang sa mga pamamaraan na tumatagal ng a
prefix at paganahin ang pagsubaybay sa iisang device.
Buod
ns-3 may kasamang napakayamang kapaligiran na nagbibigay-daan sa mga user sa ilang antas na mag-customize
ang mga uri ng impormasyon na maaaring makuha mula sa mga simulation.
May mga high-level helper function na nagbibigay-daan sa mga user na kontrolin lang ang koleksyon ng
paunang natukoy na mga output sa isang pinong granularity. May mga mid-level helper function na papayagan
mas sopistikadong mga user upang i-customize kung paano kinukuha at sine-save ang impormasyon; at doon
ay mababang antas ng mga pangunahing function upang payagan ang mga dalubhasang user na baguhin ang system upang magpakita ng bago at
dating hindi na-export na impormasyon sa paraang maa-access kaagad ng mga user sa
mas mataas na antas.
Ito ay isang napakakomprehensibong sistema, at napagtanto namin na ito ay maraming dapat tunawin, lalo na
para sa mga bagong user o sa mga hindi pamilyar sa C++ at sa mga idyoma nito. Isinasaalang-alang namin
ang sistema ng pagsubaybay ay isang napakahalagang bahagi ng ns-3 at kaya inirerekomenda na maging kasing pamilyar
posible kasama nito. Ito ay marahil ang kaso na ang pag-unawa sa natitirang bahagi ng ns-3 sistema
magiging medyo simple kapag na-master mo na ang tracing system
DATA Koleksyon
Ang aming huling kabanata ng tutorial ay nagpapakilala ng ilang bahagi na idinagdag sa ns-3 sa bersyon
3.18, at iyon ay nasa ilalim pa rin ng pag-unlad. Ang seksyon ng tutorial na ito ay isa ring
ginagawang trabaho.
Pagganyak
Ang isa sa mga pangunahing punto ng pagpapatakbo ng mga simulation ay ang pagbuo ng data ng output, alinman para sa
mga layunin ng pananaliksik o para lamang malaman ang tungkol sa sistema. Sa nakaraang kabanata, tayo
ipinakilala ang tracing subsystem at ang halimbawa ikaanim.cc. kung saan ang PCAP o ASCII trace
nabuo ang mga file. Ang mga bakas na ito ay mahalaga para sa pagsusuri ng data gamit ang iba't-ibang
panlabas na mga tool, at para sa maraming mga gumagamit, ang naturang output data ay isang ginustong paraan ng pangangalap
data (para sa pagsusuri ng mga panlabas na tool).
Gayunpaman, mayroon ding mga kaso ng paggamit para sa higit sa pagbuo ng trace file, kabilang ang
sumusunod:
· pagbuo ng data na hindi maganda ang pagmamapa sa mga bakas ng PCAP o ASCII, gaya ng hindi packet
data (hal. protocol state machine transition),
· malalaking simulation kung saan ang mga kinakailangan ng disk I/O para sa pagbuo ng mga trace file ay
bawal o masalimuot, at
· ang pangangailangan para sa online pagbabawas o pag-compute ng data, sa panahon ng simulation.
Ang isang magandang halimbawa nito ay upang tukuyin ang isang kondisyon ng pagwawakas para sa simulation, upang sabihin
ito kung kailan titigil kapag nakatanggap na ito ng sapat na data upang bumuo ng isang makitid na kumpiyansa
agwat sa paligid ng pagtatantya ng ilang parameter.
Ang ns-3 Ang balangkas ng pangongolekta ng data ay idinisenyo upang ibigay ang mga karagdagang kakayahan na ito
lampas sa trace-based na output. Inirerekomenda namin na ang mambabasa na interesado sa paksang ito ay kumonsulta
ang ns-3 Manwal para sa mas detalyadong paggamot sa balangkas na ito; dito, nagbubuod kami sa
isang halimbawang programa ang ilan sa pagbuo ng mga kakayahan.
halimbawa kodigo
Ang halimbawa ng tutorial mga halimbawa/tutorial/ikapito.cc kahawig ng ikaanim.cc halimbawa tayo
naunang nasuri, maliban sa ilang pagbabago. Una, ito ay pinagana para sa IPv6
suporta sa isang command-line na opsyon:
CommandLine cmd;
cmd.AddValue ("useIpv6", "Use Ipv6", useV6);
cmd.Parse (argc, argv);
Kung tinukoy ng gumagamit gumamit ngIpv6, opsyon, tatakbo ang program gamit ang IPv6 sa halip na IPv4.
Ang Tulungan opsyon, magagamit sa lahat ns-3 mga program na sumusuporta sa CommandLine object bilang
ipinapakita sa itaas, ay maaaring i-invoke bilang mga sumusunod (pakitandaan ang paggamit ng double quotes):
./waf --run "ikapitong --tulong"
na gumagawa ng:
ns3-dev-seventh-debug [Mga Argumento ng Programa] [Mga Pangkalahatang Argumento]
Mga Argumento ng Programa:
--useIpv6: Gamitin ang IPv6 [false]
Pangkalahatang Argumento:
--PrintGlobals: I-print ang listahan ng mga global.
--PrintGroups: I-print ang listahan ng mga grupo.
--PrintGroup=[group]: I-print ang lahat ng TypeIds ng grupo.
--PrintTypeIds: I-print ang lahat ng TypeIds.
--PrintAttributes=[typeid]: I-print ang lahat ng attribute ng typeid.
--PrintHelp: I-print ang mensahe ng tulong na ito.
Ang default na ito (paggamit ng IPv4, dahil false ang useIpv6) ay maaaring mabago sa pamamagitan ng pag-toggle sa boolean
halaga tulad ng sumusunod:
./waf --run "ikapitong --useIpv6=1"
at tingnan ang nabuong pcap, tulad ng sa tcpdump:
tcpdump -r ikapito.pcap -nn -tt
Ito ay naging isang maikling digression sa IPv6 support at ang command line, na noon din
ipinakilala nang mas maaga sa tutorial na ito. Para sa isang nakatuong halimbawa ng paggamit ng command line,
tingnan nyo po src/core/examples/command-line-example.cc.
Ngayon bumalik sa pangongolekta ng data. Nasa mga halimbawa/tutorial/ direktoryo, i-type ang sumusunod
utos: Diff -u ikaanim.cc ikapitong.cc, at suriin ang ilan sa mga bagong linya ng diff na ito:
+ std::string probeType;
+ std::string tracePath;
+ kung (useV6 == false)
+ {
...
+ probeType = "ns3::Ipv4PacketProbe";
+ tracePath = "/NodeList/*/$ns3::Ipv4L3Protocol/Tx";
+ }
+ iba pa
+ {
...
+ probeType = "ns3::Ipv6PacketProbe";
+ tracePath = "/NodeList/*/$ns3::Ipv6L3Protocol/Tx";
+ }
...
+ // Gamitin ang GnuplotHelper upang i-plot ang bilang ng packet byte sa paglipas ng panahon
+ GnuplotHelper plotHelper;
+
+ // I-configure ang plot. Ang unang argumento ay ang prefix ng pangalan ng file
+ // para sa mga output file na nabuo. Ang pangalawa, pangatlo, at pang-apat
+ // ang mga argumento ay, ayon sa pagkakabanggit, ang pamagat ng plot, x-axis, at y-axis na mga label
+ plotHelper.ConfigurePlot ("seventh-packet-byte-count",
+ "Packet Byte Count vs. Time",
+ "Oras (Segundo)",
+ "Bilang ng Packet Byte");
+
+ // Tukuyin ang uri ng probe, trace source path (sa configuration namespace), at
+ // probe output trace source ("OutputBytes") para mag-plot. Ang ikaapat na argumento
+ // ay tumutukoy sa pangalan ng label ng serye ng data sa plot. Ang huli
+ // na-format ng argumento ang plot sa pamamagitan ng pagtukoy kung saan dapat ilagay ang susi.
+ plotHelper.PlotProbe (probeType,
+ tracePath,
+ "OutputBytes",
+ "Bilang ng Packet Byte",
+ GnuplotAggregator::KEY_BELOW);
+
+ // Gamitin ang FileHelper upang isulat ang bilang ng packet byte sa paglipas ng panahon
+ FileHelper fileHelper;
+
+ // I-configure ang file na isusulat, at ang pag-format ng output data.
+ fileHelper.ConfigureFile ("seventh-packet-byte-count",
+ FileAggregator::FORMATTED);
+
+ // Itakda ang mga label para sa na-format na output file na ito.
+ fileHelper.Set2dFormat ("Oras (Second) = %.3e\tPacket Byte Count = %.0f");
+
+ // Tukuyin ang uri ng probe, landas ng probe (sa namespace ng pagsasaayos), at
+ // probe output trace source ("OutputBytes") para isulat.
+ fileHelper.WriteProbe (probeType,
+ tracePath,
+ "OutputBytes");
+
Simulator::Stop (Segundo (20));
Simulator::Run ();
Simulator:: Wasakin ();
Mapapansin ng maingat na mambabasa, kapag sinusubukan ang IPv6 command line attribute sa itaas,
na ikapitong.cc ay lumikha ng isang bilang ng mga bagong output file:
ikapitong-packet-byte-count-0.txt
ikapitong-packet-byte-count-1.txt
ikapitong-packet-byte-count.dat
ikapitong-packet-byte-count.plt
ikapitong-packet-byte-count.png
ikapitong-packet-byte-count.sh
Ang mga ito ay nilikha ng mga karagdagang pahayag na ipinakilala sa itaas; sa partikular, sa pamamagitan ng a
GnuplotHelper at isang FileHelper. Ang data na ito ay ginawa sa pamamagitan ng pag-hook ng data collection
bahagi sa ns-3 trace source, at pagsasama-sama ng data sa isang naka-format gnplot at
sa isang na-format na text file. Sa susunod na mga seksyon, susuriin namin ang bawat isa sa mga ito.
GnuplotHelper
Ang GnuplotHelper ay isang ns-3 katulong na bagay na naglalayon sa paggawa ng gnplot mga plot na may
kaunting mga pahayag hangga't maaari, para sa mga karaniwang kaso. Nakakabit ito ns-3 subaybayan ang mga mapagkukunan na may data
mga uri na sinusuportahan ng sistema ng pagkolekta ng data. Hindi lahat ns-3 trace source ang mga uri ng data ay
suportado, ngunit marami sa mga karaniwang uri ng trace ay, kabilang ang TracedValues na may payak na luma
mga uri ng data (POD).
Tingnan natin ang output na ginawa ng katulong na ito:
ikapitong-packet-byte-count.dat
ikapitong-packet-byte-count.plt
ikapitong-packet-byte-count.sh
Ang una ay isang file ng data ng gnuplot na may isang serye ng mga timestamp at packet na nakatakda sa espasyo
mga bilang ng byte. Sasaklawin natin kung paano na-configure ang partikular na output ng data na ito sa ibaba, ngunit hayaan natin
magpatuloy sa mga output file. Ang file ikapitong-packet-byte-count.plt ay isang plot ng gnuplot
file, na mabubuksan mula sa loob ng gnuplot. Ang mga mambabasa na nakakaunawa ng gnuplot syntax ay maaari
tingnan na gagawa ito ng format na output PNG file na pinangalanan
ikapitong-packet-byte-count.png. Sa wakas, isang maliit na script ng shell
ikapitong-packet-byte-count.sh pinapatakbo ang plot file na ito sa pamamagitan ng gnuplot upang makagawa ng ninanais
PNG (na maaaring matingnan sa isang editor ng imahe); iyon ay, ang utos:
sh ikapitong-packet-byte-count.sh
magbubunga ikapitong-packet-byte-count.png. Bakit hindi ginawa ang PNG na ito noong una
lugar? Ang sagot ay sa pamamagitan ng pagbibigay ng plt file, maaaring i-configure ng user ang
resulta kung ninanais, bago gawin ang PNG.
Ang pamagat ng imahe ng PNG ay nagsasaad na ang plot na ito ay isang plot ng "Packet Byte Count vs. Time", at
na ito ay nagpaplano ng probed data na naaayon sa trace source path:
/NodeList/*/$ns3::Ipv6L3Protocol/Tx
Tandaan ang wild-card sa trace path. Sa buod, ang kinukuha ng plot na ito ay ang plot
ng mga packet byte na naobserbahan sa transmit trace source ng Ipv6L3Protocol object;
higit sa lahat 596-byte TCP segment sa isang direksyon, at 60-byte TCP acks sa isa pa (dalawa
node trace source ay itinugma ng trace source na ito).
Paano ito na-configure? Ang ilang mga pahayag ay kailangang ibigay. Una, ang GnuplotHelper
bagay ay dapat ipahayag at i-configure:
+ // Gamitin ang GnuplotHelper upang i-plot ang bilang ng packet byte sa paglipas ng panahon
+ GnuplotHelper plotHelper;
+
+ // I-configure ang plot. Ang unang argumento ay ang prefix ng pangalan ng file
+ // para sa mga output file na nabuo. Ang pangalawa, pangatlo, at pang-apat
+ // ang mga argumento ay, ayon sa pagkakabanggit, ang pamagat ng plot, x-axis, at y-axis na mga label
+ plotHelper.ConfigurePlot ("seventh-packet-byte-count",
+ "Packet Byte Count vs. Time",
+ "Oras (Segundo)",
+ "Bilang ng Packet Byte");
Sa puntong ito, isang walang laman na plot ang na-configure. Ang prefix ng filename ang una
argumento, ang pamagat ng plot ay ang pangalawa, ang x-axis na label ang pangatlo, at ang y-axis na label
ang ikaapat na argumento.
Ang susunod na hakbang ay upang i-configure ang data, at dito ay kung saan ang trace source ay nakakabit.
Una, tandaan sa itaas sa program na ipinahayag namin ang ilang mga variable para magamit sa ibang pagkakataon:
+ std::string probeType;
+ std::string tracePath;
+ probeType = "ns3::Ipv6PacketProbe";
+ tracePath = "/NodeList/*/$ns3::Ipv6L3Protocol/Tx";
Ginagamit namin ang mga ito dito:
+ // Tukuyin ang uri ng probe, trace source path (sa configuration namespace), at
+ // probe output trace source ("OutputBytes") para mag-plot. Ang ikaapat na argumento
+ // ay tumutukoy sa pangalan ng label ng serye ng data sa plot. Ang huli
+ // na-format ng argumento ang plot sa pamamagitan ng pagtukoy kung saan dapat ilagay ang susi.
+ plotHelper.PlotProbe (probeType,
+ tracePath,
+ "OutputBytes",
+ "Bilang ng Packet Byte",
+ GnuplotAggregator::KEY_BELOW);
Ang unang dalawang argumento ay ang pangalan ng uri ng probe at ang trace source path. Ang mga ito
dalawa ang marahil ang pinakamahirap na matukoy kapag sinubukan mong gamitin ang balangkas na ito upang magplano ng iba
bakas. Ang probe trace dito ay ang Tx bakas ang pinagmulan ng klase Ipv6L3Protocol. Kapag tayo
suriin ang pagpapatupad ng klase na ito (src/internet/model/ipv6-l3-protocol.cc) mapapansin natin:
.AddTraceSource ("Tx", "Ipadala ang IPv6 packet sa papalabas na interface.",
MakeTraceSourceAccessor (&Ipv6L3Protocol::m_txTrace))
Sinasabi nito na Tx ay isang pangalan para sa variable m_txTrace, na may deklarasyon ng:
/ **
* \maikling Callback upang i-trace ang mga TX (transmission) packet.
*/
TracedCallback , Ptr , uint6_t> m_txTrace;
Lumalabas na ang partikular na pirma ng pinagmumulan ng bakas na ito ay sinusuportahan ng isang klase ng Probe (ano
kailangan namin dito) ng klase Ipv6PacketProbe. Tingnan ang mga file
src/internet/model/ipv6-packet-probe.{h,cc}.
Kaya, sa pahayag ng PlotProbe sa itaas, nakikita natin na ang pahayag ay nakakabit sa bakas
pinagmulan (natukoy ng path string) na may tugma ns-3 Uri ng probe ng Ipv6PacketProbe. Kung
hindi namin sinusuportahan ang uri ng probe na ito (tumutugma sa trace source signature), hindi namin maaaring gawin
ginamit ang pahayag na ito (bagaman ang ilang mas kumplikadong mas mababang antas na mga pahayag ay maaaring
ginamit, tulad ng inilarawan sa manwal).
Ang Ipv6PacketProbe ay nag-e-export, mismo, ng ilang trace source na kumukuha ng data mula sa
probed Packet object:
TypeId
Ipv6PacketProbe::GetTypeId ()
{
static na TypeId tid = TypeId ("ns3::Ipv6PacketProbe")
.SetParent ()
.AddConstructor ()
.AddTraceSource ( "Output",
"Ang packet kasama ang IPv6 object at interface nito na nagsisilbing output para sa probe na ito",
MakeTraceSourceAccessor (&Ipv6PacketProbe::m_output))
.AddTraceSource ( "OutputBytes",
"Ang bilang ng mga byte sa packet",
MakeTraceSourceAccessor (&Ipv6PacketProbe::m_outputBytes))
;
return tid;
}
Ang ikatlong argumento ng aming PlotProbe na pahayag ay tumutukoy na kami ay interesado sa
bilang ng mga byte sa packet na ito; partikular, ang "OutputBytes" trace source ng
Ipv6PacketProbe. Sa wakas, ang huling dalawang argumento ng pahayag ay nagbibigay ng alamat ng balangkas
para sa data series na ito ("Packet Byte Count"), at isang opsyonal na gnuplot formatting statement
(GnuplotAggregator::KEY_BELOW) na gusto naming maipasok ang plot key sa ibaba ng plot.
Kasama sa iba pang mga opsyon ang NO_KEY, KEY_INSIDE, at KEY_ABOVE.
Suportadong Kopyahin o sipiin sa pamamagitan ng pag-aninag Uri
Ang mga sumusunod na sinusubaybayang halaga ay sinusuportahan ng Probes sa pagsulat na ito:
┌; ────────────────────┐
│TracedValue type │ Probe type │ File │
├; ────────────────────┤
│double │ DoubleProbe │ stats/model/double-probe.h │
├; ────────────────────┤
│uint8_t │ Uinteger8Probe │ stats/model/uinteger-8-probe.h │
├; ────────────────────┤
│uint16_t │ Uinteger16Probe │ stats/model/uinteger-16-probe.h │
├; ────────────────────┤
│uint32_t │ Uinteger32Probe │ stats/model/uinteger-32-probe.h │
├; ────────────────────┤
│bool │ BooleanProbe │ stats/model/uinteger-16-probe.h │
├; ────────────────────┤
│ns3::Oras │ TimeProbe │ stats/model/time-probe.h │
└; ────────────────────┘
Ang mga sumusunod na uri ng TraceSource ay sinusuportahan ng Probes sa pagsulat na ito:
┌; Ap ──────────┐
├; Ap ──────────┤
├; Ap ──────────┤
├; Ap ──────────┤
├; Ap ──────────┤
├; Ap ──────────┤
└; Ap ──────────┘
Tulad ng makikita, iilan lamang sa mga bakas na mapagkukunan ang sinusuportahan, at lahat sila ay nakatuon sa
pag-output ng laki ng Packet (sa bytes). Gayunpaman, karamihan sa mga pangunahing uri ng data
magagamit dahil maaaring suportahan ang TracedValues sa mga katulong na ito.
FileHelper
Ang klase ng FileHelper ay isang pagkakaiba-iba lamang ng nakaraang halimbawa ng GnuplotHelper. Ang
Ang halimbawang programa ay nagbibigay ng naka-format na output ng parehong timestamped na data, tulad ng sumusunod:
Oras (Segundo) = 9.312e+00 Packet Byte Count = 596
Oras (Segundo) = 9.312e+00 Packet Byte Count = 564
Dalawang file ang ibinigay, isa para sa node "0" at isa para sa node "1" gaya ng makikita sa
mga filename. Tingnan natin ang code piece-by-piece:
+ // Gamitin ang FileHelper upang isulat ang bilang ng packet byte sa paglipas ng panahon
+ FileHelper fileHelper;
+
+ // I-configure ang file na isusulat, at ang pag-format ng output data.
+ fileHelper.ConfigureFile ("seventh-packet-byte-count",
+ FileAggregator::FORMATTED);
Ang file helper file prefix ay ang unang argumento, at isang format specifier ang susunod. Ang ilan
Kasama sa iba pang mga opsyon para sa pag-format ang SPACE_SEPARATED, COMMA_SEPARATED, at TAB_SEPARATED.
Nagagawang baguhin ng mga user ang pag-format (kung tinukoy ang FORMATTED) gamit ang string ng format
tulad ng sumusunod:
+
+ // Itakda ang mga label para sa na-format na output file na ito.
+ fileHelper.Set2dFormat ("Oras (Second) = %.3e\tPacket Byte Count = %.0f");
Sa wakas, ang bakas na pinagmumulan ng interes ay dapat na baluktot. Muli, ang probeType at tracePath
ang mga variable sa halimbawang ito ay ginagamit, at ang output trace source ng probe na "OutputBytes" ay
baluktot:
+
+ // Tukuyin ang uri ng probe, trace source path (sa configuration namespace), at
+ // probe output trace source ("OutputBytes") para isulat.
+ fileHelper.WriteProbe (probeType,
+ tracePath,
+ "OutputBytes");
+
Ang mga wildcard na field sa trace source specifier na ito ay tumutugma sa dalawang trace source. hindi tulad ng
Halimbawa ng GnuplotHelper, kung saan na-overlay ang dalawang serye ng data sa parehong plot, dito, dalawa
hiwalay na mga file ay nakasulat sa disk.
Buod
Ang suporta sa pagkolekta ng data ay bago sa ns-3.18, at pangunahing suporta para sa pagbibigay ng time series
naidagdag ang output. Ang pangunahing pattern na inilarawan sa itaas ay maaaring kopyahin sa loob ng
saklaw ng suporta ng mga umiiral na probes at trace source. Higit pang mga kakayahan kabilang ang
ang pagpoproseso ng mga istatistika ay idadagdag sa mga paglabas sa hinaharap.
Konklusyon
Futures
Ang dokumentong ito ay inilaan bilang isang buhay na dokumento. Umaasa kami at inaasahan na lalago ito sa paglipas ng panahon
upang masakop ang higit pa at higit pa sa mga mani at bolts ng ns-3.
Ang pagsulat ng mga manwal at tutorial na mga kabanata ay hindi isang bagay na nasasabik nating lahat, ngunit ito ay
napakahalaga sa proyekto. Kung ikaw ay isang dalubhasa sa isa sa mga lugar na ito, mangyaring
isaalang-alang ang pag-aambag sa ns-3 sa pamamagitan ng pagbibigay ng isa sa mga kabanatang ito; o kahit anong chapter mo
maaaring isipin na mahalaga.
Pagsasara
ns-3 ay isang malaki at kumplikadong sistema. Imposibleng sakupin ang lahat ng bagay sa iyo
ay kailangang malaman sa isang maliit na tutorial. Hinihikayat ang mga mambabasa na gustong matuto nang higit pa
basahin ang sumusunod na karagdagang dokumentasyon:
· Ang ns-3 manwal
· Ang ns-3 modelong dokumentasyon ng aklatan
· Ang ns-3 Doxygen (dokumentasyon ng API)
· Ang ns-3 wiki
-- Ang ns-3 pangkat ng pag-unlad.
Gumamit ng ns-3-tutorial online gamit ang mga serbisyo ng onworks.net