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

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

4 Агляд канцэпцыі
4.1 Ключавыя абстракцыі
4.1.1 Node (Вузел)
4.1.2 Application (Дадатак)
4.1.3 Channel (Канал)
4.1.4 Net Device (Сеткавая прылада)
4.1.5 Тапалагічныя памагатыя
4.2 Першы скрыпт ns-3
4.2.1 Boilerplate код
4.2.2 Падключаюцца модулі
4.2.3 Прастора імёнаў ns3
4.2.4 Журналіраванне
4.2.5 Галоўная функцыя
4.2.6 Выкарыстанне тапалагічных памагатых
4.2.7 Выкарыстанне Application
4.2.8 Сімулятар
4.2.9 Зборка вашага сцэнара
4.3 ns-3 Зыходны код

кіраўнік 4

Агляд канцэпцыі

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

4.1 Ключавыя абстракцыі

У гэтай частцы мы разгледзім некаторыя тэрміны, якія звычайна выкарыстоўваюцца ў сетцы, але маюць вызначанае значэнне ў ns‑3.

4.1.1 Node (Вузел)

На інтэрнэт-жаргоне камп'ютарная прылада, якая падключаецца да сеткі, называецца хастом ці часам канчатковай сістэмай. Па тым чынніку, што ns‑3 – гэта сімулятар сеткі, а не сімулятар Інтэрнэт, мы наўмысна не выкарыстоўваем тэрмін хост, бо гэта цесна злучана з Інтэрнэтам і яго пратаколамі. Замест гэтага мы выкарыстоўваем больш агульны тэрмін, таксама які выкарыстоўваецца іншымі сімулятарамі, які бярэ пачатак у тэорыі графаў - вузел.вузел).

У ns-3 базавая абстракцыя вылічальнай прылады завецца вузлом. Гэтая абстракцыя прадстаўлена ў C++ класам Node. Клас NodeNode (вузел) дае метады для кіравання ўяўленнямі вылічальных прылад у сімуляцыях.

Вы павінны разумець вузел як кампутар, да якога вы дадасце функцыянальнасць. Вы дадасце такія рэчы, як прыкладанні, стэкі пратаколаў і перыферыйныя карты з драйверамі, якія дазваляюць кампутару выконваць карысную працу. Мы выкарыстоўваем такую ​​ж базавую мадэль у ns-3.

4.1.2 Application (Дадатак)

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

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

У ns‑3 базавай абстракцыяй для карыстацкай праграмы, якая генеруе некаторую актыўнасць для мадэлявання, з'яўляецца прыкладанне. Гэтая абстракцыя прадстаўлена ў C++ класам Application (дадатак). Клас Application дае метады для кіравання ў сімуляцыях прадстаўленнямі нашай версіі прыкладанняў ўзроўню карыстальніка. Ад распрацоўшчыкаў чакаецца, што для стварэння новых прыкладанняў яны будуць спецыялізаваць клас Application у сэнсе аб'ектна-арыентаванага праграмавання. У гэтым кіраўніцтве мы будзем выкарыстоўваць спецыялізацыі класа Application, званыя UdpEchoClientApplication и UdpEchoServerApplication. Як і варта было чакаць, гэтыя прыкладанні складаюць набор прыкладанняў кліент/сервер выкарыстоўваных для генерацыі і рэха сімуляцыі сеткавых пакетаў.

4.1.3 Channel (Канал)

У рэальным свеце можна падлучыць кампутар да сеткі. Часта асяроддзі, па якіх перадаюцца дадзеныя ў гэтых сетках, завуцца каналамі. Калі вы падлучаеце кабель Ethernet да разеткі на сцяне, вы падлучаеце кампутар да канала сувязі Ethernet. У змадэляваным свеце ns‑3 вузел падлучаецца да аб'екта, які прадстаўляе канал сувязі. Тут асноўная абстракцыя камунікацыйнай падсеткі завецца каналам і ўяўляецца ў C++ класам Channel (канал).

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

Мы будзем выкарыстоўваць у гэтым кіраўніцтве спецыялізаваныя версіі канала пад назвай CsmaChannelCsmaChannel, PointToPointChannelPointToPointChannel и WifiChannelWifiChannel. CsmaChannel, напрыклад, мадэлюе версію камунікацыйнай падсеткі якая рэалізуе камунікацыйнае асяроддзе множнага доступу з кантролем апорнай. Гэта дае нам Ethernet-падобную функцыянальнасць.

4.1.4 Net Device (Сеткавая прылада)

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

Сеткавая карта не будзе працаваць без праграмнага драйвера, які кіруе яе абсталяваннем. У Unix (ці Linux), частка перыферыйнага абсталявання класіфікуецца як device. Прылады кіруюцца з дапамогай драйвераў прылад (device drivers), а сеткавыя прылады (NIC) кіруюцца з выкарыстаннем драйвераў сеткавых прылад (network device drivers) і маюць зборную назву сеткавыя прылады (net devices). У Unix і Linux вы звяртаецеся да сеткавых прылад па такіх імёнах, як напрыклад eth0.

У ns‑3 абстракцыя сеткавай прылады ахапляе як праграмны драйвер, так і мадэляванае абсталяванне. Пры сімуляцыі сеткавая прылада "ўстаноўлена" у вузле, каб дазволіць яму звязвацца з іншымі вузламі праз каналы. Як і ў рэальным кампутары, вузел можа быць падлучаны да некалькіх каналам праз некалькі прылад. NetDevices.

Сеткавая абстракцыя прылады прадстаўлена ў C++ класам NetDevice. Клас NetDevice забяспечвае метады кіравання злучэннямі з аб'ектамі Node і Channel; і могуць быць спецыялізаваны распрацоўшчыкамі ў сэнсе аб'ектна-арыентаванага праграмавання. У гэтым кіраўніцтве мы будзем выкарыстоўваць некалькі спецыялізаваных версій NetDevice пад назовамі CsmaNetDevice, PointToPointNetDevice и WifiNetDevice. Гэтак жа, як сеткавы адаптар Ethernet прызначаны для працы з сеткай Ethernet, CsmaNetDevice прызначаны для працы з CsmaChannel, PointToPointNetDevice прызначаны для працы з PointToPointChannel, А WifiNetDevice - прызначаны для працы з 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 у дырэкторыі з імем repos у вашай хатняй дырэкторыі. Перайдзіце ў дырэкторыю вызваліць

Калі ў вас няма такой дырэкторыі, значыць вы пры зборцы рэлізнай версіі ns‑3 не паказалі выходную дырэкторыю, выканайце зборку так:
$ ./waf configure -build-profile=release -out=build/release,
$ ./waf build

там вы павінны ўбачыць структуру дырэкторыі падобную на наступную:

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

Перайдзіце ў дырэкторыю examples/tutorial. Вы павінны ўбачыць размешчаны там файл з імем first.cc. Гэта скрыпт, які створыць простае злучэнне кропка-кропка паміж двума вузламі і перадасць адзін пакет паміж вузламі. Давайце паглядзім на гэты скрыпт парадкова, для гэтага адкрыем first.cc у вашым каханым рэдактары.

4.2.1 Boilerplate код
Першы радок у файле - гэта радок рэжыму рэдактара 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 License. Вы ўбачыце адпаведны юрыдычны загаловак GNU у кожным файле дыстрыбутыва ns‑3. Часта вы можаце ўбачыць апавяшчэнне аб аўтарскіх правах для адной з устаноў, што ўдзельнічаюць у праекце 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 ва ўсталяваным вамі рэлізе. У лістынгу гэтай дырэкторыі вы знойдзеце вялікую колькасць загалоўкавых файлаў. Калі вы робіце зборку, Waf змяшчае агульнадаступныя загалоўкавыя файлы ў дырэкторыю ns3 у паддырэкторыю build/debug

Калі ў вас няма такой дырэкторыі, значыць вы пры зборцы рэлізнай версіі ns‑3 не паказалі выходную дырэкторыю, выканайце зборку так:
$ ./waf configure -build-profile=debug -out=build/debug
$ ./waf build
або
$ ./waf configure -build-profile=optimized -out=build/optimized
$ ./waf build

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

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

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

$ ./waf

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

4.2.3 Прастора імёнаў ns3

Наступны радок у скрыпце first.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, вы знойдзеце спасылку "Дакументацыя" (Documentation) на панэлі навігацыі. Калі вы вылучыце гэтую спасылку, то апынецеся на нашай старонцы дакументацыі. Існуе спасылка на "Апошні рэліз", якая прывядзе вас да дакументацыі для апошняй стабільнай версіі ns‑3. Калі вы вылучыце спасылку "API Documentation", вы патрапіце на старонку дакументацыі API ns‑3.

З левага боку старонкі вы знойдзеце графічнае ўяўленне структуры дакументацыі. Добрае месца для пачатку гэта кніга Modules ns‑3 у дрэве навігацыі ns‑3. Калі вы раскрыеце Модулі, вы ўбачыце спіс дакументацыі модуляў ns‑3. Як абмяркоўвалася вышэй, канцэпцыя модуля тут напроста злучана з уключанымі ў модуль файламі вышэй. Падсістэма часопісавання (вядзення часопіса, лагіравання) ns‑3 абмяркоўваецца ў раздзеле Выкарыстанне модуля часопісавання, таму мы вернемся да яе пазней у гэтым кіраўніцтве, але Вы можаце даведацца аб прыведзеным вышэй зацвярджэнні, паглядзеўшы на модуль Core, а затым адкрыўшы кнігу Інструменты для адладкі, а затым выбраўшы старонку Запіс. Клікніце па Запіс.

Цяпер вы павінны прагледзець дакументацыю Doxygen для модуля Запіс. У спісе макрасаў у верхняй частцы старонкі вы ўбачыце запіс для NS_LOG_COMPONENT_DEFINE. Перад тым як перайсці па спасылцы, абавязкова паглядзіце "Падрабязнае апісанне" модуля рэгістрацыі, каб зразумець яго працу ў цэлым. Каб зрабіць гэта, вы можаце пракруціць ўніз або выбраць «More…» пад дыяграмай.

Як толькі ў вас будзе агульнае ўяўленне аб тым, што адбываецца, працягвайце і паглядзіце дакументацыю на канкрэтныя 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, проста пракруціце уверх да верхняй частцы старонкі і абярыце ўкладку Classes. Вы павінны ўбачыць новы набор укладак, адзін з якіх спіс класаў. Пад гэтай укладкай вы ўбачыце спіс усіх класаў ns‑3. Пракруціце ўніз, да ns3 :: NodeContainer. Калі вы знойдзеце клас, абярыце яго, каб перайсці да дакументацыі для класа.

Як мы памятаем, адной з нашых ключавых абстракцый з'яўляецца вузел. Ён уяўляе кампутар, да якога мы збіраемся дадаць такія рэчы, як стэкі пратаколаў, прыкладанні і перыферыйныя карты. Тапалагічны памочнік NodeContainer забяспечвае зручны спосаб стварэння, кіравання і доступу да любых аб'ектаў вузел, якія мы ствараем для запуску сімуляцыі. Першы радок вышэй проста аб'яўляе NodeContainer, які мы называем nodes. Другі радок выклікае метад Create для аб'екта nodes і просіць кантэйнер стварыць два вузла. Як апісана ў 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.

З больш канкрэтнага пункту гледжання, радок "DataRate" адпавядае таму, што мы называем атрыбутам PointToPointNetDevice. Калі вы паглядзіце на Doxygen для класа ns3::PointToPointNetDevice і ў дакументацыі да метаду GetTypeId вы знойдзеце спіс атрыбутаў, вызначаных для прылады. Сярод іх будзе атрыбутDataRate». Большасць бачных карыстачом аб'ектаў ns‑3 маюць падобныя спісы атрыбутаў. Мы выкарыстоўваем гэты механізм для простай налады сімуляцыі без перакампілявання, як вы ўбачыце ў наступным раздзеле.

ПадобнаDataRate» у PointToPointNetDevice, вы знойдзеце атрыбут "Delay", звязаны з PointToPointChannel. Фінальны радок,

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

кажа PointToPointHelper выкарыстоўваць значэнне "2 мс" (дзве мілісекунды) у якасці значэння затрымкі распаўсюджвання па канале кропка-кропка, які ён пасля стварае.

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 (nodes) у нас будзе два вузла, кожны з усталяванай сеткавай прыладай "кропка-кропка" і адным каналам "кропка-кропка" паміж імі. Абодва прылады будуць настроены на перадачу дадзеных з хуткасцю пяць мегабіт у секунду з затрымкай перадачы па канале ў дзве мілісекунды.

InternetStackHelper

Цяпер у нас настроены вузлы і прылады, але на нашых вузлах не ўстаноўлены стэкі пратаколаў. Наступныя два радкі кода паклапоцяцца пра гэта.

InternetStackHelper stack;
stack.Install (nodes);

InternetStackHelper — уяўляе сабой тапалагічны памагаты для інтэрнэт-стэкаў, падобна PointToPointHelper для двухкропкавых сеткавыя прылад. Метад Усталёўваць прымае NodeContainer у якасці параметру. Пры выкананні ён усталюе Інтэрнэт-стэк (TCP, UDP, IP і т. д.) на кожным вузле кантэйнера.

Ipv4AddressHelper

Затым нам трэба да нашы прылады звязаць з IP адрасамі. Мы даем тапалагічнага памочніка для кіравання размеркаваннем IP-адрасоў. Адзіны бачны карыстачу API - гэта ўсталёўка базавага IP-адрасы і маскі сеткі для выкарыстання пры выкананні фактычнага размеркавання адрасоў (гэта робіцца на ніжэйшым узроўні ўсярэдзіне памагатага). Наступныя два радкі кода ў нашым прыкладзе скрыпту first.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-адрасам і прыладай, выкарыстоўваючы аб'ект Ipv4Interface. Гэтак жа, як нам часам патрэбен спіс сеткавых прылад, створаных памагатым для наступнага выкарыстання, нам часам патрэбен спіс аб'ектаў. Ipv4Interface. Ipv4InterfaceContainer дае гэтую функцыянальнасць.

Мы пабудавалі сетку кропка-кропка, з усталяванымі стэкамі і прызначанымі IP-адрасамі. Цяпер нам патрэбныя ў кожным вузле прыкладання для генерацыі трафіку.

4.2.7 Выкарыстанне Application

Яшчэ адна з асноўных абстракцый сістэмы ns‑3 – гэта дадатак (дадатак). У гэтым сцэнары мы выкарыстоўваем дзве спецыялізацыі базавага класа. дадатак ns‑3 пад назвай UdpEchoServerApplication и UdpEchoClientApplication. Як і ў папярэдніх выпадках, мы выкарыстоўваем дапаможныя аб'екты для настройкі і кіравання базавымі аб'ектамі. Тут мы выкарыстоўваем UdpEchoServerHelper и UdpEchoClientHelper аб'екты, каб зрабіць наша жыццё прасцей.

UdpEchoServerHelper

Наступныя радкі кода ў нашым прыкладзе скрыпту first.cc, выкарыстоўваюцца для налады прыкладання UDP рэха сервера на адным з вузлоў, якія мы стварылі раней.

UdpEchoServerHelper echoServer (9);

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

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

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

Няяўнае пераўтварэнне C++, якое працуе тут, прымае вынік метаду node.Get (1) (які вяртае разумны паказальнік на аб'ект вузла Ptr ) і выкарыстоўвае яго ў канструктару для ананімнага аб'екта NodeContainer, які затым перадаецца метаду Усталёўваць. Калі вы не можаце вызначыць у C++ кодзе, метад з якой сігнатурай кампілюецца і выконваецца, то шукайце сярод няяўных пераўтварэнняў.

Цяпер мы бачым, што echoServer.Install збіраецца ўсталяваць дадатак UdpEchoServerApplication на знойдзены ў NodeContainer, які мы выкарыстоўваем для кіравання нашымі вузламі, вузел з індэксам 1. Метад Усталёўваць верне кантэйнер, які змяшчае паказальнікі на ўсе прыкладанні (у дадзеным выпадку адно, паколькі мы перадалі ананімны NodeContainer, які змяшчае адзін вузел) створаны памочнікам.

Прыкладанням патрабуецца пазначыць момант запуску генерацыі трафіку "start" і можа спатрэбіцца дадаткова пазначыць час, калі яго спыніць "stop". Мы даем абодва параметры. Гэтыя часы ўстанаўліваюцца з дапамогай метадаў ApplicationContainer дома и Стоп. Гэтыя метады прымаюць параметры тыпу час. У гэтым выпадку мы выкарыстоўваем відавочную паслядоўнасць пераўтварэнняў C++, каб узяць C++ ўдвая 1.0 і пераўтварыць яго ў аб'ект тns‑3 Time, які выкарыстоўвае аб'ект Seconds для перакладу ў секунды. Памятайце, што правілы пераўтварэнні могуць кантралявацца аўтарам мадэлі, і C++ мае свае ўласныя правілы, таму вы не заўсёды можаце разлічваць на тое, што параметры будуць пераўтвораны так, як вы чакалі. Два радкі,

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

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

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));;

Аднак для рэха-кліента нам трэба ўсталяваць пяць розных атрыбутаў. Першыя два атрыбуты ўстанаўліваюцца падчас стварэння UdpEchoClientHelper. Мы перадаем параметры, якія выкарыстоўваюцца (ўнутры памочніка) для ўстаноўкі атрыбутаў "RemoteAddress" и "RemotePort" у адпаведнасці з нашым пагадненнем, аб перадачы неабходных параметраў у канструктар памочніка.

Нагадаем, што мы выкарыстоўвалі Ipv4InterfaceContainer для адсочвання IP-адрасоў, якія мы прысвоілі нашым прыладам. Нулявы інтэрфейс у кантэйнеры інтэрфейсаў будзе адпавядаць IP-адрасу нулявога вузла ў кантэйнеры вузлоў. Першы інтэрфейс у кантэйнеры інтэрфейсаў адпавядае IP-адрасу першага вузла ў кантэйнеры вузлоў. Такім чынам, у першым радку кода (зверху) мы ствараем памагатага і паведамляем яму, што выдаленым адрасам кліента будзе IP-адрас, прызначаны вузлу, на якім знаходзіцца сервер. Мы таксама гаворым, што трэба арганізаваць адпраўку пакетаў на дзявяты порт.

Атрыбут "MaxPackets" паведамляе кліенту максімальную колькасць пакетаў, якую мы можам адправіць падчас мадэлявання. Атрыбут "Interval" паведамляе кліенту, як доўга чакаць паміж пакетамі, і атрыбут "PacketSize" паведамляе кліенту, наколькі вялікая павінны быць карысная нагрузка пакета. Гэтай камбінацыяй атрыбутаў мы гаворым кліенту адправіць адзін 1024-байтавы пакет.

Як і ў выпадку з рэха-серверам, мы ўсталёўваем рэха-кліенту атрыбуты дома и Стоп, Але тут мы запускаем кліент праз секунду пасля ўключэння сервера (праз дзве секунды пасля пачатку сімуляцыі).

4.2.8 Сімулятар

На гэтым этапе нам трэба запусьціць сымуляцыю. Гэта робіцца з дапамогай глабальнай функцыі Simulator::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 секунды. Пасля выкліку Simulator::Run, сістэма пачне праглядаць спіс запланаваных падзей і выконваць іх. Спачатку ён запусціць падзею праз 1,0 секунды, што актывуе дадатак рэха-сервера (гэтая падзея можа, у сваю чаргу, запланаваць шмат іншых падзей). Затым ён запусціць падзею, запланаваную на t = 2,0 секунды, якое запусціць прыкладанне рэха-кліента. Ізноў жа, гэтая падзея можа запланаваць яшчэ шмат падзей. Рэалізацыя падзеі запуску ў рэха-кліенце пачне этап перадачы дадзеных мадэлявання, даслаўшы пакет на сервер.

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

У выніку, паколькі мы адпраўляем толькі адзін пакет (нагадаем, атрыбут MaxPackets быў усталяваны ў адзінку), ланцужок падзей ініцыяваны гэтым адзіным кліенцкім рэха-запытам скончыцца, і сімуляцыя пяройдзе ў рэжым чакання. Як толькі гэта адбудзецца, пакінутымі запланаванымі падзеямі будуць падзеі Стоп для сервера і кліента. Калі гэтыя падзеі выканаюцца, падзей для далейшай апрацоўкі не застанецца і Simulator::Run верне кіраванне. Мадэляванне завершана.

Засталося толькі прыбраць за сабой. Гэта робіцца шляхам выкліку глабальнай функцыі Simulator::Destroy. Паколькі выклікаліся функцыі памагатых (або код нізкага ўзроўня ns‑3), якія арганізаваныя так, каб у сімулятары былі ўстаўленыя хукі для знішчэння ўсіх аб'ектаў, якія былі створаны. Вам не патрабуецца адсочваць якія-небудзь з гэтых аб'ектаў самастойна - усё, што вам трэба было зрабіць гэта выклікаць Simulator::Destroy і выйсці. Сістэма ns‑3 зробіць гэтую цяжкую працу за вас. Пакінутыя радкі нашага першага ns‑3 скрыпта, first.cc, робяць менавіта гэта:

Simulator::Destroy ();
return 0;
}

Калі сімулятар спыніцца?

ns‑3 – сімулятар дыскрэтных падзей (DE). У такім сімулятары кожная падзея звязана з часам яго выканання, а сімуляцыя працягваецца апрацоўкай падзей у парадку іх узнікнення па ходзе сімуляцыі. Падзеі могуць стаць прычынай планавання будучых падзей (напрыклад, таймер можа перапланаваць сябе, каб скончыць рахунак у наступным інтэрвале).

Пачатковыя падзеі звычайна ініцыююцца аб'ектам, напрыклад, IPv6 будзе планаваць вызначэнне сэрвісаў у сетцы, запыты суседзяў і г.д. Прыкладанне плануе першую падзею адпраўкі пакета і г.д. Калі падзея апрацоўваецца, яна можа генераваць нуль, адну ці некалькі падзей. Па меры выканання сімуляцыі, адбываюцца падзеі, проста сканчаючыся ці спараджаючы новыя. Сімуляцыя спыніцца аўтаматычна, калі чарга падзей апынецца пустой або будзе выяўлены спецыяльная падзея Стоп. Падзея Стоп генеруецца функцыяй Simulator::Stop (спыніць час).

Існуе тыповы выпадак, калі Simulator::Stop абсалютна неабходна для прыпынку сімуляцыі: калі ёсць самоподдерживающиеся падзеі. Самападтрымліваюцца (або паўтараюцца) падзеі - гэта падзеі, якія заўсёды пераплануюцца. Як следства, яны заўсёды захоўваюць чаргу падзей не пустой. Існуе шмат пратаколаў і модуляў, якія змяшчаюць паўтаральныя падзеі, напрыклад:

• FlowMonitor - перыядычная праверка на страчаныя пакеты;

• RIPng - перыядычная трансляцыя абнаўлення табліц маршрутызацыі;

• і г.д.

У такіх выпадках Simulator::Stop неабходны для карэктнага спынення сімуляцыі. Акрамя таго, калі ns‑3 знаходзіцца ў рэжыме эмуляцыі, RealtimeSimulator выкарыстоўваецца, каб сінхранізаваць гадзіны сімуляцыі з гадзінамі машыны, і Simulator::Stop неабходны для спынення працэсу.

Многія з праграм сімуляцыі ў падручніку не выклікаюць Simulator::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, і ён будзе аўтаматычна сабраны, калі вы запусціце Waf. Давай паспрабуем. Вернецеся ў каталог верхняга ўзроўню і скапіруйце examples/tutorial/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

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

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

Нашы прыклады сцэнарыяў знаходзяцца ў дырэкторыі Прыклады. Калі вы націснеце на прыклады, вы ўбачыце спіс паддырэкторый. Адзін з файлаў у паддырэкторыі tutorial - first.cc. Калі вы націснеце на first.cc вы ўбачыце код, які вы толькі што вывучылі.

Зыходны код знаходзіцца ў асноўным у дырэкторыі SRC. Вы можаце прагледзець зыходны код, націснуўшы на імя дырэкторыі або націснуўшы на спасылку файлы справа ад імя дырэкторыі. Калі вы клікнеце на дырэкторыя src, вы атрымаеце спіс паддырэкторый src. Калі вы затым клікнеце па паддырэкторыі core, вы знойдзеце спіс файлаў. Першы файл, які вы ўбачыце (на момант напісання гэтага кіраўніцтва) abort.h. Калі вы націснеце на спасылку abort.h, вы будзеце адпраўлены на зыходны файл для abort.h, які змяшчае карысныя макрасы для выхаду са скрыптоў, калі выяўлены ненармальныя ўмовы. Зыходны код для памочнікаў, якія мы выкарыстоўвалі ў гэтым раздзеле, можна знайсці ў дырэкторыі src/Applications/helper. Не саромейцеся капацца ў дрэве дырэкторый, каб зразумець, што дзе і разабрацца ў стылі праграм ns‑3.

Крыніца: habr.com

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