Падручнік па сімулятары сеткі ns-3. Кіраўнік 5

Падручнік па сімулятары сеткі ns-3. Кіраўнік 5
кіраўніка 1,2
раздзел 3
раздзел 4

5 Настройка
5.1 Выкарыстанне модуля часопісавання
5.1.1 Агляд часопісавання
5.1.2 Дазвол часопісавання
5.1.3 Даданне часопісавання ў ваш код
5.2 Выкарыстанне аргументаў каманднага радка
5.2.1 Пераазначэнне значэнняў атрыбутаў па змаўчанні
5.2.2 Захоп вашых уласных каманд
5.3 Выкарыстанне сістэмы трасіроўкі
5.3.1 ASCII Трасіроўка
Парсінг ASCII трас
5.3.2 Трасіроўка PCAP

кіраўнік 5

Настройка

5.1 Выкарыстанне модуля часопісавання

Мы ўжо сцісла разгледзелі модуль часопісавання ns‑3, праглядаючы скрыпт. first.cc. У гэтым раздзеле мы больш пільна прыгледзімся да магчымых варыянтаў выкарыстання падсістэмы часопісавання.

5.1.1 Агляд часопісавання

Многія вялікія сістэмы падтрымліваюць нейкі сродак рэгістрацыі паведамленняў, і ns‑3 не з'яўляецца выключэннем. У некаторых выпадках, у "кансоль аператара" (якая звычайна з'яўляецца stderr у сістэмах на аснове Unix) запісваюцца толькі паведамленні аб памылках. У іншых сістэмах могуць выводзіцца папераджальныя паведамленні, а таксама больш падрабязная інфармацыя. У некаторых выпадках, сродкі часопісавання выкарыстоўваюцца для вываду адладкавых паведамленняў, якія могуць хутка «замыліць» выснову.

Падхрд, які выкарыстоўваецца ў ns‑3, мяркуе, што ўсе гэтыя ўзроўні інфарматыўнасці карысныя, і мы даем выбарчы, шматузроўневы падыход да рэгістрацыі паведамленняў. Журналіраванне можа быць поўнасцю адключана, уключана для асобных кампанентаў або ў глабальным маштабе. Для гэтага служаць наладжвальныя ўзроўні інфарматыўнасці. Модуль часопісавання ns‑3 забяспечвае адносна просты спосаб атрымання карыснай інфармацыі з вашай сімуляцыі.

Вы павінны разумець, што мы даем механізм агульнага прызначэння - трасіроўку - для вымання дадзеных з вашых мадэляў, які павінен быць пераважным для вываду пры мадэляванні (для атрымання больш падрабязнай інфармацыі аб нашай сістэмы трасіроўкі гл. раздзел падручніка 5.3). Журналіраванне павінна быць пераважным метадам атрымання адладкавай інфармацыі, папярэджанняў, паведамленняў аб памылках або для хуткага вываду паведамленняў з вашых сцэнарыяў або мадэляў у любы момант.

У наш час у сістэме вызначана сем узроўняў (тыпаў) паведамленняў часопіса па ўзрастанні інфарматыўнасці.

  • LOG_ERROR - рэгістрацыя паведамленняў аб памылках (звязаны макрас: NS_LOG_ERROR);
  • LOG_WARN - рэгістрацыя папераджальных паведамленняў (звязаны макрас: NS_LOG_WARN);
  • LOG_DEBUG - рэгістрацыя адносна рэдкіх спецыяльных паведамленняў адладкі (звязаны макрас: NS_LOG_DEBUG);
  • LOG_INFO - рэгістрацыя інфармацыйных паведамленняў аб ходзе выканання праграмы (звязаны макрас: NS_LOG_INFO);
  • LOG_FUNCTION - рэгістрацыя паведамленняў, якія апісваюць кожную выкліканую функцыю (два звязаных макраса: NS_LOG_FUNCTION, які выкарыстоўваецца для функцый-членаў, і NS_LOG_FUNCTION_NOARGS, які выкарыстоўваецца для статычных функцый);
  • LOG_LOGIC - рэгістрацыя паведамленняў, якія апісваюць лагічны паток ўнутры функцыі (звязаны макрас: NS_LOG_LOGIC);
  • LOG_ALL - рэгістрацыя ўсяго згаданага вышэй (звязанага макраса няма).
    Для кожнага тыпу (LOG_TYPE) ёсць таксама тып LOG_LEVEL_TYPE, які, калі выкарыстоўваецца, дазваляе рэгістраваць у дадатак да яго ўласнага ўзроўня ўсе ўзроўні над ім. (Як следства, LOG_ERROR і LOG_LEVEL_ERROR, а таксама LOG_ALL і LOG_LEVEL_ALL функцыянальна эквівалентныя.) Напрыклад, уключэнне LOG_INFO будзе дазваляць толькі паведамленні, якія прадстаўляюцца макрасам NS_LOG_INFO, пры ўключэнні LOG_LEVEL_INFO таксама будуць уключаны паведамленні, прадстаўленыя макра _ERROR.

Мы таксама прадстаўляем макрас безумоўнага часопісавання, які адлюстроўваецца заўсёды, незалежна ад узроўню вядзення часопіса ці кампанента выбар.

  • NS_LOG_UNCOND - безумоўная рэгістрацыя звязанага паведамлення (без звязанага ўзроўню часопісавання).

Кожны ўзровень можа быць запытаны па асобнасці або кумулятыўна. Журналіраванне можна наладзіць з дапамогай зменнай sh-асяроддзя NS_LOG або шляхам рэгістрацыі выкліку сістэмнай функцыі. Як было паказана раней, сістэма часопісавання мае Doxygen-дакументацыю і зараз самы час яе прагледзець, калі вы гэта яшчэ не зрабілі.

Цяпер, калі вы прачыталі дакументацыю вельмі падрабязна, давайце скарыстаемся гэтымі ведамі, каб атрымаць некаторыя цікавую інфармацыю з прыкладу сцэнара scratch/myfirst.cc, які вы ўжо кампілявалі.

5.1.2 Дазвол часопісавання

Давайце выкарыстоўваем зменную асяроддзі NS_LOG, каб запусціць яшчэ некалькі часопісаў, але спачатку, проста для таго, каб зарыентавацца, запусціце апошні скрыпт, як вы рабілі раней,

$ ./waf --run scratch/myfirst

Вы павінны ўбачыць ужо знаёмую выснову першай праграмы-прыкладу ns‑3

$ Waf: Entering directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build' 'build'
finished successfully (0.413s)
Sent 1024 bytes to 10.1.1.2
Received 1024 bytes from 10.1.1.1
Received 1024 bytes from 10.1.1.2

Аказваецца, што «адпраўленыя» і «атрыманыя» паведамленні, якія вы бачыце вышэй, насамрэч гэта зарэгістраваныя паведамленні ад UdpEchoClientApplication и UdpEchoServerApplication. Напрыклад, мы можам папрасіць кліенцкае прыкладанне, раздрукаваць дадатковую інфармацыю, усталяваўшы яе ўзровень часопісавання праз зменную асяроддзі NS_LOG.

З гэтага моманту я збіраюся выказаць здагадку, што вы выкарыстоўваеце sh-падобную абалонку, якая выкарыстоўвае сінтаксіс "VARIABLE = value". Калі вы выкарыстоўваеце csh-падобную абалонку, тады вам давядзецца пераўтварыць мае прыклады ў сінтаксіс «пераменнае значэнне setenv» патрабуецца гэтымі абалонкамі.

У дадзены момант, прыкладанне UDP рэха-кліента адказвае на наступны радок кода ў scratch/myfirst.cc,

LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO);

Яна актывуе ўзровень часопісавання LOG_LEVEL_INFO. Калі мы перадаем сцяг ўзроўню часопісавання, мы на самой справе ўключаем дадзены ўзровень і ўсё больш нізкія ўзроўні. У дадзеным выпадку мы ўключылі NS_LOG_INFO, NS_LOG_DEBUG, NS_LOG_WARN і NS_LOG_ERROR. Мы можам павысіць узровень часопіса і атрымаць больш інфармацыі, без змен скрыпту і перакампіляванне, шляхам усталёўкі зменнай асяроддзя NS_LOG наступным чынам:

$ export NS_LOG=UdpEchoClientApplication=level_all

Так мы ўсталёўваем наступнае значэнне зменнай NS_LOG sh-абалонкі,

UdpEchoClientApplication=level_all

Левая частка прысваення - гэта імя журналіраванага кампанента, які мы хочам наладзіць, а правая частка - гэта сцяг, які мы хочам для гэтага прымяніць. У дадзеным выпадку мы збіраемся ўключыць у дадатку ўсе ўзроўні адладкі. Калі вы запусціце скрыпт з усталяванай такім чынам NS_LOG, сістэма часопісавання ns‑3 прыме змены і вы павінны ўбачыць наступную выснову:

Waf: Entering directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' finished successfully (0.404s)
UdpEchoClientApplication:UdpEchoClient()
UdpEchoClientApplication:SetDataSize(1024)
UdpEchoClientApplication:StartApplication()
UdpEchoClientApplication:ScheduleTransmit()
UdpEchoClientApplication:Send()
Sent 1024 bytes to 10.1.1.2
Received 1024 bytes from 10.1.1.1
UdpEchoClientApplication:HandleRead(0x6241e0, 0x624a20)
Received 1024 bytes from 10.1.1.2
UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()

Дадатковая адладкавая інфармацыя, якая прадстаўляецца дадаткам, зараз адпавядае ўзроўню NS_LOG_FUNCTION. Ён паказвае кожны выпадак выкліку функцый падчас выканання скрыпту. Як правіла, у функцыях-метадах пераважна выкарыстоўваць (як мінімум)NS_LOG_FUNCTION (this). выкарыстоўвайце NS_LOG_FUNCTION_NOARGS ()
толькі ў статычных функцыях. Тым не менш, звернеце ўвагу, што ў сістэме ns‑3 няма патрабаванняў падтрымліваць якую-небудзь функцыянальнасць часопісавання. Рашэнне аб тым, колькі інфармацыі рэгіструецца, застаецца індывідуальна за распрацоўшчыкам мадэлі. У выпадку рэха-прыкладанняў даступна вялікая колькасць выходных дадзеных для часопісавання.

Цяпер вы можаце прагледзець часопіс выклікаў функцый, якія былі зроблены дадаткам. Калі вы прыгледзіцеся ўважліва, то заўважыце двукроп'е паміж радком. UdpEchoClientApplication і імем метаду, у тым месцы, дзе вы магчыма чакалі ўбачыць аператар вобласці бачнасці C++ (: :). Гэта зроблена наўмысна.

Насамрэч гэта не імя класа, а імя кампанента часопісавання. Калі ёсць адпаведнасць паміж зыходным файлам і класам, звычайна гэтае імя класа, але вы павінны разумець, што на самой справе гэта не імя класа, і там адна двокроп'е замест падвойнай двокроп'я. Гэта спосаб дапамагчы вам адносна тонкім спосабам канцэптуальна аддзяліць імя кампанента часопісавання ад імя класа.

Тым не менш, у некаторых выпадках бывае складана вызначыць, які метад насамрэч генеруе паведамленне часопіса. Калі вы паглядзіце на тэкст вышэй, то ў вас узнікне пытанне, адкуль узяўся радок.Received 1024 bytes from 10.1.1.2». Вы можаце вырашыць гэтую праблему, усталяваўшы ўзровень prefix_func у зменную асяроддзі NS_LOG. Паспрабуй зрабіць наступнае,

$ export 'NS_LOG=UdpEchoClientApplication=level_all|prefix_func'

Звярніце ўвагу, што двукоссі неабходныя, паколькі вертыкальная рыса, якую мы выкарыстоўваем для абазначэння аперацыі АБО, таксама з'яўляецца злучальнікам канвеераў Unix. Цяпер, калі вы запусціце сцэнар, вы ўбачыце, што сістэма часопісавання гарантуе, што кожнае паведамленне з дадзенага часопіса мае прэфікс з імем кампанента.

Waf: Entering directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' finished successfully (0.417s)
UdpEchoClientApplication:UdpEchoClient()
UdpEchoClientApplication:SetDataSize(1024)
UdpEchoClientApplication:StartApplication()
UdpEchoClientApplication:ScheduleTransmit()
UdpEchoClientApplication:Send()
UdpEchoClientApplication:Send(): Sent 1024 bytes to 10.1.1.2
Received 1024 bytes from 10.1.1.1
UdpEchoClientApplication:HandleRead(0x6241e0, 0x624a20)
UdpEchoClientApplication:HandleRead(): Received 1024 bytes from 10.1.1.2
UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()

Цяпер вы можаце бачыць, што ўсе паведамленні, якія паступаюць ад прыкладання UDP рэха-кліента, ідэнтыфікаваны як такія. Паведамленне «Received 1024 bytes from 10.1.1.2» зараз дакладна вызначана як паступае ад прыкладання рэха-кліента. Пакінутае паведамленне павінна паступіць з прыкладання UDP рэха-сервера. Мы можам уключыць гэты кампанент, увёўшы спіс кампанентаў, падзеленых двукроп'ямі, у зменным асяроддзі NS_LOG.

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

Папярэджанне: у прыведзеным вышэй прыкладзе тэксту вам трэба будзе выдаліць сімвал новага радка пасля двукроп'я (:), ён выкарыстаны для фарматавання дакумента. Цяпер, калі вы запусціце сцэнар, вы ўбачыце ўсе паведамленні часопіса з кліенцкага і сервернага рэха-прыкладанняў. Вы можаце ўбачыць, што гэта можа быць вельмі карысна пры адладцы.

Waf: Entering directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' finished successfully (0.406s)
UdpEchoServerApplication:UdpEchoServer()
UdpEchoClientApplication:UdpEchoClient()
UdpEchoClientApplication:SetDataSize(1024)
UdpEchoServerApplication:StartApplication()
UdpEchoClientApplication:StartApplication()
UdpEchoClientApplication:ScheduleTransmit()
UdpEchoClientApplication:Send()
UdpEchoClientApplication:Send(): Sent 1024 bytes to 10.1.1.2
UdpEchoServerApplication:HandleRead(): Received 1024 bytes from 10.1.1.1
UdpEchoServerApplication:HandleRead(): Echoing packet
UdpEchoClientApplication:HandleRead(0x624920, 0x625160)
UdpEchoClientApplication:HandleRead(): Received 1024 bytes from 10.1.1.2
UdpEchoServerApplication:StopApplication()
UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoServerApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()
UdpEchoServerApplication:~UdpEchoServer()

Таксама часам карысна мець магчымасць бачыць час мадэлявання, у які было створана паведамленне часопіса. Вы можаш зрабіць гэта шляхам дадання па АБО біта prefix_time:

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

Зноў жа, вам давядзецца выдаліць вышэй сімвал новага радка. Калі вы зараз запусціце скрыпт, то павінны ўбачыць наступную выснову:

Waf: Entering directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' finished successfully (0.418s)
0s UdpEchoServerApplication:UdpEchoServer()
0s UdpEchoClientApplication:UdpEchoClient()
0s UdpEchoClientApplication:SetDataSize(1024)
1s UdpEchoServerApplication:StartApplication()
2s UdpEchoClientApplication:StartApplication()
2s UdpEchoClientApplication:ScheduleTransmit()
2s UdpEchoClientApplication:Send()
2s UdpEchoClientApplication:Send(): Sent 1024 bytes to 10.1.1.2
2.00369s UdpEchoServerApplication:HandleRead(): Received 1024 bytes from 10.1.1.1
2.00369s UdpEchoServerApplication:HandleRead(): Echoing packet
2.00737s UdpEchoClientApplication:HandleRead(0x624290, 0x624ad0)
2.00737s UdpEchoClientApplication:HandleRead(): Received 1024 bytes from 10.1.1.2
10s UdpEchoServerApplication:StopApplication()
10s UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoServerApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()
UdpEchoServerApplication:~UdpEchoServer()

Звярніце ўвагу, што канструктар для UdpEchoServer быў выкліканы падчас сімуляцыі 0 секунд. Гэта на самой справе адбываецца да пачатку сімуляцыі, але гэты час адлюстроўваецца як нуль секунд. Тое ж самае дакладна для паведамленне канструктара UdpEchoClient.

Waf: Entering directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' finished successfully (0.418s)
0s UdpEchoServerApplication:UdpEchoServer()
0s UdpEchoClientApplication:UdpEchoClient()
0s UdpEchoClientApplication:SetDataSize(1024)
1s UdpEchoServerApplication:StartApplication()
2s UdpEchoClientApplication:StartApplication()
2s UdpEchoClientApplication:ScheduleTransmit()
2s UdpEchoClientApplication:Send()
2s UdpEchoClientApplication:Send(): Sent 1024 bytes to 10.1.1.2
2.00369s UdpEchoServerApplication:HandleRead(): Received 1024 bytes from 10.1.1.1
2.00369s UdpEchoServerApplication:HandleRead(): Echoing packet
2.00737s UdpEchoClientApplication:HandleRead(0x624290, 0x624ad0)
2.00737s UdpEchoClientApplication:HandleRead(): Received 1024 bytes from 10.1.1.2
10s UdpEchoServerApplication:StopApplication()
10s UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoServerApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()
UdpEchoServerApplication:~UdpEchoServer()

Нагадаем, што скрыпт scratch/first.cc запусціў прыкладанне рэха-сервера за адну секунду да пачатку сімуляцыі. Цяпер вы можаце бачыць, што метад StartApplication сервера фактычна выклікаецца на першай секундзе. Вы таксама можаце заўважыць, што рэха-кліент запускаецца на другой секундзе сімуляцыі, як мы і прасілі ў скрыпце.

Цяпер вы можаце сачыць за ходам сімуляцыі па выкліку ScheduleTransmit у кліенце, які выклікае Send зваротнага выкліку HandleRead у дадатку рэха-сервера. Звярніце ўвагу, што мінулы час для адпраўкі пакета праз двухкропкавы лінк складае 3,69 мілісекунды. Відаць, што рэха-сервер рэгіструе паведамленне аб тым, што ён адгукнуўся на пакет, а затым, пасля затрымкі канала, вы бачыце, што рэха-кліент атрымлівае рэха-пакет у сваім метадзе HandleRead.

У гэтай сімуляцыі шмат што адбываецца неўзаметку для вас. Але вы можаце вельмі лёгка адсачыць увесь працэс, улучыўшы ў сістэме ўсе кампаненты часопісавання. Паспрабуйце ўсталяваць у зменнай NS_LOG наступнае значэнне,

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

Зорачка вышэй з'яўляецца падстановачным сімвалам кампанента часопісавання. Гэта ўключыць усе запісы ва ўсіх кампанентах выкарыстоўваецца ў сімуляцыі. Я не буду прайграваць выснову тут (на момант напісання артыкула ён вырабляе 1265 радкоў вываду для адзін рэха-пакет), але вы можаце перанакіраваць гэтую інфармацыю ў файл і прагледзець яго ў вашым каханым рэдактары,

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

Я асабіста выкарыстоўваю гэтую надзвычай шматслоўную версію вядзення часопіса, калі ў мяне ўзнікла праблема, і я паняцця не маю, дзе справы пайшлі не так. Я магу даволі лёгка сачыць за выкананнем кода, не ўсталёўваючы кропкі супыну і пакрокавы код у адладчыку. Я магу проста адрэдагаваць выснову ў маім каханым рэдактары і шукаць тое, што я чакаю, і бачыць, што адбываецца тое, чаго не чакаў. Калі ў мяне ёсць агульнае ўяўленне аб тым, што ідзе не так, я пераходжу ў адладчык для дэталёвага вывучэння праблемы. Гэты від вываду можа быць асабліва карысны, калі ваш скрыпт робіць нешта зусім нечаканае. Калі вы карыстаецеся толькі адладчыкам, вы можаце поўнасцю прапусціць нечаканы паварот. Рэгістрацыя робіць такія павароты прыкметнымі.

5.1.3 Даданне часопісавання ў ваш код

Вы можаце дадаць новыя запісы ў свае сімуляцыі, здзяйсняючы выклікі кампанента log з некалькіх макрасаў. Давайце зробім гэта ў сцэнары myfirst.cc, які мы маем у «чыстай» дырэкторыі. Нагадаем, што мы вызначылі ў гэтым сцэнары кампанент часопісавання:

NS_LOG_COMPONENT_DEFINE ("FirstScriptExample");

Вам вядома, што вы можаце ўключыць часопісаванне ўсіх паведамленняў гэтага кампанента, усталяваўшы зменнае асяроддзі NS_LOG на розных узроўнях. Давайце працягнем і дадамо некаторыя запісы ў скрыпт. Макрас, які выкарыстоўваецца для дадання ў часопіс паведамленняў інфармацыйнага ўзроўню - NS_LOG_INFO. Давайце дадамо паведамленне (непасрэдна перад тым, як мы пачнем ствараць вузлы), якое кажа вам, што сцэнар знаходзіцца на этапе стварэння тапалогіі ("Creating Topology"). Гэта робіцца ў наступным фрагменце кода,
Адкрыйце scratch/myfirst.cc у вашым каханым рэдактары і дадайце радок,
NS_LOG_INFO ("Creating Topology");
прама перад радкамі,

NodeContainer nodes;
nodes.Create (2);

Цяпер скампілюйце скрыпт, выкарыстоўваючы вафля, і ачысціце зменную NS_LOG, каб адключыць струмень часопісавання, які мы ўключылі раней:

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

вы не ўбачыце новае паведамленне, бо злучаны з ім кампанент часопісавання (FirstScriptExample) не быў уключаны. Каб убачыць ваша паведамленне, вам трэба ўключыць кампанент вядзення часопіса FirstScriptExample з узроўнем не ніжэй за NS_LOG_INFO. Калі вы проста хочаце ўбачыць гэты канкрэтны ўзровень вядзення часопіса, вы можаце ўключыць яго так,

$ export NS_LOG=FirstScriptExample=info

Калі вы зараз запусціце скрыпт, то ўбачыце новае паведамленне «Creating Topology»,

Waf: Entering directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' finished successfully (0.404s)
Creating Topology
Sent 1024 bytes to 10.1.1.2
Received 1024 bytes from 10.1.1.1
Received 1024 bytes from 10.1.1.2

5.2 Выкарыстанне аргументаў каманднага радка

5.2.1 Пераазначэнне значэнняў атрыбутаў па змаўчанні

Іншы спосаб змяніць паводзіны сцэнараў ns‑3 без рэдагавання і зборкі - выкарыстанне аргументаў каманднага радка. Мы даем механізм для разбору аргументаў каманднага радка і аўтаматычнай усталёўкі лакальных і глабальных зменных на аснове вынікаў.

Першым крокам у выкарыстанні сістэмы аргументаў каманднага радка з'яўляецца аб'ява сінтаксічнага аналізатара каманднага радка. Гэта зрабіць даволі проста (у вашай асноўнай праграме), як у наступным кодзе,

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

Гэты просты двухрадковы фрагмент насамрэч вельмі карысны сам па сабе. Ён адчыняе дзверы да глабальнай зменнай ns‑3 і сістэме атрыбутаў. Давайце дадамо два радкі кода ў пачатак галоўнай функцыі скрыпту scratch/myfirst.cc. Рухаючыся далей, кампілюем сцэнар і запускаем яго, пры запуску які робіцца запыт даведкі наступным чынам,

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

Гэтая каманда папросіць Waf запусціць скрыпт scratch/myfirst і перадаць яму аргумент каманднага радка -PrintHelp. Звычкі неабходныя, каб паказаць, для якой праграмы прызначаны аргумент. Парсер каманднага радка выявіць аргумент -PrintHelp і выведзе адказ,

Waf: Entering directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' finished successfully (0.413s)
TcpL4Protocol:TcpStateMachine()
CommandLine:HandleArgument(): Handle arg name=PrintHelp value=
--PrintHelp: Print this help message.
--PrintGroups: Print the list of groups.
--PrintTypeIds: Print all TypeIds.
--PrintGroup=[group]: Print all TypeIds of group.
--PrintAttributes=[typeid]: Print all attributes of typeid.
--PrintGlobals: Print the list of globals.

Цяпер разгледзім опцыю -PrintAttributes. Мы ўжо згадвалі сістэму атрыбутаў ns‑3 пры вывучэнні скрыпту first.cc. Мы бачылі наступныя радкі кода,

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

і казалі, што DataRate на самой справе з'яўляецца атрыбутам PointToPointNetDevice. Давайце прымянім сінтаксічны аналізатар аргументаў каманднага радка для прагляду атрыбутаў PointToPointNetDevice. Спіс дапамогі кажа, што мы павінны прадаставіць TypeId. Гэта імя класа, да якога належаць цікавыя атрыбуты. У нашым выпадку гэта будзе ns3::PointToPointNetDevice. Працягнем рухацца наперад, увядзіце,

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

Сістэма раздрукуе ўсе атрыбуты гэтага тыпу сеткавай прылады. Вы ўбачыце, што сярод атрыбутаў у спісе ёсць,

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

Гэта значэнне па змаўчанні, якое будзе выкарыстоўвацца ў сістэме пры стварэнні аб'екта PointToPointNetDevice. Мы перавызначым гэтае значэнне па змаўчанні з дапамогай параметру атрыбут в PointToPointHelper вышэй. Давайце выкарыстоўваць значэння па змаўчанні для кропка-кропка прылад і каналаў. Для гэтага выдалім выклікі SetDeviceAttribute и SetChannelAttribute з myfirst.cc, які мы маем у чыстай дырэкторыі.

Ваш скрыпт павінен зараз проста аб'явіць PointToPointHelper і не выконваць ніякіх аперацый па ўстаноўцы, як паказана ў прыкладзе ніжэй,

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

Працягвайце і стварыце новы скрыпт з Waf (./waf) і давайце вернемся назад і ўключым некаторы запіс з UDP рэха-прыкладанні сервера і ўключым прэфікс часу.

$ export 'NS_LOG=UdpEchoServerApplication=level_all|prefix_time'

Калі вы запусціце скрыпт, то павінны ўбачыць наступную выснову:

Waf: Entering directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' finished successfully (0.405s)
0s UdpEchoServerApplication:UdpEchoServer()
1s UdpEchoServerApplication:StartApplication()
Sent 1024 bytes to 10.1.1.2
2.25732s Received 1024 bytes from 10.1.1.1
2.25732s Echoing packet
Received 1024 bytes from 10.1.1.2
10s UdpEchoServerApplication:StopApplication()
UdpEchoServerApplication:DoDispose()
UdpEchoServerApplication:~UdpEchoServer()

Нагадаем, што ў мінулы раз, калі мы глядзелі па часе сімуляцыі, момант атрымання пакета рэха-серверам, гэта было ў 2,00369-XNUMX секунд.

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

Цяпер ён атрымлівае пакет у 2.25732 секунды. Гэта таму, што мы проста скінулі хуткасць перадачы дадзеных PointToPointNetDevice з пяці мегабіт у секунду да значэння па змаўчанні, якое складае 32768 біт у секунду. Калі б мы падставілі новы DataRate з дапамогай каманднага радка, мы маглі б зноў паскорыць нашае мадэляванне. Мы зробім гэта наступным чынам, паводле формулы, якая разумеецца элементам даведкі:

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

У выніку значэнне атрыбуту DataRate па змаўчанні вернецца да пяці мегабітам у секунду. Вы здзіўлены вынікам? Аказваецца, каб вярнуць зыходныя паводзіны сцэнара, нам трэба таксама ўсталяваць затрымку канала адпаведную хуткасці святла. Мы можам папрасіць сістэму каманднага радка раздрукаваць атрыбуты канала, таксама як мы рабілі для сеткавай прылады:

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

Мы выявім, што атрыбут затрымкі канала ўсталяваны наступным чынам:

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

Затым мы можам праз сістэму каманднага радка ўсталяваць абодва гэтых значэння па змаўчанні,

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

у гэтым выпадку мы аднаўляем час, які ў нас быў, калі мы відавочна ўсталявалі DataRate і Delay у сцэнары:

Waf: Entering directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' finished successfully (0.417s)
0s UdpEchoServerApplication:UdpEchoServer()
1s UdpEchoServerApplication:StartApplication()
Sent 1024 bytes to 10.1.1.2
2.00369s Received 1024 bytes from 10.1.1.1
2.00369s Echoing packet
Received 1024 bytes from 10.1.1.2
10s UdpEchoServerApplication:StopApplication()
UdpEchoServerApplication:DoDispose()
UdpEchoServerApplication:~UdpEchoServer()

Звярніце ўвагу, што пакет зноў атрыманы серверам праз 2,00369 секунд. Мы маглі б на самой справе ўсталяваць такім чынам любы з выкарыстоўваных у сцэнары атрыбутаў. У прыватнасці, мы маглі б ўсталяваць выдатныя ад адзінкі значэння атрыбутаў MaxPackets UdpEchoClient.

Як бы вы выкарыстоўвалі гэта? Паспрабуйце. Памятайце, што вы павінны закаментаваць месца, дзе мы перавызначаем значэнне атрыбуту па змаўчанні і відавочна ўсталяваць MaxPackets у сцэнары. Затым вы павінны перасабраць скрыпт. Вы таксама можаце сродкамі каманднага радка атрымаць даведку аб сінтаксісе для ўсталёўкі новага значэння атрыбуту па змаўчанні. Разабраўшыся ў гэтым вы зможаце кіраваць колькасцю пакетаў, якія адлюстроўваюцца ў камандным радку. Паколькі мы старанныя людзі, то наш камандны радок павінен выглядаць прыкладна так:

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

Натуральнае пытанне, якое ўзнікае ў гэтым месцы, заключаецца ў тым, як даведацца пра існаванне ўсіх гэтых атрыбутаў. Ізноў жа, сістэма каманднага радка мае функцыю дапамогі ў гэтым пытанні. Калі мы запытаем дапамогу каманднага радка, то мы павінны ўбачыць:

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

Калі вы вылучыце аргумент "PrintGroups", то павінны ўбачыць спіс усіх зарэгістраваных груп TypeId. Імёны груп стасуюцца з імёнамі модуляў у зыходнай дырэкторыі (хоць і з вялікай літары). Раздрукоўка ўсёй інфармацыі адразу будзе занадта аб'ёмнай, таму даступны дадатковы фільтр для друку інфармацыі па групах. Так, зноў факусуючыся на модулі "кропка-кропка":

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

Тут можна знайсці даступныя імёны TypeId для пошуку атрыбутаў, напрыклад, у
--PrintAttributes = ns3 :: PointToPointChannel, як паказана вышэй.

Яшчэ адзін спосаб пазнаць аб атрыбутах праз Doxygen ns‑3. Там ёсць старонка, якая пералічвае ўсе зарэгістраваныя ў сімулятары атрыбуты.

5.2.2 Захоп вашых уласных каманд

Вы таксама можаце праз сістэму каманднага радка дадаць свае ўласныя хукі. Гэта робіцца даволі проста з дапамогай метад парсера каманднага радка AddValue.
Давайце выкарыстоўваем гэтай магчымасць, каб паказаць колькасць пакетаў, якія павінны адлюстроўвацца, зусім іншым спосабам. Давайце дадамо лакальную зменную з імем nPackets у функцыю асноўнай. Мы ўсталюем яе ў адзінку, каб адпавядаць нашым папярэднім паводзінам па змаўчанні. Каб дазволіць парсеру каманднага радка, змяніць гэтае значэнне, нам трэба захапіць гэтае значэнне ў парсер. Мы робім гэта, дадаўшы выклік AddValue. Перайдзіце і змяніце скрыпт scratch/myfirst.cc так, каб пачаць з наступнага кода,

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

Пракруціце ўніз да кропкі ў скрыпце, дзе мы ўсталёўваны атрыбут MaxPackets і зменіце яго так, каб ён быў наладжаны на зменную nPackets замест канстанты 1, як паказана ніжэй.

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

Цяпер, калі вы запусціце скрыпт і падставіце аргумент - PrintHelp, вы павінны ўбачыць новы аргумент карыстальніка. пералічаны на дысплеі даведкі. Увядзіце,

$ ./waf --run "scratch/myfirst --PrintHelp"
Waf: Entering directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' finished successfully (0.403s)
--PrintHelp: Print this help message.
--PrintGroups: Print the list of groups.
--PrintTypeIds: Print all TypeIds.
--PrintGroup=[group]: Print all TypeIds of group.
--PrintAttributes=[typeid]: Print all attributes of typeid.
--PrintGlobals: Print the list of globals.
User Arguments:
--nPackets: Number of packets to echo

Калі вы жадаеце змяніць колькасць перадаваных пакетаў, вы можаце зрабіць гэта, усталяваўшы ў камандным радку аргумент - -nPackets,

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

Цяпер вы павінны зараз убачыць

Waf: Entering directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' finished successfully (0.404s)
0s UdpEchoServerApplication:UdpEchoServer()
1s UdpEchoServerApplication:StartApplication()
Sent 1024 bytes to 10.1.1.2
2.25732s Received 1024 bytes from 10.1.1.1
2.25732s Echoing packet
Received 1024 bytes from 10.1.1.2
Sent 1024 bytes to 10.1.1.2
3.25732s Received 1024 bytes from 10.1.1.1
3.25732s Echoing packet
Received 1024 bytes from 10.1.1.2
10s UdpEchoServerApplication:StopApplication()
UdpEchoServerApplication:DoDispose()
UdpEchoServerApplication:~UdpEchoServer()

Вы зараз адправілі два пакеты. Даволі проста, ці не праўда?
Вы можаце бачыць, што як карыстач ns‑3, вы можаце выкарыстоўваць сістэму аргументаў каманднага радка для кіравання глабальнымі значэннямі і атрыбутамі. Калі вы аўтар мадэлі, вы можаце дадаць новыя атрыбуты да вашых аб'ектаў, і яны будуць аўтаматычна даступныя для наладкі вашымі карыстальнікамі праз сістэму каманднага радка. Калі вы аўтар сцэнара, вы можаце дадаваць новыя зменныя ў вашыя скрыпты і бязбольна падлучаць іх да сістэмы каманднага радка.

5.3 Выкарыстанне сістэмы трасіроўкі

Увесь сэнс мадэлявання заключаецца ў стварэнні выходных дадзеных для далейшага вывучэння, а сістэма трасіроўкі ns-3 з'яўляецца асноўным механізмам для гэтага. Паколькі ns‑3 – гэта праграма на C++, то могуць быць скарыстаны стандартныя сродкамі генерацыі выходных дадзеных праграмы на C++:

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

Вы нават можаце выкарыстоўваць модуль часопісавання, каб дадаць невялікую структуру ў ваша рашэнне. Вядома шмат праблем спараджаюцца такім падыходам і таму для вырашэння гэтых праблем мы падалі агульную падсістэму трасіроўкі падзей.

Асноўныя мэты сістэмы трасіроўкі ns‑3:

  • Для базавых задач сістэма трасіроўкі павінна дазваляць карыстачу генераваць стандартную трасіроўку для папулярных крыніц, і выбіраць аб'екты генеруюць трасіроўку;

  • Прамежкавыя карыстачы павінны мець магчымасць пашыраць сістэму трасіроўкі для змены генераванага выходнага фармату або для ўстаўкі новых крыніц трасіроўкі, без мадыфікацыі ядра сімулятара;

  • Дасведчаныя карыстачы могуць мадыфікаваць ядро ​​сімулятара для дадання новых крыніц і прымачоў трасіроўкі. Сістэма трасіроўкі ns‑3 пабудавана на прынцыпах незалежных крыніц адсочвання і прымачоў, а таксама ўніфікаваным механізме падлучэння крыніц да спажыўцоў.

Сістэма трасіроўкі ns-3 пабудавана на прынцыпах незалежных крыніц і прымачоў трасіроўкі, а таксама ўніфікаваны механізм падлучэння крыніц да прымачоў. Крыніцамі трасіроўкі з'яўляюцца аб'екты, якія могуць сігналізаваць аб падзеях, якія адбываюцца ў сімуляцыі і забяспечыць доступ да базавых даных. Напрыклад, крыніца трасіроўкі можа паказваць, калі сеткавая прылада атрымала пакет і забяспечвае доступ да змесціва пакета для зацікаўленых прымачоў трасіроўкі.

Крыніцы трасіроўкі самі па сабе бескарысныя, калі яны не "звязаны" з іншымі часткамі кода, якія насамрэч робяць з інфармацыяй, прадстаўленай прымачом, нешта карыснае. Трасіроўшчыкі з'яўляюцца спажыўцамі падзей і даных, прадастаўленых крыніцамі трасіроўкі. Напрыклад, можна стварыць прымач трасіроўкі, які будзе (пры падлучэнні да крыніцы трасіроўкі папярэдняга прыклад) выводзіць на друк якія цікавяць часткі атрыманага пакета.

Разумная падстава для такога відавочнага падзелу складаецца ў тым, каб дазволіць карыстачам падлучаць новыя тыпы прымачоў да існых крыніц трасіроўкі без неабходнасці рэдагавання і перакампіляванні ядра сімулятара. Такім чынам, у прыведзеным вышэй прыкладзе карыстач можа вызначыць новы трасіроўшчык у сваім скрыпце і падлучыць яго да існай крыніцы трасіроўкі, вызначанай у ядры сімуляцыі, толькі рэдагуючы карыстацкі скрыпт.

У гэтым кіраўніцтве мы пройдземся па некаторых наканаваных крыніцах і прымачах і пакажам, як іх можна наладзіць з найменшымі намаганнямі з боку карыстальніка. Глядзіце Кіраўніцтва ns‑3 або раздзелы з інструкцыямі для атрымання інфармацыі аб пашыранай канфігурацыі трасіроўкі, уключаючы пашырэнне прасторы імёнаў трасіроўкі і стварэнне новых крыніц трасіроўкі.

5.3.1 ASCII Трасіроўка

ns‑3 забяспечвае дапаможны функцыянал, які дае нізкаўзроўневую сістэму трасіроўкі, каб дапамагчы вам з дэталямі, пры наладзе нескладаных трасіровак пакетаў. Калі вы ўключыце гэтую функцыю, вы ўбачыце выходныя дадзеныя ў файлах ASCII. Для тых, хто знаёмы з высновай ns-2, гэты тып трасіроўкі аналагічны out.tr, Які згенераваны мноствам скрыптоў.

Давайце пяройдзем да справы і дадамо некаторыя вынікі ASCII трасіроўкі ў наш скрыпт scratch/myfirst.cc. Прама перад выклікам Simulator :: Run (), дадайце наступныя радкі кода:
AsciiTraceHelper ascii;

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

Як і ў шматлікіх іншых ідыёмах ns‑3, гэты код выкарыстае дапаможны аб'ект для стварэння трасіровак ASCII. Другі радок утрымоўвае два ўкладзеных выкліку метаду. Метад «унутры» CreateFileStream () выкарыстоўвае ідыёму ананімнага аб'екта для стварэння аб'екта струменя файлаў у стэку (без імя аб'екта) і перадае яго выкліканаму метаду. У будучыні мы паглыбімся ў гэтае пытанне, але ўсё, што вам трэба ведаць на гэтым этапе, гэта тое, што вы ствараеце аб'ект, які прадстаўляе файл з імем myfirst.tr і перадаць яго ў ns‑3. Мы ўскладаем на ns‑3, клопат аб створаным аб'екце на ўвесь час яго жыцця, падчас якой вырашаюцца праблемы, выкліканых малавядомым (наўмысным) абмежаваннем злучаным з якія капіююць канструктарамі струменевых аб'ектаў C++.

Вонкавы выклік EnableAsciiAll() паведамляе памагатаму, што вы жадаеце ўлучыць у вашай сімуляцыі ASCII трасіроўку для ўсіх злучэнняў прылады кропка-кропка і тое, што вы жадаеце, каб (паказаныя) прымачы трасіроўкі запісвалі інфармацыю аб перасоўванні пакетаў у фармаце ASCII.

Для тых, хто знаёмы з ns-2, адсочваныя падзеі эквівалентныя вядомым кропкам трасіроўкі, якія часопісуюць падзеі "+", "-", "d" і "r".
Цяпер вы можаце сабраць скрыпт і запусціць яго з каманднага радка:

$ ./waf --run scratch/myfirst

Як шмат разоў да гэтага, вы ўбачыце некалькі паведамленняў ад Waf, а затым "'build' finished successfully" (зборка завершана паспяхова) з некаторай колькасцю паведамленняў ад працуючай праграмы.

Пры працы, праграма створыць файл з імем myfirst.tr. З-за асаблівасцей працы Waf, па змаўчанні файл ствараецца не ў лакальнай дырэкторыі, а ў дырэкторыі верхняга ўзроўня рэпазітара. Калі вы хочаце змяніць шлях, дзе захоўваюцца трасы, то каб паказаць яго вы можаце выкарыстоўваць для Waf параметр --cwd. Мы гэтага не зрабілі, то каб зірнуць на файл ASCII трасіроўкі myfirst.tr у вашым каханым рэдактары, нам запатрабуецца перайсці ў дырэкторыю верхняга ўзроўня нашага рэпазітара.

Парсінг ASCII трас

Там вельмі шмат інфармацыі ў даволі шчыльнай форме, але першае, на што трэба звярнуць увагу, дык гэта тое, што файл складаецца з асобных радкоў. Гэта стане выразна відаць, калі вы разгарнеце акно прагляду шырэй.

Кожны радок у файле адпавядае падзеі трасіроўкі. У дадзеным выпадку мы трасіруем падзеі ў чарзе перадачы, якая прысутнічае ў кожнай сеткавай прыладзе кропка-кропка ў сімуляцыі. Чарга перадачы - гэта чарга, праз якую павінен прайсці кожны пакет для канала кропка-кропка. Звярніце ўвагу, што кожны радок у файле трасіроўкі пачынаецца з адзіночнага сімвала (і мае прабел пасля яго). Гэты сімвал будзе мець наступнае значэнне:

+: у чарзе прылады адбылася аперацыя пастаноўкі ў чаргу;
-: у чарзе прылады адбылася аперацыя вымання элемента;
d: пакет быў адкінуты, як правіла, таму, што чарга запоўнена;
r: пакет быў атрыманы сеткавай прыладай.

Давайце больш дэталёва разгледзім першы радок у файле трасіроўкі. Я разаб'ю яе на часткі (з водступамі для нагляднасці) і нумарам радка злева:

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

Першы раздзел гэтай пашыранай падзеі трасіроўкі (радок 0) - гэта аперацыя. У нас тут сімвал +, што адпавядае аперацыі пастаноўкі ў чаргу на перадачу. Другая частка (радок 1) - час мадэлявання, выяўленае ў секундах. Вы можаце ўспомніць, што мы папрасілі UdpEchoClientApplication пачаць адпраўку пакетаў праз дзве секунды. Тут мы бачым пацверджанне таго, што гэта сапраўды адбываецца.

У наступным раздзеле прыкладу трасіроўкі (з радка 2) паказваецца, якая крыніца трасіроўкі спарадзіла гэту падзею (паказваецца трасіроўка прасторы імёнаў). Вы можаце ўяўляць прастору імёнаў трасіроўкі прыкладна гэтак жа, як прасторы імёнаў файлавай сістэмы. Коранем прасторы імёнаў з'яўляецца NodeList. Гэта адпавядае кантэйнеру, які кіруецца ў асноўным кодзе ns‑3. У ім змяшчаюцца ўсе вузлы, якія ствараюцца ў скрыпце. Гэтак жа, як файлавая сістэма можа мець у корані дырэкторыі, у NodeList у нас можа быць мноства вузлоў. Такім чынам, радок /NodeList/0 спасылаецца на нулявы вузел у NodeList, які мы звычайна разумеем як "вузел 0". У кожным вузле ёсць спіс прылад, якія былі ўстаноўлены. Гэты спіс размешчаны наступным у прасторы імёнаў. Вы можаце бачыць, што гэта падзея трасіроўкі зыходзіць з DeviceList/0, Які з'яўляецца прыладай нулявым устаноўленым у вузле.

Наступны падрадок, $ ns3 :: PointToPointNetDevice, паведамляе, якая прылада знаходзіцца ў нулявой пазіцыі: спісу прылад нулявога вузла. Нагадаем, што аперацыя +, змешчаная ў радку 0, азначала, што ў чарзе перадачы прылады адбылося даданне элемента. Гэта адлюстравана ў апошніх сегментах шляху трасы : TxQueue/Enqueue.

Астатнія раздзелы ў трасіроўцы павінны быць дастаткова зразумелыя інтуітыўна. Радкі 3-4 паказваюць, што пакет інкапсуляванага ў пратаколе кропка-кропка. Радкі 5-7 паказваюць, што пакет мае загаловак версіі IP4 і ўзнік у IP-адрасе 10.1.1.1 і прызначаны для 10.1.1.2. Радкі 8-9 паказваюць, што гэты пакет мае загаловак UDP і, нарэшце, радок 10 паказвае, што карысная нагрузка - чаканыя 1024 байта.

Наступны радок у файле трасіроўкі паказвае, што той жа пакет быў выняты з чаргі перадачы на ​​тым жа вузле.

Трэці радок у файле трасіроўкі паказвае, што пакет прыняты сеткавай прыладай на вузле з рэха-серверам. Я прайграў гэтую падзею ніжэй.

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

Звярніце ўвагу, што аперацыя трасіроўкі зараз r, а час сімуляцыі павялічана да 2,25732 секунд. Калі вы ўважліва прытрымліваліся інструкцый падручніка, то гэта азначае, што вы пакінулі DataRate сеткавых прылад і затрымку канала ў іх значэннях па змаўчанні. Гэты час павінен быць знаёмы, як вы ўжо бачылі ў папярэднім раздзеле.

Запіс прасторы імёнаў крыніцы трасіроўкі (радок 2) быў зменены, каб адлюстраваць, што гэтая падзея зыходзіць ад вузла 1 (/NodeList/1) і пакет прыняты крыніцай трасіроўкі (/MacRx). Вам павінна быць даволі лёгка адсачыць за рухам пакета праз тапалогію, праглядаючы пакінутыя ў файле трасы.

5.3.2 Трасіроўка PCAP

Памочнікі прылад ns‑3 таксама можна выкарыстоўваць для стварэння файлаў трасіроўкі ў фармаце. Pcap. Акронім PCAP (звычайна пішацца ў ніжнім рэгістры) абазначае захоп пакетаў і фактычна з'яўляецца API, які ўключае вызначэнне фармату файла .pcap. Найбольш папулярнай праграмай, якая можа чытаць і адлюстроўваць гэты фармат, з'яўляецца Wireshark (раней называлася эфірны). Тым не менш, ёсць шмат аналізатараў трасіроўкі трафіку, якія выкарыстоўваюць гэты фармат пакета. Мы рэкамендуем карыстальнікам выкарыстоўваць мноства інструментаў, даступных для аналізу pcap трас. У гэтым кіраўніцтве мы засяродзімся на праглядзе pcap трас з дапамогай tcpdump.

Уключэнне pcap трасіроўкі, выконваецца адным радком кода.

pointToPoint.EnablePcapAll ("myfirst");

Устаўце гэты радок кода пасля кода трасіроўкі ASCII, які мы толькі што дадалі ў scratch/myfirst.cc. Звярніце ўвагу, што мы перадалі толькі радок "myfirst", а не "myfirst.pcap" ці нешта падобнае. Гэта таму, што параметр гэта прэфікс, а не поўнае імя файла. Падчас сімуляцыі памагаты фактычна створыць файл трасіроўкі для кожнай прылады кропка-кропка. Імёны файлаў будуць пабудаваны з выкарыстаннем прэфікса, нумара вузла, нумара прылады і суфікса”.PCAP.

Для нашага прыкладу сцэнара мы ў канчатковым выніку ўбачым файлы з імёнамі.myfirst-0-0.pcap»І«myfirst-1-0.pcap», якія з'яўляюцца pcap трасіроўкамі для вузла 0-прылада 0 і вузла 1-прылада 0 адпаведна. Пасля таго, як вы дадалі радок кода для ўключэння pcap трасіроўкі, вы можаце запусціць скрыпт звычайным спосабам:

$ ./waf --run scratch/myfirst

Калі вы паглядзіце ў дырэкторыю верхняга ўзроўню вашага дыстрыбутыва, вы павінны ўбачыць тры файлы: файл ASCII трасіроўкі myfirst.tr, які мы перад гэтым вывучылі, файлы myfirst-0-0.pcap и myfirst-1-0.pcap - новыя pcap файлы, якія мы толькі што згенеравалі.

Чытанне вываду з дапамогай tcpdump

На дадзены момант для прагляду файлаў pcap прасцей за ўсё будзе выкарыстоўваць tcpdump.

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

У дампе myfirst-0-0.pcap (кліенцкае прылада) вы можаце бачыць, што рэха-пакет адпраўляецца праз 2 секунды сімуляцыі. Калі вы паглядзіце на другі дамп (myfirst-1-0.pcap), вы ўбачыце, што пакет прымаецца ў момант 2,257324 секунды. Вы ўбачыце ў другім дампе, што пакет вяртаецца ў момант 2.257324 секунды, і, нарэшце, што пакет быў атрыманы кліентам назад у першым дампе ў момант 2.514648 секунд.

Чытанне вываду з дапамогай Wireshark

Калі вы не знаёмыя з Wireshark, ёсць вэб-сайт, з якога вы можаце спампаваць праграмы і дакументацыю: http://www.wireshark.org/. Wireshark - Гэта графічны інтэрфейс карыстальніка, які можна выкарыстоўваць для адлюстравання гэтых файлаў трасіроўкі. Калі ў вас ёсць Wireshark, вы можаце адкрыць любы з файлаў трасіроўкі і адлюстраваць змесціва, як калі б вы захапілі пакеты, выкарыстоўваючы аналізатар пакетаў.

Крыніца: habr.com

Дадаць каментар