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 logging մոդուլին՝ նայելով սցենարը առաջին.cc. Այս գլխում մենք ավելի մանրամասն կանդրադառնանք անտառահատումների ենթահամակարգի հնարավոր կիրառություններին:

5.1.1 Մատյանների ակնարկ

Բազմաթիվ խոշոր համակարգեր աջակցում են հաղորդագրությունների գրանցման մի տեսակ, և ns-3-ը բացառություն չէ: Որոշ դեպքերում «օպերատորի կոնսոլին» գրվում են միայն սխալի հաղորդագրություններ (որը սովորաբար stderr է Unix-ի վրա հիմնված համակարգերում): Այլ համակարգերում կարող են ցուցադրվել նախազգուշական հաղորդագրություններ, ինչպես նաև ավելի մանրամասն տեղեկություններ: Որոշ դեպքերում գրանցման գործիքներն օգտագործվում են վրիպազերծման հաղորդագրություններ դուրս բերելու համար, որոնք կարող են արագորեն մշուշել ելքը:

ns-3-ում օգտագործվող subHRD-ը ենթադրում է, որ տեղեկատվական բովանդակության այս բոլոր մակարդակները օգտակար են, և մենք տրամադրում ենք ընտրովի, շերտավոր մոտեցում հաղորդագրությունների գրանցման համար: Գրանցումը կարող է ամբողջությամբ անջատվել, միացնել յուրաքանչյուր բաղադրիչի հիման վրա կամ գլոբալ: Այդ նպատակով օգտագործվում են տեղեկատվական բովանդակության կարգավորելի մակարդակներ: ns-3 logging մոդուլը համեմատաբար պարզ միջոց է տալիս ձեր սիմուլյացիայից օգտակար տեղեկատվություն ստանալու համար:

Դուք պետք է հասկանաք, որ մենք տրամադրում ենք ընդհանուր նպատակի մեխանիզմ՝ հետագծում, ձեր մոդելներից տվյալներ հանելու համար, որը պետք է լինի սիմուլյացիաների նախընտրելի արդյունքը (մեր հետագծման համակարգի մասին լրացուցիչ տեղեկությունների համար տե՛ս ձեռնարկի բաժին 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 մակրոյով տրամադրված հաղորդագրությունները միացնելով, միացնելով LOG_LEVEL_INFO մակրոները, ներառելով նաև LOG_LEVEL_INFO-ի կողմից տրամադրված հաղորդագրությունները: _WARN և NS_LOG_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 echo հաճախորդի հավելվածը պատասխանում է հետևյալ կոդի հետևյալ տողին 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

Այսպիսով, մենք sh shell փոփոխականը սահմանեցինք NS_LOG հետևյալ արժեքով.

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++ շրջանակի օպերատորը (: :): Սա միտումնավոր է:

Սա իրականում դասի անվանումը չէ, այլ լոգինգ բաղադրիչի անվանումը: Երբ աղբյուրի ֆայլի և դասի միջև համընկնում է, դա սովորաբար դասի անունն է, բայց դուք պետք է հասկանաք, որ դա իրականում դասի անունը չէ, և կրկնակի երկու կետի փոխարեն կա մեկ կետ: Սա մի միջոց է, որը կօգնի ձեզ կոնցեպտուալ կերպով առանձնացնել logging bean անունը դասի անունից համեմատաբար նուրբ ձևով:

Այնուամենայնիվ, որոշ դեպքերում կարող է դժվար լինել որոշել, թե որ մեթոդն է իրականում ստեղծում գրանցամատյանի հաղորդագրությունը: Եթե ​​նայեք վերևի տեքստին, կարող եք մտածել, թե որտեղ է տողը »Received 1024 bytes from 10.1.1.2« Դուք կարող եք լուծել այս խնդիրը մակարդակը սահմանելով prefix_func NS_LOG միջավայրի փոփոխականին: Փորձեք հետևյալը.

$ export 'NS_LOG=UdpEchoClientApplication=level_all|prefix_func'

Նկատի ունեցեք, որ չակերտներն անհրաժեշտ են, քանի որ ուղղահայաց բարը, որը մենք օգտագործում ենք OR գործողությունը ներկայացնելու համար, նույնպես 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 echo հաճախորդի հավելվածից եկող բոլոր հաղորդագրությունները նույնացվում են որպես այդպիսին: Հաղորդագրություն»Received 1024 bytes from 10.1.1.2«Այժմ պարզորոշված ​​է, որ այն գալիս է echo հաճախորդի հավելվածից: Մնացած հաղորդագրությունը պետք է գա UDP echo սերվերի հավելվածից: Մենք կարող ենք ակտիվացնել այս բաղադրիչը՝ մուտքագրելով 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()

Երբեմն նաև օգտակար է տեսնել սիմուլյացիայի ժամանակը, երբ ստեղծվել է տեղեկամատյան հաղորդագրությունը: Դուք կարող եք դա անել՝ ավելացնելով OR բիթը նախածանց_ժամանակ:

$ 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 սկսել է echo սերվերի հավելվածը սիմուլյացիայի մեկնարկից մեկ վայրկյան առաջ: Այժմ դուք կարող եք տեսնել, որ մեթոդը StartApplication սերվերը իրականում կանչվում է առաջին վայրկյանին: Կարող եք նաև նկատել, որ echo-հաճախորդը սկսվում է սիմուլյացիայի երկրորդ վայրկյանից, ինչպես մենք խնդրել ենք սցենարում:

Այժմ դուք կարող եք հետևել սիմուլյացիայի առաջընթացին կանչով ScheduleTransmit հաճախորդում, որը կանչում է HandleRead հետ կանչը Ուղարկեք echo սերվերի հավելվածը: Նկատի ունեցեք, որ կետից կետ հղումով փաթեթ ուղարկելու համար անցած ժամանակը 3,69 միլիվայրկյան է: Դուք կարող եք տեսնել, որ echo սերվերը գրանցում է հաղորդագրություն, որ նա պատասխանել է փաթեթին, և այնուհետև, ալիքի ուշացումից հետո, տեսնում եք, որ echo-հաճախորդը ստանում է echo փաթեթը իր HandleRead մեթոդով:

Այս սիմուլյացիայի մեջ շատ բան տեղի է ունենում առանց դուք նկատելու: Բայց դուք կարող եք շատ հեշտությամբ հետևել ամբողջ գործընթացին` միացնելով համակարգում գրանցման բոլոր բաղադրիչները: Փորձեք սահմանել NS_LOG փոփոխականը հետևյալ արժեքով.

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

Վերևի աստղանիշը լոգերի բաղադրիչի նիշ է: Սա կներառի սիմուլյացիայի մեջ օգտագործվող բոլոր բաղադրիչների բոլոր գրառումները: Ես այստեղ չեմ վերարտադրի ելքը (գրելու պահին այն արտադրում է 1265 տող ելք մեկ էկո փաթեթի համար), բայց դուք կարող եք վերահղել այս տեղեկատվությունը ֆայլ և դիտել այն ձեր սիրելի խմբագրիչում:

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

Ես անձամբ օգտագործում եմ անտառահատումների այս չափազանց խոսուն տարբերակը, երբ խնդիր եմ ունենում և գաղափար չունեմ, թե որտեղ են սխալները: Ես կարող եմ բավականին հեշտությամբ հետևել կոդերի կատարմանը, առանց բեկման կետեր սահմանելու և սխալների հայտնաբերման կոդի միջով անցնելու: Ես կարող եմ պարզապես խմբագրել արդյունքը իմ սիրելի խմբագրիչում և փնտրել այն, ինչ ակնկալում եմ, և տեսնել, թե ինչ է կատարվում, որը ես չէի սպասում: Երբ ես ընդհանուր պատկերացում ունենամ այն ​​մասին, թե ինչն է սխալ, ես ցատկում եմ վրիպազերծիչը՝ խորացնելու խնդիրը: Այս տեսակի ելքը կարող է հատկապես օգտակար լինել, երբ ձեր սցենարը բոլորովին անսպասելի բան է անում: Եթե ​​դուք օգտագործում եք միայն վրիպազերծիչը, կարող եք ամբողջությամբ բաց թողնել շրջադարձը: Գրանցումը նկատելի է դարձնում նման շրջադարձերը։

5.1.3 Ձեր կոդի մեջ գրանցման ավելացում

Դուք կարող եք նոր գրառումներ ավելացնել ձեր սիմուլյացիաներին՝ զանգեր կատարելով մատյան բաղադրիչին մի քանի մակրոներից: Եկեք դա անենք սցենարով myfirst.cc, որը մենք ունենք «մաքուր» գրացուցակում: Հիշեցնենք, որ մենք սահմանել ենք գրանցման բաղադրիչ այս սցենարում.

NS_LOG_COMPONENT_DEFINE ("FirstScriptExample");

Դուք տեղյակ եք, որ կարող եք ակտիվացնել այս բաղադրիչի բոլոր հաղորդագրությունների գրանցումը` տարբեր մակարդակներում դնելով NS_LOG միջավայրի փոփոխականը: Եկեք առաջ գնանք և մի քանի գրառում ավելացնենք սցենարին: Մակրոն, որն օգտագործվում է տեղեկամատյանում տեղեկատվական մակարդակի հաղորդագրություններ ավելացնելու համար, NS_LOG_INFO է: Եկեք ավելացնենք հաղորդագրություն (նախքան մենք կսկսենք ստեղծել հանգույցներ), որը տեղեկացնում է ձեզ, որ սցենարը գտնվում է «Տոպոլոգիայի ստեղծում» փուլում: Սա արվում է հետևյալ կոդի հատվածում.
Բաց է 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

Եթե ​​հիմա գործարկեք սցենարը, կտեսնեք նոր հաղորդագրություն «Տոպոլոգիայի ստեղծում»,

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"

Այս հրամանը կհարցնի վաֆ գործարկել սցենարը 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"));

և նրանք ասացին Տվյալների տոկոսադրույքը իրականում հատկանիշ է 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) և եկեք վերադառնանք և ներառենք որոշ մուտք UDP echo սերվերի հավելվածից և ներառենք ժամանակի նախածանցը:

$ 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()

Հիշեցնենք, որ վերջին անգամ մենք նայեցինք սիմուլյացիայի ժամանակը, այն պահին, երբ փաթեթը ստացվեց echo սերվերի կողմից, դա 2,00369 վայրկյան էր:

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 անունները հատկանիշների որոնումների համար, օրինակ՝ in
--PrintAttributes = ns3 :: PointToPointChannelինչպես ցույց է տրված վերևում:

Հատկությունների մասին իմանալու մեկ այլ միջոց է Doxygen ns-3-ը: Կա մի էջ, որտեղ թվարկված են սիմուլյատորում գրանցված բոլոր հատկանիշները:

5.2.2 Ձեր սեփական հրամանների ընդունումը

Կարող եք նաև ավելացնել ձեր սեփական կեռիկները հրամանի տող համակարգի միջոցով: Սա արվում է շատ պարզ՝ օգտագործելով հրամանի տողի վերլուծիչ մեթոդը AddValue.
Եկեք օգտագործենք այս հատկությունը՝ բոլորովին այլ ձևով նշելու փաթեթների քանակը։ Եկեք ավելացնենք տեղական փոփոխական, որը կոչվում է nՓաթեթներ ֆունկցիայի մեջ հիմնական. Մենք այն կդնենք մեկին, որպեսզի համապատասխանի մեր նախորդ լռելյայն վարքագծին: Որպեսզի հրամանի տողի վերլուծիչը փոխի այս արժեքը, մենք պետք է այս արժեքը գրավենք վերլուծիչում: Մենք դա անում ենք՝ ավելացնելով զանգ 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 Manual կամ «how-to» բաժինները՝ հետագծման առաջադեմ կազմաձևման մասին տեղեկությունների համար, ներառյալ հետագծերի անվան տարածքի ընդլայնումը և հետագծման նոր աղբյուրներ ստեղծելը:

5.3.1 ASCII հետագծում

ns-3-ն ապահովում է օգնականի գործառույթ, որն ապահովում է ցածր մակարդակի հետագծման համակարգ, որը կօգնի ձեզ մանրամասների հարցում պարզ փաթեթների հետքեր ստեղծելիս: Եթե ​​միացնեք այս հնարավորությունը, կտեսնեք արդյունքը ASCII ֆայլերում: Նրանց համար, ովքեր ծանոթ են ns-2 ելքին, հետքի այս տեսակը նման է դուրս.տր, որը ստեղծվում է բազմաթիվ սցենարներով։

Եկեք սկսենք գործին և ավելացնենք 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-ից, այնուհետև «կառուցումը» հաջողությամբ ավարտվեց» գործող ծրագրի որոշ հաղորդագրություններով:

Գործարկելիս ծրագիրը կստեղծի ֆայլ անունով myfirst.tr. Աշխատանքի բնույթից ելնելով վաֆ, լռելյայնորեն ֆայլը ստեղծվում է ոչ թե տեղական գրացուցակում, այլ պահեստի վերին մակարդակի գրացուցակում։ Եթե ​​ցանկանում եք փոխել ուղին, որտեղ պահվում են հետքերը, ապա կարող եք օգտագործել Waf պարամետրը այն նշելու համար: --cwd. Մենք դա չենք արել, ուստի ASCII հետագծային myfirst.tr ֆայլը դիտելու համար ձեր սիրելի խմբագրիչում, մենք պետք է նավարկենք դեպի մեր պահոցի վերին մակարդակի գրացուցակը:

ASCII հետքերի վերլուծություն

Այնտեղ շատ տեղեկատվություն կա բավականին խիտ ձևով, բայց առաջին բանը, որ դուք պետք է ուշադրություն դարձնեք, այն է, որ ֆայլը բաղկացած է առանձին տողերից: Սա հստակ տեսանելի կդառնա, եթե դիտման պատուհանն ավելի լայն ընդլայնեք:

Ֆայլի յուրաքանչյուր տող համապատասխանում է հետքի իրադարձությանը: Այս դեպքում մենք հետևում ենք իրադարձություններին սիմուլյացիայի յուրաքանչյուր կետից կետ ցանցային սարքում առկա փոխանցման հերթում: Փոխանցման հերթը այն հերթն է, որով յուրաքանչյուր փաթեթ պետք է անցնի կետից կետ կապի համար: Նկատի ունեցեք, որ հետագծային ֆայլի յուրաքանչյուր տող սկսվում է մեկ նիշով (և դրանից հետո ունի բացատ): Այս խորհրդանիշը կունենա հետևյալ նշանակությունը.

+. սարքի հերթում տեղի է ունեցել հերթագրման գործողություն.
-. սարքի հերթում տեղի է ունեցել տարրերի որոնման գործողություն.
դ. փաթեթը բաց թողնվեց, սովորաբար այն պատճառով, որ հերթը լիքն էր.
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 բայթ է:

Հետագծման ֆայլի հաջորդ տողը ցույց է տալիս, որ նույն փաթեթը հանվել է նույն հանգույցի փոխանցման հերթից:

Հետագծման ֆայլի երրորդ տողը ցույց է տալիս, որ փաթեթը ստացվել է ցանցային սարքի կողմից echo սերվերի հոսթի վրա: Միջոցառումը վերարտադրել եմ ստորև։

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-ը և Link Delay-ը իրենց լռելյայն արժեքներով: Այս լարվածությունը պետք է ծանոթ լինի, ինչպես տեսաք նախորդ բաժնում:

Հետագծման աղբյուրի անվանատարածքի մուտքագրումը (տող 2) փոփոխվել է, որպեսզի արտացոլի, որ այս իրադարձությունը ծագում է հանգույց 1-ից (/NodeList/1) և փաթեթը ստացվում է հետքի աղբյուրի կողմից (/MacRx) Ձեզ համար բավականին հեշտ պետք է լինի հետևել փաթեթի շարժմանը տոպոլոգիայի միջով՝ դիտելով ֆայլում մնացած հետքերը:

5.3.2 PCAP Հետք

ns-3 Device Helpers-ը կարող է օգտագործվել նաև .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 (հաճախորդի սարք) դուք կարող եք տեսնել, որ echo փաթեթն ուղարկվում է սիմուլյացիայից 2 վայրկյան հետո: Եթե ​​նայեք երկրորդ աղբանոցին (myfirst-1-0.pcap), կտեսնեք, որ փաթեթը ստացվել է 2,257324 վայրկյանում։ Երկրորդ աղբավայրում կտեսնեք, որ փաթեթը վերադարձվում է 2.257324 վայրկյանում, և վերջապես, որ փաթեթը հաճախորդը հետ է ստացել առաջին աղբավայրում 2.514648 վայրկյանում:

Արդյունքների ընթերցում Wireshark-ով

Եթե ​​ծանոթ չեք Wireshark, կա կայք, որտեղից կարող եք ներբեռնել ծրագրեր և փաստաթղթեր. http://www.wireshark.org/. Wireshark GUI է, որը կարող է օգտագործվել այս հետագծային ֆայլերը ցուցադրելու համար: Եթե ​​ունեք Wireshark, կարող եք բացել հետագծային ֆայլերից որևէ մեկը և ցուցադրել բովանդակությունը այնպես, կարծես փաթեթները գրավել եք փաթեթների հայտնաբերման միջոցով:

Source: www.habr.com

Добавить комментарий