ns-3 ցանցի սիմուլյատորի ձեռնարկ: Գլուխ 4

ns-3 ցանցի սիմուլյատորի ձեռնարկ: Գլուխ 4
գլուխ 1,2
գլուխ 3

4 Հայեցակարգի ակնարկ
4.1 Հիմնական աբստրակցիաներ
4.1.1 Հանգույց
4.1.2 Կիրառում
4.1.3 Ալիք
4.1.4 Զուտ սարք
4.1.5 Տոպոլոգիական օգնականներ
4.2 Առաջին ns-3 սցենար
4.2.1 Կաթսայի ծածկագիր
4.2.2 Փլագիններ
4.2.3 ns3 անվանատարածք
4.2.4 անտառահատումներ
4.2.5 Հիմնական գործառույթը
4.2.6 Տոպոլոգիայի օգնականների օգտագործումը
4.2.7 Օգտագործելով հավելվածը
4.2.8 Սիմուլյատոր
4.2.9 Կառուցեք ձեր սցենարը
4.3 ns-3 Աղբյուրի կոդը

Գլուխ 4

Հայեցակարգի ակնարկ

Առաջին բանը, որ մենք պետք է անենք, նախքան սկսենք սովորել կամ գրել ns-3 կոդը, բացատրելն է համակարգում մի քանի հիմնական հասկացություններ և աբստրակցիաներ: Սրա մեծ մասը կարող է ոմանց համար ակնհայտ թվալ, բայց մենք խորհուրդ ենք տալիս ժամանակ տրամադրել այս բաժինը կարդալու համար, որպեսզի համոզվեք, որ դուք սկսում եք ամուր հիմքի վրա:

4.1 Հիմնական աբստրակցիաներ

Այս բաժնում մենք կանդրադառնանք որոշ տերմինների, որոնք սովորաբար օգտագործվում են համացանցում, բայց ունեն հատուկ նշանակություն ns-3-ում:

4.1.1 Հանգույց

Համացանցի ժարգոնում համակարգչային սարքը, որը միանում է ցանցին, կոչվում է հոսթ կամ երբեմն վերջնական համակարգ: Քանի որ ns-3-ը ցանցային սիմուլյատոր է և ոչ թե ինտերնետի սիմուլյատոր, մենք միտումնավոր չենք օգտագործում հոսթ տերմինը, քանի որ այն սերտորեն կապված է ինտերնետի և դրա արձանագրությունների հետ: Փոխարենը, մենք օգտագործում ենք ավելի ընդհանուր տերմին, որն օգտագործվում է նաև այլ սիմուլյատորների կողմից, որը ծագում է գրաֆիկների տեսությունից՝ հանգույց (հանգույց).

ns-3-ում հաշվողական սարքի հիմքում ընկած աբստրակցիան կոչվում է հանգույց: Այս աբստրակցիան C++-ում ներկայացված է Node դասով։ Դասարան NodeNode (հանգույց) ապահովում է սիմուլյացիաներում հաշվողական սարքերի ներկայացումները շահարկելու մեթոդներ:

Դուք պետք է հասկանաք Հանգույց ինչպես համակարգիչը, որին դուք ֆունկցիոնալություն եք ավելացնում: Դուք կավելացնեք այնպիսի բաներ, ինչպիսիք են հավելվածները, արձանագրությունների կույտերը և ծայրամասային քարտերը վարորդներով, որոնք թույլ են տալիս համակարգչին օգտակար աշխատանք կատարել: Մենք օգտագործում ենք նույն հիմնական մոդելը ns-3-ում:

4.1.2 Կիրառում

Ընդհանուր առմամբ, համակարգչային ծրագրերը բաժանվում են երկու լայն դասի. Համակարգային ծրագրակազմը կազմակերպում է համակարգչային տարբեր ռեսուրսներ, ինչպիսիք են հիշողությունը, պրոցեսորի ցիկլերը, սկավառակը, ցանցը և այլն՝ ըստ որոշ հաշվողական մոդելի: Համակարգային ծրագրաշարը սովորաբար չի օգտագործում այդ ռեսուրսները՝ օգտվողին անմիջականորեն օգուտ բերող առաջադրանքներ կատարելու համար: Օգտագործողը սովորաբար գործարկում է հավելված՝ որոշակի նպատակին հասնելու համար, որը ստանում և օգտագործում է համակարգի ծրագրային ապահովման կողմից վերահսկվող ռեսուրսները:

Հաճախ համակարգի և կիրառական ծրագրերի միջև բաժանման գիծը գծվում է արտոնությունների մակարդակի փոփոխություններով, որոնք տեղի են ունենում օպերացիոն համակարգի թակարդներում: ns-3-ը չունի օպերացիոն համակարգի իրական գաղափար և, հետևաբար, արտոնությունների մակարդակների կամ համակարգային զանգերի հայեցակարգ: Այնուամենայնիվ, մենք գաղափար ունենք հավելվածի համար: Ճիշտ այնպես, ինչպես «իրական աշխարհում» ծրագրային հավելվածներն աշխատում են համակարգիչների վրա՝ առաջադրանքներ կատարելու համար, ns-3 հավելվածներն աշխատում են ns-3 հանգույցների վրա՝ մոդելավորված աշխարհում սիմուլյացիաները կառավարելու համար:

ns-3-ում օգտագործողի ծրագրի հիմնական աբստրակցիան, որը մոդելավորման համար որոշակի գործունեություն է առաջացնում, հավելվածն է: Այս աբստրակցիան C++-ում ներկայացված է Application դասով։ Application դասը տրամադրում է սիմուլյացիաներում հավելվածների մեր օգտատերերի մակարդակի տարբերակի դիտումները շահարկելու մեթոդներ: Ակնկալվում է, որ մշակողները կմասնագիտացնեն Application դասը օբյեկտի վրա հիմնված ծրագրավորման իմաստով՝ նոր հավելվածներ ստեղծելու համար: Այս ձեռնարկում մենք կօգտագործենք Application դասի մասնագիտացումները, որոնք կոչվում են UdpEchoClientApplication и UdpEchoServerApplication. Ինչպես կարող եք ակնկալել, այս հավելվածները կազմում են հաճախորդի/սերվերի հավելվածների մի շարք, որոնք օգտագործվում են ցանցային փաթեթներ ստեղծելու և արձագանքելու համար:

4.1.3 Ալիք

Իրական աշխարհում դուք կարող եք միացնել համակարգիչը ցանցին: Հաճախ լրատվամիջոցները, որոնց միջոցով տվյալները փոխանցվում են այս ցանցերում, կոչվում են ալիքներ: Երբ դուք միացնում եք Ethernet մալուխը պատի վարդակից, դուք միացնում եք ձեր համակարգիչը Ethernet հղմանը: Մոդելավորված ns-3 աշխարհում հանգույցը միացված է կապի ալիքը ներկայացնող օբյեկտին: Այստեղ կապի ենթացանցի հիմնական աբստրակցիան կոչվում է ալիք և C++-ում ներկայացված է Channel դասով։

Դաս ChannelChannel ապահովում է ենթացանցային օբյեկտների փոխազդեցության կառավարման և դրանց հետ հանգույցները միացնելու մեթոդներ: Ալիքները կարող են նաև մասնագիտացված լինել ծրագրավորողների կողմից՝ օբյեկտի վրա հիմնված ծրագրավորման իմաստով: Ալիքների մասնագիտացումը կարող է մոդելավորել այնպիսի պարզ բան, ինչպիսին է մետաղալարը: Հատուկ ալիքը կարող է նաև մոդելավորել բարդ բաներ, ինչպիսիք են Ethernet-ի մեծ անջատիչը կամ անլար ցանցերի դեպքում խոչընդոտներով լի եռաչափ տարածությունը:

Մենք կօգտագործենք ալիքի մասնագիտացված տարբերակները այս ձեռնարկում, որը կոչվում է CsmaChannelCsmaChannel, PointToPointChannelPointToPointChannel и WifiChannelWifiChannel. CsmaChannelՕրինակ, մոդելավորում է կապի ենթացանկի տարբերակը, որն իրականացնում է կրիչի զգայարանային բազմակի մուտքի հաղորդակցման միջավայր: Սա մեզ տալիս է Ethernet-ի նման ֆունկցիոնալություն:

4.1.4 Զուտ սարք

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

Ցանցային քարտը չի աշխատի առանց ծրագրաշարի վարորդի, որը վերահսկում է իր սարքաշարը: Unix-ում (կամ Linux-ում) ծայրամասային սարքավորումների մի մասը դասակարգվում է որպես սարք: Սարքերը կառավարվում են սարքի դրայվերների միջոցով, իսկ ցանցային սարքերը (NIC) կառավարվում են ցանցային սարքի դրայվերների միջոցով (ցանցային սարքի վարորդներ) և միասին կոչվում են ցանցային սարքեր (ցանցային սարքեր) Unix-ում և Linux-ում դուք վերաբերում եք ցանցային սարքերին այնպիսի անուններով, ինչպիսիք են eth0.

ns-3-ում ցանցային սարքի աբստրակցիան ընդգրկում է ինչպես վարորդի ծրագրակազմը, այնպես էլ մոդելավորվող սարքաշարը: Մոդելավորման ժամանակ հանգույցում «տեղադրվում է» ցանցային սարք, որը թույլ է տալիս հաղորդակցվել այլ հանգույցների հետ կապուղիների միջոցով: Ճիշտ այնպես, ինչպես իրական համակարգիչը, հանգույցը կարող է միանալ բազմաթիվ ալիքների մի քանի սարքերի միջոցով NetDevices.

Սարքի ցանցային աբստրակցիան C++-ում ներկայացված է դասի կողմից NetDevice. Դասարան NetDevice ապահովում է հանգույցների և ալիքների օբյեկտների հետ կապերը կառավարելու մեթոդներ. և կարող է մասնագիտացված լինել ծրագրավորողների կողմից՝ օբյեկտի վրա հիմնված ծրագրավորման իմաստով: Այս ձեռնարկում մենք կօգտագործենք NetDevice-ի մի քանի մասնագիտացված տարբերակներ, որոնք կոչվում են CsmaNetDevice, PointToPointNetDevice и WifiNet Սարք. Ճիշտ այնպես, ինչպես Ethernet ցանցի ադապտերը նախատեսված է ցանցի հետ աշխատելու համար Ethernet, CsmaNetDevice նախատեսված է աշխատելու համար CsmaChannel, PointToPointNetDevice նախատեսված է աշխատելու համար PointToPointChannelԻսկ WifiNet Սարք - նախատեսված է աշխատելու համար WifiChannel.

4.1.5 Տոպոլոգիական օգնականներ

Իրական ցանցում դուք կգտնեք հյուրընկալող համակարգիչներ՝ ավելացված (կամ ներկառուցված) ցանցային քարտերով: ns-3-ում մենք կասեինք, որ դուք կտեսնեք հանգույցներ՝ կցված NetDevices-ով: Խոշոր սիմուլյացված ցանցում ձեզ անհրաժեշտ կլինի կապեր կազմակերպել բազմաթիվ օբյեկտների միջև Հանգույց, NetDevice и Նեղուց.

NetDevices-ը հանգույցներին միացնելուց, NetDevices-ը հղումներին, IP հասցեներ նշանակելուց և այլն: ns-3-ում սովորական խնդիր է, որպեսզի դա հնարավորինս հեշտ դարձնենք, մենք տրամադրում ենք այսպես կոչված տոպոլոգիայի օգնականներ: Օրինակ, NetDevice ստեղծելու համար անհրաժեշտ է կատարել բազմաթիվ ns-3 միջուկի գործողություններ, ավելացնել MAC հասցե, տեղադրել ցանցային սարքը Node-ում, կարգավորել հանգույցի պրոտոկոլների փաթեթը և այնուհետև միացնել NetDevice-ը Channel-ին: Նույնիսկ ավելի շատ աշխատանք կպահանջվի մի քանի սարքեր միացնելու համար բազմակետ հղումներին, այնուհետև առանձին ցանցերը միացնելու համար Internetworks ցանցին: Մենք տրամադրում ենք տոպոլոգիայի օգնական օբյեկտներ, որոնք համատեղում են այս բազմաթիվ գործողությունները՝ դարձնելով հեշտ օգտագործվող մոդել՝ ձեր հարմարության համար:

4.2 Առաջին ns-3 սցենար

Եթե ​​դուք տեղադրել եք համակարգը, ինչպես առաջարկվել է վերևում, դուք կունենաք ns-3 թողարկումը մի գրացուցակում, որը կոչվում է ռեպո ձեր հիմնական գրացուցակում: Գնացեք գրացուցակ ազատ արձակել

Եթե ​​դուք չունեք այդպիսի գրացուցակ, նշանակում է, որ դուք չեք նշել ելքային գրացուցակը ns-3-ի թողարկման տարբերակը կառուցելիս, կառուցեք այսպես.
$ ./waf կազմաձևել — build-profile = թողարկում — դուրս = կառուցել / թողարկել,
$ ./waf կառուցել

այնտեղ դուք պետք է տեսնեք գրացուցակի կառուցվածքը, որը նման է հետևյալին.

AUTHORS       examples      scratch       utils       waf.bat*
bindings      LICENSE       src           utils.py    waf-tools
build         ns3           test.py*      utils.pyc   wscript
CHANGES.html  README        testpy-output VERSION     wutils.py
doc           RELEASE_NOTES testpy.supp   waf*        wutils.pyc

Գնացեք գրացուցակ օրինակներ / ձեռնարկ. Դուք պետք է տեսնեք այնտեղ գտնվող ֆայլը, որը կոչվում է առաջին.cc. Սա սկրիպտ է, որը կստեղծի պարզ կետ առ կետ կապ երկու հանգույցների միջև և մեկ փաթեթ կփոխանցի հանգույցների միջև: Եկեք տող առ տող նայենք այս սցենարին, դա անելու համար բացեք first.cc-ն ձեր սիրելի խմբագրիչում:

4.2.1 Կաթսայի ծածկագիր
Ֆայլի առաջին տողը խմբագրի ռեժիմի տողն է emacs. Այն emacs-ին պատմում է ձևաչափման կոնվենցիաների (կոդավորման ոճ) մասին, որոնք մենք օգտագործում ենք մեր սկզբնական կոդում:

/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */

Սա միշտ բավականին վիճելի հարց է, ուստի մենք պետք է շտկենք ռեկորդը, որպեսզի այն անմիջապես վերացնենք ճանապարհից: ns-3 նախագիծը, ինչպես մեծ նախագծերի մեծ մասը, ընդունել է կոդավորման ոճ, որին պետք է համապատասխանի բոլոր ներդրված ծածկագրերը: Եթե ​​ցանկանում եք ձեր կոդը ներդնել նախագծին, ի վերջո ստիպված կլինեք համապատասխանել ns-3 կոդավորման ստանդարտին, ինչպես նկարագրված է ֆայլում: doc/codingstd.txt կամ ցուցադրված է նախագծի վեբ էջում. https://www.nsnam.org/develop/contributing-code/coding-style/.

Խորհուրդ ենք տալիս ընտելանալ ns-3 կոդի տեսքին և տեսքին և կիրառել այս ստանդարտը, երբ աշխատում եք մեր կոդով: Մշակման ողջ թիմը և ներդրողները համաձայնեցին դրան որոշ տրտնջալուց հետո: Emacs ռեժիմի վերևի տողը հեշտացնում է ճիշտ ձևաչափումը, եթե դուք օգտագործում եք emacs խմբագրիչը:

ns-3 սիմուլյատորը լիցենզավորված է, օգտագործելով GNU General Public լիցենզիա. Յուրաքանչյուր ns-3 բաշխման ֆայլում կտեսնեք համապատասխան GNU իրավական վերնագիրը: Հաճախ դուք կտեսնեք հեղինակային իրավունքի ծանուցում ns-3 նախագծի մասնակից հաստատություններից մեկի համար GPL տեքստի և հեղինակի վերևում, որը ցույց է տրված ստորև:

/* 
* This program is free software; you can redistribute it and/or modify 
* it under the terms of the GNU General Public License version 2 as 
* published by the Free Software Foundation; 
*
* This program is distributed in the hope that it will be useful, 
* but WITHOUT ANY WARRANTY; without even the implied warranty of 
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
* GNU General Public License for more details. 
* 
* You should have received a copy of the GNU General Public License 
* along with this program; if not, write to the Free Software 
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
*/

4.2.2 Փլագիններ

Կոդն ինքնին սկսվում է մի շարք ներառման հայտարարություններով (ներառում են).

#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"

Որպեսզի օգնենք մեր բարձր մակարդակի սկրիպտավորման օգտատերերին հաղթահարել համակարգում առկա մեծ թվով վերնագրերի ֆայլերը, մենք դրանք խմբավորում ենք ըստ դրանց օգտագործման մեծ մոդուլների: Մենք տրամադրում ենք մեկ վերնագրի ֆայլ, որը ռեկուրսիվորեն բեռնելու է տվյալ մոդուլում օգտագործվող վերնագրի բոլոր ֆայլերը: Փոխանակ որոնելու, թե կոնկրետ ինչ վերնագիր է ձեզ անհրաժեշտ և, հնարավոր է, ստանաք կախվածությունների ճիշտ ցանկը, մենք ձեզ հնարավորություն ենք տալիս ներբեռնել մի խումբ ֆայլեր մեծ հստակությամբ: Դա ամենաարդյունավետ մոտեցումը չէ, բայց, իհարկե, շատ ավելի հեշտացնում է սցենարներ գրելը:

ns-3 ներառող ֆայլերից յուրաքանչյուրը տեղադրվում է անունով գրացուցակում ns3 (կառուցել ենթատեղեկատու)՝ կառուցման գործընթացում ֆայլի անվանման կոնֆլիկտներից խուսափելու համար: Ֆայլ ns3/core-module.h համապատասխանում է ns-3 մոդուլին, որը դուք կգտնեք գրացուցակում src/core ձեր տեղադրած թողարկման մեջ: Այս գրացուցակի ցուցակում դուք կգտնեք մեծ թվով վերնագրի ֆայլեր: Երբ հավաքում եք, վաֆ տեղադրում է հանրային վերնագրի ֆայլերը ns3 գրացուցակում ենթագրքում կառուցել/վրիպազերծել

Եթե ​​դուք չունեք այդպիսի գրացուցակ, նշանակում է, որ դուք չեք նշել ելքային գրացուցակը ns-3-ի թողարկման տարբերակը կառուցելիս, կառուցեք այսպես.
$ ./waf configure --build-profile=debug --out=build/debug
$ ./waf կառուցել
կամ
$ ./waf configure --build-profile=optimized --out=build/optimized
$ ./waf կառուցել

կամ կառուցել/օպտիմիզացված, կախված ձեր կոնֆիգուրացիայից: վաֆ նաև ավտոմատ կերպով կստեղծի մոդուլ, որը ներառում է ֆայլ՝ բոլոր հանրային վերնագրի ֆայլերը բեռնելու համար: Քանի որ դուք, իհարկե, հետևում եք այս ուղեցույցին կրոնական առումով, դուք արդեն արել եք

$ ./waf -d debug --enable-examples --enable-tests configure

նախագիծը կարգավորելու համար վրիպազերծման կառուցումներ գործարկելու համար, որոնք ներառում են օրինակներ և թեստեր: Դուք նույնպես արեցիք

$ ./waf

նախագիծը հավաքելու համար: Այսպիսով, հիմա, երբ դուք նայեք գրացուցակում ../../build/debug/ns3, ապա այնտեղ կգտնեք, ի թիվս այլոց, վերը նշված չորս մոդուլների վերնագրի ֆայլերը: Դուք կարող եք դիտել այս ֆայլերի բովանդակությունը և գտնել, որ դրանք ներառում են բոլոր հանրային ֆայլերը, որոնք օգտագործվում են համապատասխան մոդուլների կողմից:

4.2.3 ns3 անվանատարածք

Հաջորդ տողը սցենարով առաջին.cc անվանատարածքի հայտարարություն է:

using namespace ns3;

ns-3 նախագիծն իրականացվում է C++ անվանատարածքում, որը կոչվում է ns3: Սա խմբավորում է ns-3-ի հետ կապված բոլոր հայտարարությունները գլոբալ անունների տարածությունից դուրս մի շրջանակի մեջ, որը հուսով ենք կօգնի ինտեգրվել այլ կոդի հետ: Օգտագործելով C++ օպերատորը, ներմուծվում է ns-3 անվանատարածք ընթացիկ (գլոբալ) հռչակագրային տարածաշրջանում: Սա շքեղ ձև է ասելու, որ այս հայտարարությունից հետո դուք կարիք չեք ունենա մուտքագրել ns3::scope թույլտվության օպերատորը ձեր բոլոր ns-3 ծածկագրերից առաջ այն օգտագործելու համար: Եթե ​​ծանոթ չեք անունների տարածքներին, դիմեք գրեթե ցանկացած C++ դասագրքին և համեմատեք ns3 անվանատարածքը՝ օգտագործելով std անվանատարածքը և հռչակագիրը: using namespace std; ելքային օպերատորի հետ աշխատելու օրինակներում արժեք և հոսքեր։

4.2.4 անտառահատումներ

Սցենարի հաջորդ տողը հետևյալն է.

NS_LOG_COMPONENT_DEFINE ("FirstScriptExample");

Մենք կօգտագործենք այս հայտարարությունը որպես հարմար վայր՝ քննարկելու մեր փաստաթղթային համակարգը Doxygen- ը. Եթե ​​նայեք ns-3 նախագծի կայքէջին, նավիգացիոն տողում կգտնեք Փաստաթղթերի հղումը: Եթե ​​սեղմեք այս հղումը, դուք կտեղափոխվեք մեր փաստաթղթերի էջ: Կա «Վերջին թողարկում» հղում, որը ձեզ կտանի դեպի ns-3-ի վերջին կայուն տարբերակի փաստաթղթերը: Եթե ​​ընտրեք «API Documentation» հղումը, դուք կտեղափոխվեք ns-3 API փաստաթղթերի էջ:

Էջի ձախ կողմում դուք կգտնեք փաստաթղթերի կառուցվածքի գրաֆիկական պատկերը: Սկսելու համար լավ տեղ է Modules ns-3 «գիրքը» ns-3 նավիգացիոն ծառում: Եթե ​​բացահայտես մոդուլներ, կտեսնեք ns-3 մոդուլների փաստաթղթերի ցանկը: Ինչպես քննարկվեց վերևում, այստեղ մոդուլի գաղափարը ուղղակիորեն կապված է վերը նշված մոդուլում ներառված ֆայլերի հետ: ns-3 գրանցման ենթահամակարգը քննարկվում է բաժնում Օգտագործելով Logging մոդուլը, այնպես որ մենք կվերադառնանք դրան ավելի ուշ այս ձեռնարկում, բայց դուք կարող եք իմանալ վերը նշված հայտարարության մասին՝ նայելով մոդուլը Coreիսկ հետո բացելով գիրքը Կարգավորման գործիքներայնուհետև ընտրելով էջը Փայտամթերում. Սեղմեք Փայտամթերում.

Այժմ դուք պետք է վերանայեք փաստաթղթերը Doxygen- ը մոդուլի համար Փայտամթերում. Էջի վերևում գտնվող մակրոների ցանկում կտեսնեք NS_LOG_COMPONENT_DEFINE մուտքը: Հղումը սեղմելուց առաջ համոզվեք, որ նայեք գրանցման մոդուլի «Մանրամասն նկարագրությունը»՝ հասկանալու համար, թե ինչպես է այն աշխատում ընդհանուր առմամբ: Դա անելու համար դուք կարող եք ոլորել ներքև կամ ընտրել «Ավելին...» գծապատկերի տակ:

Երբ ընդհանուր պատկերացում ունենաք, թե ինչ է կատարվում, շարունակեք և դիտեք փաստաթղթերը կոնկրետ NS_LOG_COMPONENT_DEFINE-ի համար: Ես այստեղ փաստաթղթերը չեմ կրկնօրինակի, բայց ամփոփելու համար այս տողում հայտարարվում է գրանցման բաղադրիչ, որը կոչվում է FirstScriptExample, որը թույլ է տալիս միացնել կամ անջատել հաղորդագրությունների վահանակի գրանցումը` հղում կատարելով անվանմանը:

4.2.5 Հիմնական գործառույթը

Սցենարի հետևյալ տողերում կտեսնեք.

int 
main (int argc, char *argv[])
{ 

Սա պարզապես ձեր ծրագրի (սկրիպտի) հիմնական գործառույթի հռչակագիրն է: Ինչպես ցանկացած C++ ծրագրի դեպքում, դուք պետք է սահմանեք հիմնական գործառույթը, այն առաջինը կատարվում է: Այստեղ առանձնահատուկ բան չկա: Ձեր ns-3 սկրիպտը պարզապես C++ ծրագիր է: Հետևյալ տողը սահմանում է ժամանակի լուծաչափը 1 նանվայրկյան, որը լռելյայն է.

Time::SetResolution (Time::NS);

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

Ստորև բերված սցենարի երկու տողերը օգտագործվում են երկու գրանցման բաղադրիչ միացնելու համար, որոնք ներկառուցված են հավելվածներում EchoClient и EchoServer:

LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO); LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO);

Եթե ​​կարդաք Logging բաղադրիչի փաստաթղթերը, կտեսնեք, որ կան գրանցման/հատկավորության մի քանի մակարդակ, որոնք կարող եք միացնել յուրաքանչյուր բաղադրիչի վրա: Կոդի այս երկու տողերը հնարավորություն են տալիս վրիպազերծման գրանցումը INFO մակարդակի էխո հաճախորդների և սերվերների համար: Այս մակարդակում հավելվածը սիմուլյացիայի ընթացքում փաթեթներ ուղարկելու և ստանալու ընթացքում հաղորդագրություններ է տպելու:

Այժմ մենք կանցնենք տոպոլոգիայի ստեղծման և սիմուլյացիայի գործարկմանը: Մենք օգտագործում ենք տոպոլոգիայի օգնական օբյեկտներ՝ այս աշխատանքը հնարավորինս հեշտացնելու համար:

4.2.6 Տոպոլոգիայի օգնականների օգտագործումը

Կոդի հաջորդ երկու տողերը մեր սկրիպտում իրականում կստեղծեն Node ns-3 օբյեկտները, որոնք կներկայացնեն համակարգիչները մոդելավորման մեջ:

NodeContainer nodes;
nodes.Create (2);

Նախքան շարունակելը, եկեք գտնենք դասի փաստաթղթերը NodeContainer. Տվյալ դասի փաստաթղթերին հասնելու մեկ այլ միջոց է ներդիրը Դասեր էջերի վրա Doxygen- ը. Եթե ​​դուք արդեն բացել եք Doxygen-ը, պարզապես ոլորեք էջի վերևում և ընտրեք Դասեր ներդիրը: Դուք պետք է տեսնեք ներդիրների նոր հավաքածու, որոնցից մեկը դասերի ցանկն է: Այս ներդիրի տակ կտեսնեք բոլոր ns-3 դասերի ցանկը: Ոլորեք ներքև դեպի ns3::NodeContainer. Երբ դաս եք գտնում, ընտրեք այն՝ դասի փաստաթղթերին անցնելու համար:

Ինչպես հիշում ենք, մեր հիմնական աբստրակցիաներից մեկը հանգույցն է: Այն ներկայացնում է համակարգիչը, որին մենք պատրաստվում ենք ավելացնել այնպիսի բաներ, ինչպիսիք են արձանագրությունների կույտերը, հավելվածները և ծայրամասային քարտերը: Տոպոլոգիայի օգնական NodeContainer ապահովում է ցանկացած օբյեկտ ստեղծելու, կառավարելու և մուտք գործելու հարմար միջոց Հանգույց, որը մենք ստեղծում ենք սիմուլյացիան գործարկելու համար: Վերևի առաջին տողը պարզապես հայտարարում է NodeContainer, որը մենք անվանում ենք հանգույցներ։ Երկրորդ տողը կանչում է Ստեղծել մեթոդը հանգույցների օբյեկտի վրա և խնդրում է կոնտեյներին ստեղծել երկու հանգույց: Ինչպես նկարագրված է Doxygen- ը, կոնտեյները խնդրում է ns-3 համակարգին՝ ստեղծել երկու օբյեկտ Հանգույց և ներսից պահում է այս օբյեկտների ցուցիչները:

Սցենարում ստեղծված հանգույցները դեռ ոչինչ չեն անում։ Տոպոլոգիայի կառուցման հաջորդ քայլը մեր հանգույցները ցանցին միացնելն է: Ցանցի ամենապարզ ձևը, որը մենք աջակցում ենք, կետ առ կետ կապն է երկու հանգույցների միջև: Այժմ մենք կստեղծենք նման կապ:

PointToPointHelper

Մենք ստեղծում ենք կետ-կետ կապ՝ օգտագործելով ծանոթ օրինաչափություն՝ օգտագործելով տոպոլոգիայի օգնական օբյեկտ՝ միացման համար անհրաժեշտ ցածր մակարդակի աշխատանքը կատարելու համար: Հիշեցնենք, որ մեր երկու հիմնական աբստրակցիաները NetDevice и Նեղուց. Իրական աշխարհում այս տերմինները մոտավորապես համապատասխանում են ծայրամասային քարտերին և ցանցային մալուխներին: Սովորաբար, այս երկու բաները սերտորեն կապված են միմյանց հետ, և ոչ ոք չի կարող հույս դնել, օրինակ, սարքերի փոխանակման վրա: Ethernet անլար ալիքով: Մեր տոպոլոգիայի օգնականները հետևում են այս սերտ հարաբերություններին և, հետևաբար, դուք կօգտագործեք մեկ օբյեկտ այս սցենարում PointToPointHelper ns-3 օբյեկտների տեղադրման և միացման համար PointToPointNetDevice и PointToPointChannel. Սցենարում հաջորդ երեք տողերը.

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

Առաջին տող,

PointToPointHelper pointToPoint;

ստեղծում է կույտի վրա գտնվող օբյեկտի օրինակ PointToPointHelper. Բարձր մակարդակի տեսանկյունից հետևյալ տողը.

pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));

պատմում է օբյեկտին PointToPointHelper օգտագործել «5 Մբիթ/վրկ» արժեքը (հինգ մեգաբիթ/վրկ) որպես «Տվյալների տոկոսադրույքը.

Ավելի կոնկրետ տեսանկյունից «DataRate» տողը համապատասխանում է նրան, ինչ մենք անվանում ենք հատկանիշ PointToPointNetDevice. Եթե ​​նայեք Doxygen- ը դասի համար ns3::PointToPointNetDevice և մեթոդի փաստաթղթերում GetTypeId դուք կգտնեք սարքի համար սահմանված ատրիբուտների ցանկը: Դրանց թվում կլինի հատկանիշը «Տվյալների տոկոսադրույքը« Օգտատիրոջ տեսանելի ns-3 օբյեկտների մեծամասնությունն ունեն ատրիբուտների նմանատիպ ցուցակներ: Մենք օգտագործում ենք այս մեխանիզմը, որպեսզի հեշտությամբ կարգավորենք սիմուլյացիան առանց վերակազմավորման, ինչպես կտեսնեք հաջորդ բաժնում:

Նման "Տվյալների տոկոսադրույքըPointToPointNetDevice-ում դուք կգտնեք «Delay» հատկանիշը՝ կապված PointToPointChannel-ի հետ: Վերջնական գիծ

pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));

Ասում են PointToPointHelper օգտագործեք «2 ms» արժեքը (երկու միլիվայրկյան) որպես տարածման հետաձգման արժեք այն կետ-կետ կապի համար, որը հետագայում ստեղծում է:

NetDeviceContainer

Այս պահին սցենարում ունենք NodeContainer, որը պարունակում է երկու հանգույց։ Մենք ունենք PointToPointHelper, որը պատրաստված է օբյեկտներ ստեղծելու համար PointToPointNetDevices և դրանք միացնելով PointToPointChannel օբյեկտի միջոցով: Ինչպես մենք օգտագործեցինք NodeContainer տոպոլոգիայի օգնական օբյեկտը հանգույցներ ստեղծելու համար, մենք կհարցնենք PointToPointHelper կատարել աշխատանք մեզ համար՝ կապված մեր սարքերի ստեղծման, կազմաձևման և տեղադրման հետ: Մեզ անհրաժեշտ է բոլոր ստեղծված օբյեկտների ցանկը NetDevice, ուստի մենք օգտագործում ենք NetDeviceContainer դրանք պահել այնպես, ինչպես մենք օգտագործել ենք NodeContainer մեր ստեղծած հանգույցները պահելու համար: Կոդի հաջորդ երկու տողերը,

NetDeviceContainer devices;
devices = pointToPoint.Install (nodes);

սարքի և ալիքի ամբողջական կարգավորում: Առաջին տողում նշվում է վերը նշված սարքի կոնտեյները, իսկ երկրորդը կատարում է հիմնական աշխատանքը: Մեթոդ Տեղադրեք առարկա PointToPointHelper ընդունում է NodeContainer որպես պարամետր: Ներսում NetDeviceContainer յուրաքանչյուր հանգույցի համար, որը գտնվում է NodeContainer ստեղծվել է (կետ առ կետ հաղորդակցության համար պետք է լինեն դրանցից ուղիղ երկուսը) PointToPointNetDevice ստեղծվում և պահվում է սարքի կոնտեյներով: PointToPointChannel ստեղծվում է և դրան կցվում են երկու PointToPointNetDevices. Օբյեկտներ ստեղծելուց հետո ատրիբուտները պահվում են PointToPointHelper, օգտագործվում են ստեղծված օբյեկտներում համապատասխան ատրիբուտները սկզբնավորելու համար։

Զանգելուց հետո pointToPoint.Install (հանգույցներ) մենք կունենանք երկու հանգույց, որոնցից յուրաքանչյուրում տեղադրված է կետ առ կետ ցանցային սարք և նրանց միջև մեկ կետ առ կետ կապ: Երկու սարքերն էլ կկարգավորվեն այնպես, որ տվյալներ փոխանցեն հինգ մեգաբիթ/վրկ արագությամբ՝ երկու միլիվայրկյան ուշացումով ալիքով:

InternetStackHelper

Այժմ մենք ունենք կազմաձևված հանգույցներ և սարքեր, բայց մեր հանգույցներում տեղադրված չեն արձանագրությունների կույտեր: Կոդի հաջորդ երկու տողերը հոգ կտանեն այս մասին:

InternetStackHelper stack;
stack.Install (nodes);

InternetStackHelper - տոպոլոգիայի օգնական է ինտերնետի կույտերի համար, որը նման է PointToPointHelper-ին կետ առ կետ ցանցային սարքերի համար: Մեթոդ Տեղադրեք որպես պարամետր ընդունում է NodeContainer-ը: Կատարվելուց հետո այն կտեղադրի ինտերնետի փաթեթը (TCP, UDP, IP և այլն) յուրաքանչյուր կոնտեյների հանգույցի վրա:

IPv4AddressHelper

Այնուհետև մենք պետք է մեր սարքերը կապենք IP հասցեների հետ: Մենք տրամադրում ենք տոպոլոգիայի օգնական՝ IP հասցեների տեղաբաշխումը կառավարելու համար: Միակ API-ն, որը տեսանելի է օգտատիրոջը, սահմանում է բազային IP հասցեն և ցանցի դիմակը, որոնք պետք է օգտագործվեն հասցեների իրական բաշխումն իրականացնելիս (սա արվում է օգնականի ավելի ցածր մակարդակում): Կոդի հաջորդ երկու տողերը մեր օրինակի սցենարում առաջին.cc,

Ipv4AddressHelper address;
address.SetBase ("10.1.1.0", "255.255.255.0");

հայտարարեք հասցեի օգնական օբյեկտը և ասեք, որ այն պետք է սկսի IP հասցեներ հատկացնել 10.1.1.0 ցանցից՝ որոշելու համար օգտագործելով 255.255.255.0 բիթդիմակը: Լռելյայնորեն, հատկացված հասցեները կսկսվեն մեկից և կմեծանան միապաղաղ, ուստի այս բազայից հատկացված առաջին հասցեն կլինի 10.1.1.1, այնուհետև 10.1.1.2 և այլն: Իրականում, ցածր մակարդակով, ns-3 համակարգը հիշում է բոլոր հատկացված IP հասցեները և առաջացնում է ճակատագրական սխալ, եթե պատահաբար ստեղծեք մի իրավիճակ, երբ նույն հասցեն ստեղծվում է երկու անգամ (ի դեպ, այս սխալը դժվար է կարգաբերել):

Կոդի հետևյալ տողը,

Ipv4InterfaceContainer interfaces = address.Assign (devices);

կատարում է իրական հասցեի նշանակումը. ns-3-ում մենք կապ ենք հաստատում IP հասցեի և օբյեկտի օգտագործմամբ սարքի միջև IPv4 ինտերֆեյս. Ինչպես մեզ երբեմն անհրաժեշտ է օգնականի կողմից ստեղծված ցանցային սարքերի ցանկը հետագա օգտագործման համար, մեզ երբեմն անհրաժեշտ է օբյեկտների ցուցակ IPv4 ինտերֆեյս. IPv4InterfaceContainer ապահովում է այս գործառույթը:

Մենք կառուցեցինք կետ առ կետ ցանց՝ տեղադրված կույտերով և նշանակված IP հասցեներով: Այժմ յուրաքանչյուր հանգույցում մեզ անհրաժեշտ են հավելվածներ՝ տրաֆիկ ստեղծելու համար:

4.2.7 Օգտագործելով հավելվածը

ns-3 համակարգի մեկ այլ հիմնական աբստրակցիան է դիմում (դիմում): Այս սցենարում մենք օգտագործում ենք երկու հիմնական դասի մասնագիտացում դիմում ns-3 կանչեց UdpEchoServerApplication и UdpEchoClientApplication. Ինչպես նախորդ դեպքերում, մենք օգտագործում ենք օժանդակ օբյեկտներ բազային օբյեկտները կարգավորելու և կառավարելու համար: Այստեղ մենք օգտագործում ենք UdpEchoServerHelper и UdpEchoClientHelper առարկաներ մեր կյանքը հեշտացնելու համար:

UdpEchoServerHelper

Կոդի հետևյալ տողերը մեր first.cc օրինակի սկրիպտում օգտագործվում են UDP echo սերվերի հավելվածը կարգավորելու համար մեր նախկին ստեղծած հանգույցներից մեկի վրա:

UdpEchoServerHelper echoServer (9);

ApplicationContainer serverApps = echoServer.Install (nodes.Get (1));
serverApps.Start (Seconds (1.0));
serverApps.Stop (Seconds (10.0));

Ստեղծվում է վերը նշված հատվածի կոդի առաջին տողը UdpEchoServerHelper. Ինչպես միշտ, սա ինքնին հավելված չէ, այն օբյեկտ է, որն օգնում է մեզ ստեղծել իրական հավելվածներ: Մեր կոնվենցիաներից մեկն այն է, որ անհրաժեշտ հատկանիշները փոխանցենք օգնական օբյեկտի կառուցողին: Այս դեպքում օգնականը չի կարող որևէ օգտակար բան անել, քանի դեռ նրան չի տրվել պորտի համարը, որի վրա սերվերը կլսի փաթեթներ, այս թիվը նույնպես պետք է հայտնի լինի հաճախորդին: Այս դեպքում մենք պորտի համարը փոխանցում ենք օգնական կոնստրուկտորին։ Կոնստրուկտորն իր հերթին պարզապես անում է SetAttribute անցած արժեքով։ Հետագայում, ցանկության դեպքում, կարող եք օգտագործել SetAttribute՝ Port հատկանիշի համար այլ արժեք սահմանելու համար:

Ինչպես շատ այլ օժանդակ օբյեկտներ, օբյեկտը UdpEchoServerHelper մեթոդ ունի Տեղադրեք. Այս մեթոդի իրականացումը արդյունավետ կերպով ստեղծում է հիմնական echo սերվերի հավելված և կապում այն ​​հոսթին: Հետաքրքիր է, որ մեթոդը Տեղադրեք ընդունում է NodeContainer որպես պարամետր, ինչպես մյուսները Տեղադրեք մեթոդներ, որոնք մենք տեսել ենք.

Այստեղ աշխատող C++ անուղղակի փոխակերպումը վերցնում է մեթոդի արդյունքը հանգույց. Ստանալ (1) (որը վերադարձնում է խելացի ցուցիչը հանգույցի օբյեկտին - Ptr ) և այն օգտագործում է կոնստրուկտորում անանուն օբյեկտի համար NodeContainerորն այնուհետև փոխանցվում է մեթոդին Տեղադրեք. Եթե ​​դուք չեք կարող որոշել C++ կոդում, թե որ մեթոդի ստորագրությունն է կազմվում և կատարվում, ապա նայեք անուղղակի փոխակերպումների շարքին:

Հիմա մենք դա տեսնում ենք echoServer.Install պատրաստվում է հավելվածը տեղադրել UdpEchoServerApplication -ում հայտնաբերվել է NodeContainerորը մենք օգտագործում ենք կառավարելու մեր հանգույցները, հանգույց ինդեքսով 1. Մեթոդ Տեղադրեք կվերադարձնի կոնտեյներ, որը պարունակում է ցուցիչներ բոլոր հավելվածներին (այս դեպքում՝ մեկը, քանի որ մենք անցել ենք անանուն NodeContainer, որը պարունակում է մեկ հանգույց) ստեղծված օգնականի կողմից։

Հավելվածները պետք է նշեն, թե երբ սկսել թրաֆիկի ստեղծումը «սկսել» և կարող է անհրաժեշտ լինել լրացուցիչ նշել այն ժամանակը, երբ դադարեցնել այն «դադար». Մենք տրամադրում ենք երկու տարբերակ. Այս ժամանակները սահմանվում են մեթոդների կիրառմամբ ApplicationContainer սկիզբ и Դադարեցնել. Այս մեթոդները ընդունում են տիպի պարամետրեր ժամանակ. Այս դեպքում մենք օգտագործում ենք C++ փոխակերպումների հստակ հաջորդականություն՝ C++ վերցնելու համար կրկնապատկել 1.0 և փոխակերպեք այն tns-3 Time օբյեկտի, որն օգտագործում է Seconds օբյեկտը վայրկյանների փոխարկելու համար: Հիշեք, որ փոխակերպման կանոնները կարող է կառավարվել մոդելի հեղինակի կողմից, և C++-ն ունի իր կանոնները, այնպես որ դուք միշտ չէ, որ կարող եք հույս դնել, որ պարամետրերը փոխարկվեն այնպես, ինչպես դուք ակնկալում էիք: Երկու տող

serverApps.Start (Seconds (1.0));
serverApps.Stop (Seconds (10.0));

կստիպի echo սերվերի հավելվածը սկսել (մեխանիկորեն միացնել) սիմուլյացիայի մեկնարկից մեկ վայրկյան հետո և դադարեցնել (անջատել) սիմուլյացիայից տասը վայրկյան հետո: Հաշվի առնելով այն հանգամանքը, որ մենք հայտարարագրել ենք սիմուլյացիոն իրադարձություն (հավելվածի դադարեցման իրադարձություն), որը կիրականացվի տասը վայրկյանում, ցանցի շահագործման առնվազն տասը վայրկյան մոդելավորվելու է:

UdpEchoClientHelper

Հաճախորդի դիմում կարոտել կազմաձևված է սերվերին գրեթե նման ձևով: Կա բազային օբյեկտ UdpEchoClientApplicationվերահսկվում է
UdpEchoClientHelper.

UdpEchoClientHelper echoClient (interfaces.GetAddress (1), 9);
echoClient.SetAttribute ("MaxPackets", UintegerValue (1));
echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.0)));
echoClient.SetAttribute ("PacketSize", UintegerValue (1024));

ApplicationContainer clientApps = echoClient.Install (nodes.Get (0));
clientApps.Start (Seconds (2.0));
clientApps.Stop (Seconds (10.0));;

Այնուամենայնիվ, echo հաճախորդի համար մենք պետք է սահմանենք հինգ տարբեր ատրիբուտներ: Առաջին երկու հատկանիշները սահմանվում են ստեղծման ժամանակ UdpEchoClientHelper. Մենք փոխանցում ենք պարամետրեր, որոնք օգտագործվում են (օգնականի ներսում) ատրիբուտները սահմանելու համար «Հեռահասցե» и «RemotePort» համաձայն մեր համաձայնության՝ փոխանցել անհրաժեշտ պարամետրերը օգնական կոնստրուկտորին:

Հիշենք, որ օգտագործել ենք IPv4InterfaceContainer հետևելու IP հասցեներին, որոնք մենք հատկացրել ենք մեր սարքերին: Ինտերֆեյսների կոնտեյների մեջ null ինտերֆեյսը կհամապատասխանի հանգույցների կոնտեյների զրոյական հանգույցի IP հասցեին: Ինտերֆեյսերի կոնտեյների առաջին ինտերֆեյսը համապատասխանում է հանգույցների կոնտեյների առաջին հանգույցի IP հասցեին: Այսպիսով, կոդի առաջին տողում (վերևում) մենք ստեղծում ենք օգնական և ասում, որ հաճախորդի հեռավոր հասցեն կլինի այն IP հասցեն, որը նշանակված է հոսթին, որտեղ գտնվում է սերվերը: Մենք նաև ասում ենք, որ մենք պետք է պայմանավորվենք, որպեսզի փաթեթները ուղարկվեն իններորդ նավահանգիստ:

«MaxPackets» հատկանիշը հաճախորդին ասում է փաթեթների առավելագույն քանակը, որը մենք կարող ենք ուղարկել սիմուլյացիայի ընթացքում: «Interval» հատկանիշը հաճախորդին ասում է, թե որքան ժամանակ պետք է սպասել փաթեթների միջև, իսկ «PacketSize» հատկանիշը հաճախորդին ասում է, թե որքան մեծ պետք է լինի փաթեթի օգտակար բեռը: Այս հատկանիշի համակցությամբ մենք հաճախորդին ասում ենք ուղարկել մեկ 1024 բայթանոց փաթեթ:

Ինչպես echo սերվերի դեպքում, մենք սահմանել ենք echo հաճախորդի ատրիբուտները սկիզբ и Դադարեցնել, բայց այստեղ մենք գործարկում ենք հաճախորդը սերվերի միացումից վայրկյան անց (սիմուլյացիայի մեկնարկից երկու վայրկյան հետո)։

4.2.8 Սիմուլյատոր

Այս պահին մենք պետք է գործարկենք սիմուլյացիան: Սա արվում է գլոբալ ֆունկցիայի միջոցով Սիմուլյատոր:: Run.

Simulator::Run ();

Երբ մենք նախկինում անվանում էինք մեթոդներ,

serverApps.Start (Seconds (1.0));
serverApps.Stop (Seconds (10.0));
... 
clientApps.Start (Seconds (2.0));
clientApps.Stop (Seconds (10.0));

մենք իրականում պլանավորել ենք իրադարձություններ սիմուլյատորում 1,0 վայրկյան, 2,0 վայրկյան և երկու իրադարձություն 10,0 վայրկյանում: Զանգից հետո Սիմուլյատոր:: Run, համակարգը կսկսի դիտել պլանավորված իրադարձությունների ցանկը և իրականացնել դրանք: Այն նախ կգործարկի իրադարձություն 1,0 վայրկյանից հետո, որը կգործարկի echo սերվերի հավելվածը (այս իրադարձությունն իր հերթին կարող է պլանավորել բազմաթիվ այլ իրադարձություններ): Այնուհետև այն կգործարկի t=2,0 վայրկյանում նախատեսված իրադարձություն, որը կգործարկի echo հաճախորդի հավելվածը: Կրկին, այս միջոցառումը կարող է ունենալ ավելի շատ միջոցառումներ: Մեկնարկային իրադարձության իրականացումը echo հաճախորդում կսկսի սիմուլյացիայի տվյալների փոխանցման փուլը՝ փաթեթ ուղարկելով սերվերին:

Փաթեթը սերվեր ուղարկելու ակտը կսկսի իրադարձությունների մի շղթա, որոնք ավտոմատ կերպով պլանավորվելու են կուլիսների հետևում և որոնք կիրականացնեն էխո փաթեթ ուղարկելու մեխանիզմը՝ ըստ ժամանակի պարամետրերի, որոնք մենք սահմանել ենք սցենարում:

Արդյունքում, քանի որ մենք ուղարկում ենք միայն մեկ փաթեթ (հիշեք, հատկանիշը MaxPackets սահմանվեց մեկ), այս մեկ հաճախորդի պինգով նախաձեռնված իրադարձությունների շղթան կավարտվի, և սիմուլյացիան կմտնի սպասման ռեժիմ: Երբ դա տեղի ունենա, մնացած ծրագրված իրադարձությունները կլինեն իրադարձությունները Դադարեցնել սերվերի և հաճախորդի համար: Երբ այս իրադարձությունները կատարվեն, հետագա մշակման համար իրադարձություններ չեն մնա և Սիմուլյատոր:: Run կվերադարձնի վերահսկողությունը: Սիմուլյացիան ավարտված է:

Մնում է միայն մաքրել ձեր հետևից: Դա արվում է գլոբալ ֆունկցիան կանչելու միջոցով Սիմուլյատոր::Destroy. Քանի որ կանչվել են օգնական ֆունկցիաները (կամ ցածր մակարդակի ns-3 կոդը), որոնք կազմակերպված են այնպես, որ սիմուլյատորի մեջ կեռիկներ են տեղադրվել՝ ոչնչացնելու բոլոր ստեղծված օբյեկտները։ Այս օբյեկտներից որևէ մեկին ինքներդ հետևելու կարիք չկար, ընդամենը պետք էր զանգահարել Սիմուլյատոր::Destroy և դուրս գալ: ns-3 համակարգը կկատարի այս ծանր աշխատանքը ձեզ համար: Մեր առաջին ns-3 սցենարի մնացած տողերը՝ first.cc, անում են հենց դա.

Simulator::Destroy ();
return 0;
}

Ե՞րբ կդադարի սիմուլյատորը:

ns-3-ը դիսկրետ իրադարձության (DE) սիմուլյատոր է: Նման սիմուլյատորում յուրաքանչյուր իրադարձություն կապված է իր կատարման ժամանակի հետ, և սիմուլյացիան շարունակվում է՝ մշակելով իրադարձությունները այն հաջորդականությամբ, որ դրանք տեղի են ունենում, քանի որ սիմուլյացիան զարգանում է: Իրադարձությունները կարող են հանգեցնել ապագա իրադարձությունների պլանավորմանը (օրինակ, ժամանակաչափը կարող է վերադասավորվել, որպեսզի ավարտի հաշվումը հաջորդ ընդմիջումով):

Սկզբնական իրադարձությունները սովորաբար նախաձեռնվում են կազմակերպության կողմից, օրինակ՝ IPv6-ը պլանավորում է ցանցում ծառայությունների հայտնաբերումը, հարևանների հարցումները և այլն: Հավելվածը պլանավորում է փաթեթների ուղարկման առաջին իրադարձությունը և այլն: Երբ իրադարձությունը մշակվում է, այն կարող է առաջացնել զրո, մեկ կամ ավելի իրադարձություններ: Քանի որ սիմուլյացիան զարգանում է, իրադարձությունները տեղի են ունենում, որոնք կամ ավարտվում են, կամ ստեղծում են նորերը: Սիմուլյացիան ինքնաբերաբար կդադարի, եթե իրադարձության հերթը դատարկ լինի կամ հայտնաբերվի հատուկ իրադարձություն Դադարեցնել. Իրադարձություն Դադարեցնել գեներացվել է ֆունկցիայի կողմից Սիմուլյատոր::Stop (դադարեցնելու ժամանակը):

Տիպիկ դեպք կա, երբ Simulator::Stop-ը բացարձակապես անհրաժեշտ է սիմուլյացիան դադարեցնելու համար. երբ լինում են ինքնապահպանվող իրադարձություններ: Ինքնապահովվող (կամ կրկնվող) իրադարձությունները այն իրադարձություններն են, որոնք միշտ վերածրագրվում են: Որպես հետևանք՝ նրանք միշտ դատարկ չեն պահում իրադարձության հերթը։ Կան բազմաթիվ արձանագրություններ և մոդուլներ, որոնք պարունակում են կրկնվող իրադարձություններ, օրինակ.

• FlowMonitor - կորած փաթեթների պարբերական ստուգում;

• RIPng – երթուղային աղյուսակի թարմացումների պարբերական հեռարձակում;

• և այլն:

Նման դեպքերում Սիմուլյատոր::Stop անհրաժեշտ է սիմուլյացիան ճիշտ դադարեցնելու համար: Բացի այդ, երբ ns-3-ը էմուլյացիայի ռեժիմում է, RealtimeSimulator-ն օգտագործվում է մոդելավորման ժամացույցը մեքենայի ժամացույցի հետ համաժամեցնելու համար, և Սիմուլյատոր::Stop գործընթացը դադարեցնելու համար անհրաժեշտ է.

Դասագրքի սիմուլյացիոն ծրագրերից շատերը չեն զանգահարում Սիմուլյատոր::Stop հստակորեն, քանի որ դրանք ինքնաբերաբար ավարտվում են, երբ հերթագրված իրադարձությունները սպառվում են: Այնուամենայնիվ, այս ծրագրերը կընդունեն նաև Simulator::Stop զանգը: Օրինակ, հետևյալ լրացուցիչ հայտարարությունը առաջին օրինակի ծրագրում կնշանակի բացահայտ կանգառ 11 վայրկյանում.

+ Simulator::Stop (Seconds (11.0));
  Simulator::Run ();
  Simulator::Destroy ();
  return 0;
}

Վերոնշյալը իրականում չի փոխի այս ծրագրի վարքագիծը, քանի որ այս կոնկրետ սիմուլյացիան բնականաբար ավարտվում է 10 վայրկյան հետո: Բայց եթե դուք փոխեիք վերը նշված հայտարարության կանգառի ժամանակը 11 վայրկյանից մինչև 1 վայրկյան, ապա կնկատեք, որ սիմուլյացիան դադարում է մինչև որևէ ելք հայտնվի էկրանին (քանի որ ելքը տեղի է ունենում մոդելավորման ժամանակից մոտ 2 վայրկյան հետո):

Կարևոր է զանգահարել Simulator::Stop նախքան Simulator::Run; Հակառակ դեպքում Simulator::Run-ը կարող է երբեք չվերադարձնի կառավարումը հիմնական ծրագրին, որպեսզի կատարի կանգառը:

4.2.9 Կառուցեք ձեր սցենարը

Մենք աննշան ենք դարձրել ձեր պարզ սցենարների ստեղծումը: Պարզապես պետք է ձեր սկրիպտը տեղադրել scratch գրացուցակում և այն ավտոմատ կերպով կկառուցվի, եթե գործարկեք վաֆ. Արի փորձենք. Վերադարձեք վերին մակարդակի գրացուցակ և պատճենեք օրինակներ/ուսուցողական/first.cc կատալոգին կորելը

$ cd ../.. 
$ cp examples/tutorial/first.cc scratch/myfirst.cc

Այժմ կառուցեք ձեր առաջին օրինակելի սցենարը՝ օգտագործելով վաֆ:

$ ./waf

Դուք պետք է տեսնեք հաղորդագրություններ, որոնք ցույց են տալիս, որ ձեր առաջին օրինակը հաջողությամբ ստեղծվել է:

Waf: Entering directory `/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: Leaving directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' finished successfully (2.357s)

Այժմ կարող եք գործարկել օրինակը (նկատի ունեցեք, որ եթե ձեր ծրագիրը կառուցում եք scratch գրացուցակում, ապա այն պետք է գործարկեք կորելը):

$ ./waf --run scratch/myfirst

Դուք պետք է տեսնեք նմանատիպ արդյունք.

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) Sent 1024 bytes to 10.1.1.2
Received 1024 bytes from 10.1.1.1
Received 1024 bytes from 10.1.1.2

Այստեղ դուք կարող եք տեսնել, որ build համակարգը ստուգում է, որ ֆայլը ստեղծվել է, այնուհետև գործարկում է այն: Դուք տեսնում եք, որ բաղադրիչի մուտքագրումը echo հաճախորդի վրա ցույց է տալիս, որ այն ուղարկել է մեկ 1024 բայթանոց փաթեթ echo սերվեր 10.1.1.2: Դուք նույնպես տեսնում եք գրանցման բաղադրիչը echo սերվերում, որպեսզի ասեք, որ այն ստացել է 1024 բայթ 10.1.1.1-ից: Echo սերվերը լուռ կրկնում է փաթեթը, և դուք կարող եք տեսնել echo հաճախորդի գրանցամատյանում, որ այն ետ է ստացել իր փաթեթը սերվերից:

4.3 ns-3 Աղբյուրի կոդը

Այժմ, երբ դուք օգտագործել եք ns-3 օգնականներից մի քանիսը, կարող եք դիտել այս գործառույթն իրականացնող որոշ ելակետային կոդը: Վերջին կոդը կարելի է դիտել մեր վեբ սերվերում հետևյալ հղումով. https://gitlab.com/nsnam/ns-3-dev.git. Այնտեղ կտեսնեք Mercurial ամփոփ էջը մեր ns-3 զարգացման ծառի համար: Էջի վերևում կտեսնեք մի քանի հղումներ,

summary | shortlog | changelog | graph | tags | files

Շարունակեք և ընտրեք ֆայլերի հղումը: Ահա թե ինչպիսին կլինի մեր պահեստների մեծ մասի վերին մակարդակը.

drwxr-xr-x                               [up]
drwxr-xr-x                               bindings python  files
drwxr-xr-x                               doc              files
drwxr-xr-x                               examples         files
drwxr-xr-x                               ns3              files
drwxr-xr-x                               scratch          files
drwxr-xr-x                               src              files
drwxr-xr-x                               utils            files
-rw-r--r-- 2009-07-01 12:47 +0200 560    .hgignore        file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 1886   .hgtags          file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 1276   AUTHORS          file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 30961  CHANGES.html     file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 17987  LICENSE          file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 3742   README           file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 16171  RELEASE_NOTES    file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 6      VERSION          file | revisions | annotate
-rwxr-xr-x 2009-07-01 12:47 +0200 88110  waf              file | revisions | annotate
-rwxr-xr-x 2009-07-01 12:47 +0200 28     waf.bat          file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 35395  wscript          file | revisions | annotate
-rw-r--r-- 2009-07-01 12:47 +0200 7673   wutils.py        file | revisions | annotate

Մեր օրինակի սցենարները գրացուցակում են օրինակներ. Եթե ​​սեղմեք օրինակների վրա, կտեսնեք ենթագրքերների ցանկը: Ենթագրքում գտնվող ֆայլերից մեկը ձեռնարկ - first.cc. Եթե ​​սեղմեք առաջին.cc դուք կտեսնեք ձեր նոր սովորած կոդը:

Աղբյուրի կոդը հիմնականում գտնվում է գրացուցակում src. Դուք կարող եք դիտել աղբյուրի կոդը՝ սեղմելով գրացուցակի անվանման վրա կամ սեղմելով ֆայլերի հղումը գրացուցակի անվան աջ կողմում: Եթե ​​սեղմեք src գրացուցակը, դուք կստանաք src ենթատեղեկատուների ցանկ: Եթե ​​այնուհետև սեղմեք հիմնական ենթատեղեկատուի վրա, դուք կգտնեք ֆայլերի ցանկ: Առաջին ֆայլը, որը դուք կտեսնեք (այս ուղեցույցը գրելու պահին) սա է ընդհատել.հ. Եթե ​​սեղմեք հղման վրա ընդհատել.հ, դուք կուղարկվեք սկզբնաղբյուր ֆայլի համար ընդհատել.հ, որը պարունակում է օգտակար մակրոներ՝ սկրիպտներից դուրս գալու համար, եթե հայտնաբերվեն աննորմալ պայմաններ: Այս գլխում օգտագործած օգնականների սկզբնական կոդը կարելի է գտնել գրացուցակում src/Applications/օգնական. Ազատորեն շրջեք գրացուցակի ծառի շուրջը՝ պարզելու, թե որտեղ է գտնվում և հասկանալ ns-3 ծրագրերի ոճը:

Source: www.habr.com

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