ns-3 retsimulilo lernilo. Ĉapitro 4

ns-3 retsimulilo lernilo. Ĉapitro 4
Ĉapitro 1,2
Ĉapitro 3

4 Koncepta superrigardo
4.1 Ŝlosilaj abstraktaĵoj
4.1.1 Nodo
4.1.2 Apliko
4.1.3 Kanalo
4.1.4 Reta Aparato
4.1.5 Topologiaj asistantoj
4.2 Unua ns-3-skripto
4.2.1 Boilerplata kodo
4.2.2 Kromaĵoj
4.2.3 ns3 nomspaco
4.2.4 Registrado
4.2.5 Ĉefa funkcio
4.2.6 Uzado de topologiaj asistantoj
4.2.7 Uzado de Apliko
4.2.8 Simulilo
4.2.9 Konstruante vian skripton
4.3 ns-3 Fontkodo

Ĉapitro 4

Koncepta superrigardo

La unua afero, kiun ni devas fari antaŭ ol komenci lerni aŭ skribi ns-3-kodon, estas klarigi kelkajn bazajn konceptojn kaj abstraktaĵojn en la sistemo. Multo de ĉi tio povas ŝajni evidenta al iuj, sed ni rekomendas preni la tempon por legi ĉi tiun sekcion por certigi, ke vi komencas sur solida bazo.

4.1 Ŝlosilaj abstraktaĵoj

En ĉi tiu sekcio, ni rigardos kelkajn terminojn, kiuj estas ofte uzataj en la reto, sed havas specifan signifon en ns-3.

4.1.1 Nodo

En Interreta ĵargono, komputila aparato kiu konektas al reto estas nomita gastiganto aŭ foje finsistemo. Ĉar ns-3 estas reto-simulilo kaj ne interreta simulilo, ni intence ne uzas la esprimon gastiganto, ĉar ĉi tio estas proksime rilata al la Interreto kaj ĝiaj protokoloj. Anstataŭe, ni uzas pli ĝeneralan terminon, ankaŭ uzatan de aliaj simuliloj, kiu originas en grafeorio: nodo (nodo).

En ns-3, la subesta abstraktado de komputika aparato estas nomita nodo. Ĉi tiu abstraktado estas reprezentita en C++ per la klaso Node. Klaso NodeNode (nodo) disponigas metodojn por manipulado de reprezentadoj de komputikaj aparatoj en simulaĵoj.

Vi devas kompreni nodo kiel komputilo al kiu vi aldonas funkciojn. Vi aldonos aferojn kiel aplikojn, protokolajn stakojn kaj ekstercentrajn kartojn kun ŝoforoj, kiuj permesas al la komputilo fari utilan laboron. Ni uzas la saman bazan modelon en ns-3.

4.1.2 Apliko

Ĝenerale, komputila programaro estas dividita en du larĝajn klasojn. Sistema programaro organizas diversajn komputilajn rimedojn kiel memoron, procesorajn ciklojn, diskon, reton ktp laŭ iu komputika modelo. Sistemprogramaro kutime ne uzas ĉi tiujn rimedojn por plenumi taskojn, kiuj rekte profitigas la uzanton. Uzanto tipe prizorgas aplikaĵon por atingi specifan celon, kiu akiras kaj uzas resursojn kontrolitajn de la sistemprogramaro.

Ofte la linio de apartigo inter sistemo kaj aplikaĵo programaro estas desegnita ĉe privileginivelaj ŝanĝoj kiuj okazas en operaciumaj kaptiloj. ns-3 havas neniun realan koncepton de operaciumo kaj tial neniun koncepton de privilegiaj niveloj aŭ sistemvokoj. Ni tamen havas ideon por aplikaĵo. Same kiel en la "reala mondo" programaroj funkcias per komputiloj por plenumi taskojn, ns-3-aplikoj funkcias per ns-3-nodoj por kontroli simulaĵojn en la ŝajniga mondo.

En ns-3, la baza abstraktado por uzantprogramo kiu generas iun agadon por modeligado estas aplikaĵo. Ĉi tiu abstraktado estas reprezentita en C++ per la Aplikklaso. La Aplikaĵo-klaso disponigas metodojn por manipuli vidojn de nia uzantnivela versio de aplikoj en simulaĵoj. Programistoj estas atenditaj specialigi la Aplikklason en objekt-orientita programa senco por krei novajn aplikojn. En ĉi tiu lernilo, ni uzos specialaĵojn de la Aplika klaso nomita UdpEchoClientApplication и UdpEchoServerApplication. Kiel vi povus atendi, ĉi tiuj aplikoj konsistigas aron de kliento/servilaj aplikoj uzataj por generi kaj eĥigi retajn pakaĵetojn.

4.1.3 Kanalo

En la reala mondo, vi povas konekti komputilon al reto. Ofte la amaskomunikilaro super kiuj datumoj estas elsenditaj en ĉi tiuj retoj estas nomitaj kanaloj. Kiam vi ŝtopas Ethernet-kablon en muron, vi konektas vian komputilon al Ethernet-ligo. En la ŝajniga ns-3-mondo, nodo estas ligita al objekto reprezentanta komunikadkanalon. Ĉi tie, la baza abstraktado de la komunika subreto estas nomita kanalo kaj estas reprezentita en C++ per la Channel-klaso.

Класс ChannelChannel disponigas metodojn por administri la interagadon de subretaj objektoj kaj ligado de nodoj al ili. Kanaloj ankaŭ povas esti specialigitaj fare de programistoj en objekt-orientita programa signifo. Kanala specialiĝo povas modeligi ion tiel simplan kiel drato. Diligenta kanalo ankaŭ povas modeligi kompleksajn aferojn kiel granda Ethernet-ŝaltilo aŭ tridimensia spaco plena de obstakloj en la kazo de sendrataj retoj.

Ni uzos specialajn versiojn de la kanalo en ĉi tiu lernilo nomita CsmaChannelCsmaChannel, PointToPointChannelPointToPointChannel и WifiChannelWifiChannel. CsmaChannel, ekzemple, modeligas version de komunikadsubreto kiu efektivigas aviad-kompani-sensan multoblan alirkomunikadmedion. Ĉi tio donas al ni Ethernet-similan funkciecon.

4.1.4 Reta Aparato

Antaŭe estis, ke se oni volis konekti komputilon al reto, oni devis aĉeti specifan retan kablon kaj aparataron nomatan (laŭ komputila terminologio) ekstercentra karto, kiun oni devis instali en la komputilon. Se ekstercentra karto efektivigis iujn interkonektajn funkciojn, ili estis nomitaj retinterfaco-kartoj aŭ retkartoj. Hodiaŭ, la plej multaj komputiloj venas kun integra retinterfaco aparataro kaj ne estas viditaj de uzantoj kiel apartaj aparatoj.

Reta karto ne funkcios sen programara pelilo, kiu regas sian aparataron. En Unikso (aŭ Linukso), peco de ekstercentra ekipaĵo estas klasifikita kiel aparato. Aparatoj estas administritaj per aparataj ŝoforoj, kaj retaj aparatoj (NIC) estas administritaj per retaj aparatoj (retaj aparatoj ŝoforoj) kaj estas kolektive nomitaj retaj aparatoj (retaj aparatoj). En Unikso kaj Linukso, vi rilatas al retaj aparatoj per nomoj kiel ekzemple et0.

En ns-3, la ret-aparato-abstraktado kovras kaj la softvarŝoforon kaj la hardvaron estantan modeligitan. En la simulado, reta aparato estas "instalita" en nodo por permesi al ĝi komuniki kun aliaj nodoj tra kanaloj. Same kiel vera komputilo, nodo povas esti konektita al pluraj kanaloj per pluraj aparatoj Retaj aparatoj.

La retabstraktado de aparato estas reprezentita en C++ fare de la klaso NetDevice. Klaso NetDevice disponigas metodojn por administri ligojn al Node kaj Channel-objektoj; kaj povas esti specialigita de programistoj en la signifo de objekt-orientita programado. En ĉi tiu lernilo ni uzos plurajn specialigitajn versiojn de NetDevice nomataj CsmaNetDevice, PointToPointNetDevice и WifiNetDevice. Same kiel Ethernet-retadaptilo estas desegnita por funkcii kun reto ethernet, CsmaNetDevice desegnita por labori kun CsmaChannel, PointToPointNetDevice desegnita por labori kun PointToPointChannelkaj WifiNetDevice - desegnita por labori kun WifiChannel.

4.1.5 Topologiaj asistantoj

En vera reto, vi trovos gastigajn komputilojn kun retkartoj aldonitaj (aŭ enkonstruitaj). En ns-3 ni dirus, ke vi vidos nodojn kun NetDevices alfiksitaj. En granda ŝajniga reto, vi devos organizi ligojn inter multaj objektoj nodo, NetDevice и kanalo.

Ekde konekto de NetDevices al nodoj, NetDevices al ligiloj, asignado de IP-adresoj ktp. en ns-3 estas ofta tasko, por fari tion kiel eble plej facila ni provizas tiel nomatajn topologiajn helpantojn. Ekzemple, por krei NetDevice, vi devas fari multajn ns-3-kernoperaciojn, aldoni MAC-adreson, instali la retan aparaton en Nodo, agordi la protokolan stakon de la nodo, kaj tiam konekti la NetDevice al la Kanalo. Eĉ pli da laboro estos postulata por konekti plurajn aparatojn al plurpunktaj ligiloj kaj poste konekti la individuajn retojn en Internetworks-reton. Ni provizas topologiajn helpajn objektojn, kiuj kombinas ĉi tiujn multajn operaciojn en facile uzeblan modelon por via komforto.

4.2 Unua ns-3-skripto

Se vi instalis la sistemon kiel supre sugestite, vi havos la ns-3-eldonon en dosierujo nomata repos en via hejma dosierujo. Iru al dosierujo ĵeto

Se vi ne havas tian dosierujon, tio signifas, ke vi ne specifis la eligdosierujon kiam vi konstruis la eldonan version de ns-3, konstruu jene:
$ ./waf agordi —build-profile=liberigi —out=konstrui/liberigi,
$ ./waf konstruo

tie vi devus vidi dosierujon similan al la jena:

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

Iru al dosierujo ekzemploj/lernilo. Vi devus vidi dosieron lokita tie nomita unue.cc. Ĉi tio estas skripto, kiu kreos simplan punkto-al-punktan konekton inter du nodoj kaj elsendos unu pakaĵeton inter la nodoj. Ni rigardu ĉi tiun skripton linion post linio; por fari tion, malfermu first.cc en via plej ŝatata redaktilo.

4.2.1 Boilerplata kodo
La unua linio en la dosiero estas la redaktila reĝimo linio emacs. Ĝi rakontas al emacs pri la formataj konvencioj (kodstilo) kiujn ni uzas en nia fontkodo.

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

Ĉi tio ĉiam estas sufiĉe polemika afero, do ni devas fiksi la rekordon rekte por forigi ĝin tuj. La ns-3-projekto, kiel la plej multaj grandaj projektoj, adoptis kodigan stilon al kiu ĉiu kontribuita kodo devas konformiĝi. Se vi volas kontribui vian kodon al la projekto, vi eventuale devos konformiĝi al la koda normo ns-3, kiel priskribite en la dosiero. doc/codingstd.txt aŭ montrata sur la retpaĝo de la projekto: https://www.nsnam.org/develop/contributing-code/coding-style/.

Ni rekomendas, ke vi kutimiĝu al la aspekto kaj sento de ns-3-kodo kaj apliki ĉi tiun normon kiam ajn vi laboras kun nia kodo. La tuta disvolva teamo kaj kontribuantoj konsentis pri tio post iom da grumblado. La emacs-reĝimo-linio supre faciligas ĝuste formati se vi uzas la emacs-redaktilon.

La simulilo ns-3 estas licencita uzante GNU Ĝenerala Publika Permesilo. Vi vidos la taŭgan GNU-leĝan kaplinion en ĉiu distribua dosiero ns-3. Ofte vi vidos kopirajtan avizon por unu el la partoprenantaj institucioj en la projekto ns-3 super la GPL-teksto kaj aŭtoro, montritaj malsupre.

/* 
* 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 Kromaĵoj

La kodo mem komenciĝas per serio de inkluzivaroj (inkluzivi).

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

Por helpi niajn altnivelajn skriptuzantojn trakti la grandan nombron da kapdosieroj ĉeestantaj en la sistemo, ni grupigas ilin laŭ ilia uzado en grandajn modulojn. Ni provizas ununuran kapdosieron, kiu rekursie ŝargos ĉiujn kapdosierojn uzatajn en donita modulo. Anstataŭ devi serĉi ĝuste kian kaplinion vi bezonas kaj eble akiri la ĝustan liston de dependecoj, ni donas al vi la kapablon elŝuti grupon da dosieroj en granda granulareco. Ĝi ne estas la plej efika aliro, sed ĝi certe faciligas verki skriptojn.

Ĉiu el la ns-3 inkluzivas dosierojn estas metita en dosierujon nomitan ns3 (konstrua subdosierujo) por eviti dosiernomajn konfliktojn dum la konstruprocezo. Dosiero ns3/core-module.h respondas al la modulo ns-3, kiun vi trovos en la dosierujo src/kerno en la eldono, kiun vi instalis. En la listo de ĉi tiu dosierujo vi trovos grandan nombron da kapdosieroj. Kiam vi faras la asembleon, Waf metas publikajn kapdosierojn en la dosierujon ns3 en subdosierujon konstrui/sencimigi

Se vi ne havas tian dosierujon, tio signifas, ke vi ne specifis la eligdosierujon kiam vi konstruis la eldonan version de ns-3, konstruu jene:
$ ./waf agordi --build-profile=sencimigi --out=konstrui/sencimigi
$ ./waf konstruo

$ ./waf agordi --build-profile=optimumigita --out=konstruo/optimumigita
$ ./waf konstruo

konstruo/optimumigita, depende de via agordo. Waf ankaŭ aŭtomate generos modulon inkluzivi dosieron por ŝargi ĉiujn publikajn kapdosierojn. Ĉar vi kompreneble sekvas ĉi tiun gvidilon religie, vi jam faris

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

por agordi la projekton por ruli sencimigajn konstruojn, kiuj inkluzivas ekzemplojn kaj testojn. Vi ankaŭ faris

$ ./waf

por kunmeti la projekton. Do nun kiam vi rigardas en la dosierujo ../../build/debug/ns3, tiam tie vi trovos, interalie, la kapdosierojn de la kvar moduloj montritaj supre. Vi povas rigardi la enhavon de ĉi tiuj dosieroj kaj trovi, ke ili inkluzivas ĉiujn publikajn dosierojn uzatajn de la respondaj moduloj.

4.2.3 ns3 nomspaco

Sekva linio en skripto unue.cc estas nomspaca deklaro.

using namespace ns3;

La ns-3 projekto estas efektivigita en C++ nomspaco nomita ns3. Ĉi tio grupigas ĉiujn ns-3-rilatajn deklarojn en amplekson ekster la tutmonda nomspaco, kiu espereble helpos kun integriĝo kun alia kodo. Uzi la C++-funkciigiston enkondukas la nomspacon ns-3 en la nunan (tutmondan) deklaran regionon. Ĉi tio estas fantazia maniero diri, ke post ĉi tiu deklaro, vi ne bezonos tajpi la ns3::scope-permesan operatoron antaŭ via tuta ns-3-kodo por uzi ĝin. Se vi ne konas nomspacojn, referencu al preskaŭ ajna C++-lernolibro kaj komparu la ns3-nomspacon uzante la std-nomspacon kaj deklaron. using namespace std; en ekzemploj de laborado kun la eligfunkciigisto kosto kaj riveretoj.

4.2.4 Registrado

La sekva linio de la skripto estas:

NS_LOG_COMPONENT_DEFINE ("FirstScriptExample");

Ni uzos ĉi tiun deklaron kiel oportunan lokon por diskuti pri nia dokumenta sistemo Doksigeno. Se vi rigardas la retejon de la projekto ns-3, vi trovos ligilon al Dokumentado en la navigadbreto. Se vi alklakas ĉi tiun ligon, vi estos kondukata al nia dokumenta paĝo. Estas ligilo "Lasta Eldono", kiu kondukos vin al la dokumentado por la plej nova stabila versio de ns-3. Se vi elektas la ligilon "API Dokumentado", vi estos kondukata al la paĝo pri dokumentado de ns-3 API.

Sur la maldekstra flanko de la paĝo vi trovos grafikan reprezenton de la dokumenta strukturo. Bona loko por komenci estas la Moduloj ns-3 "libro" en la navigada arbo ns-3. Se vi malkaŝas moduloj, vi vidos liston de dokumentado pri ns-3-moduloj. Kiel diskutite supre, la koncepto de modulo ĉi tie rekte rilatas al la dosieroj inkluzivitaj en la modulo supre. La ns-3 registra subsistemo estas diskutita en sekcio Uzante la Registradan Modulon, do ni revenos al ĝi poste en ĉi tiu lernilo, sed vi povas lerni pri la supra deklaro rigardante la modulon kernakaj poste malfermante la libron Elpurigaj ilojkaj poste elektante la paĝon tala. Alklaku tala.

Vi nun devus revizii la dokumentaron Doksigeno por modulo tala. En la listo de makrooj ĉe la supro de la paĝo, vi vidos enskribon por NS_LOG_COMPONENT_DEFINE. Antaŭ ol klaki la ligilon, nepre rigardu la "Detalan Priskribon" de la registra modulo por kompreni kiel ĝi funkcias ĝenerale. Por fari tion vi povas rulumi malsupren aŭ elekti "Pli..." sub la diagramo.

Post kiam vi havas ĝeneralan ideon pri kio okazas, daŭrigu kaj rigardu la dokumentadon por la specifa NS_LOG_COMPONENT_DEFINE. Mi ne duobligos la dokumentaron ĉi tie, sed por resumi, ĉi tiu linio deklaras registran komponanton nomatan UnuaSkriptoEkzemplo, kiu ebligas al vi ebligi aŭ malebligi konzolan protokolon de mesaĝoj per referenco al nomo.

4.2.5 Ĉefa funkcio

En la sekvaj linioj de la skripto vi vidos,

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

Ĉi tio estas simple deklaro de la ĉefa funkcio de via programo (skripto). Kiel kun iu ajn C++-programo, vi devas difini ĉefan funkcion, ĉi tio unue estas ekzekutita. Estas nenio speciala ĉi tie. Via ns-3-skripto estas nur C++-programo. La sekva linio fiksas la temporezolucion al 1 nanosekundo, kiu estas la defaŭlta:

Time::SetResolution (Time::NS);

Temprezolucio, aŭ simple rezolucio, estas la plej malgranda tempovaloro kiu povas esti uzita (la plej malgranda reprezentebla diferenco inter du tempoj). Vi povas ŝanĝi la rezolucion ĝuste unufoje. La mekanismo kiu provizas ĉi tiun flekseblecon konsumas memoron, do post kiam la rezolucio estas eksplicite fiksita, ni liberigas la memoron, malhelpante pliajn ĝisdatigojn. (Se vi ne fiksas la rezolucion eksplicite, ĝi defaŭltos al unu nanosekundo kaj la memoro estos liberigita kiam la simulado komenciĝos.)

La sekvaj du linioj de skripto estas uzataj por ebligi du protokolojn, kiuj estas enkonstruitaj en aplikoj EchoClient и EĥoServilo:

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

Se vi legas la dokumentadon por la Logging-komponento, vi vidos, ke ekzistas pluraj niveloj de registrad/granulareco, kiujn vi povas ebligi sur ĉiu komponento. Ĉi tiuj du linioj de kodo ebligas sencimigan registradon al la INFO-nivelo por eĥaj klientoj kaj serviloj. Je ĉi tiu nivelo, la aplikaĵo presas mesaĝojn dum ĝi sendas kaj ricevas pakaĵojn dum simulado.

Nun ni komencos la komercon krei la topologion kaj ruli la simuladon. Ni uzas topologiajn helpajn objektojn por fari ĉi tiun laboron kiel eble plej facila.

4.2.6 Uzado de topologiaj asistantoj

La sekvaj du linioj de kodo en nia skripto efektive kreos la objektojn Node ns-3, kiuj reprezentos la komputilojn en la simulado.

NodeContainer nodes;
nodes.Create (2);

Antaŭ ol ni daŭrigu, ni trovu la dokumentadon por la klaso NodeContainer. Alia maniero atingi la dokumentadon por difinita klaso estas per la langeto klasoj sur la paĝoj Doksigeno. Se vi jam havas Doxygen malfermita, simple rulumu ĝis la supro de la paĝo kaj elektu la langeton Klasoj. Vi devus vidi novan aron da langetoj, unu el kiuj estas listo de klasoj. Sub ĉi tiu langeto vi vidos liston de ĉiuj klasoj ns-3. Rulumu malsupren al ns3::NodeContainer. Kiam vi trovas klason, elektu ĝin por iri al la dokumentado por la klaso.

Kiel ni memoras, unu el niaj ŝlosilaj abstraktaĵoj estas la nodo. Ĝi reprezentas la komputilon al kiu ni aldonos aferojn kiel protokolajn stakojn, aplikojn kaj ekstercentrajn kartojn. Topologia asistanto NodeContainer provizas oportunan manieron krei, administri kaj aliri ajnajn objektojn nodo, kiun ni kreas por ruli la simuladon. La unua linio supre simple deklaras NodeContainer, kiujn ni nomas nodoj. La dua linio nomas la Krei-metodon sur la nodoj objekto kaj petas la ujon krei du nodojn. Kiel priskribite en Doksigeno, la ujo petas la ns-3-sistemon krei du objektojn nodo kaj stokas montrilojn al ĉi tiuj objektoj interne.

La nodoj kreitaj en la skripto ankoraŭ faras nenion. La sekva paŝo en konstruado de la topologio estas konekti niajn nodojn al la reto. La plej simpla formo de reto, kiun ni subtenas, estas punkto-al-punkta konekto inter du nodoj. Ni nun kreos tian konekton.

PointToPointHelper

Ni kreas punkto-al-punktan konekton uzante konatan ŝablonon, uzante topologian helpan objekton por fari la malaltnivelan laboron necesan por la konekto. Memoru, ke niaj du ŝlosilaj abstraktaĵoj NetDevice и kanalo. En la reala mondo, ĉi tiuj terminoj proksimume egalrilatas al ekstercentraj kartoj kaj retaj kabloj. Tipe, ĉi tiuj du aferoj estas proksime rilataj unu al la alia, kaj neniu povas fidi kunhavigi, ekzemple, aparatojn. ethernet tra sendrata kanalo. Niaj topologiaj helpantoj sekvas ĉi tiun proksiman rilaton kaj tial vi uzos ununuran objekton en ĉi tiu scenaro PointToPointHelper por starigi kaj konekti ns-3-objektojn PointToPointNetDevice и PointToPointChannel. La sekvaj tri linioj en la skripto:

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

Unua linio,

PointToPointHelper pointToPoint;

kreas ekzemplon de objekto sur la stako PointToPointHelper. De plej alta nivela vidpunkto la sekva linio,

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

diras la objekton PointToPointHelper uzu la valoron "5 Mbit/s" (kvin megabitoj sekundo) kiel "DataRate".

De pli specifa vidpunkto, la ĉeno "DataRate" respondas al tio, kion ni nomas atributo PointToPointNetDevice. Se vi rigardas Doksigeno por klaso ns3::PointToPointNetDevice kaj en la dokumentado por la metodo GetTypeId vi trovos liston de atributoj difinitaj por la aparato. Inter ili estos la atributo "DataRate" La plej multaj uzant-videblaj ns-3-objektoj havas similajn listojn de atributoj. Ni uzas ĉi tiun mekanismon por facile agordi la simuladon sen rekompilo, kiel vi vidos en la sekva sekcio.

Simila al "DataRate" en PointToPointNetDevice, vi trovos la "Prokrastan" atributon asociitan kun la PointToPointChannel. La fina linio

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

diras PointToPointHelper uzu la valoron "2 ms" (du milisekundoj) kiel la disvastigprokrastan valoron por la punkto-al-punkta ligo kiun ĝi poste kreas.

NetDeviceContainer

Nuntempe ni havas en la skripto NodeContainer, kiu enhavas du nodojn. Ni havas PointToPointHelper, kiu estas preta por krei objektojn PointToPointNetDevices kaj konekti ilin uzante PointToPointChannel objekto. Same kiel ni uzis la NodeContainer-topologian helpan objekton por krei nodojn, ni demandos PointToPointHelper plenumi laboron por ni rilate al la kreado, agordo kaj instalado de niaj aparatoj. Ni bezonas liston de ĉiuj kreitaj objektoj NetDevice, do ni uzas NetDeviceContainer konservi ilin same kiel ni uzis NodeContainer por konservi la nodojn, kiujn ni kreis. La sekvaj du linioj de kodo,

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

kompleta aparato kaj kanala agordo. La unua linio deklaras la aparato-ujon menciitan supre, kaj la dua faras la ĉefan laboron. Metodo instali objekto PointToPointHelper prenas NodeContainer kiel parametro. Interne NetDeviceContainer por ĉiu nodo situanta en NodeContainer estas kreita (por punkto-al-punkta komunikado devas ekzakte du el ili) PointToPointNetDevice estas kreita kaj konservita en la aparato-ujo. PointToPointChannel estas kreita kaj du estas ligitaj al ĝi PointToPointNetDevices. Post kreado de objektoj, la atributoj stokitaj en PointToPointHelper, estas uzataj por pravalorigi la respondajn atributojn en la kreitaj objektoj.

Post voko pointToPoint.Install (nodoj) ni havos du nodojn, ĉiu kun punkt-al-punkta ret-aparato instalita kaj unu punkt-al-punkta ligo inter ili. Ambaŭ aparatoj estos agorditaj por transdoni datumojn kun rapideco de kvin megabitoj je sekundo kun transdono prokrasto de du milisekundoj super la kanalo.

InternetStackHelper

Ni nun havas nodojn kaj aparatojn agorditaj, sed niaj nodoj ne havas protokolajn stakojn instalitajn. La sekvaj du linioj de kodo zorgos pri tio.

InternetStackHelper stack;
stack.Install (nodes);

InternetStackHelper - estas topologia helpanto por Interretaj stakoj, simila al PointToPointHelper por punkt-al-punktaj retaj aparatoj. Metodo instali prenas NodeContainer kiel parametron. Kiam ekzekutita, ĝi instalos la Interretan stakon (TCP, UDP, IP, ktp.) sur ĉiu ujo-nodo.

IPv4 AddressHelper

Tiam ni devas asocii niajn aparatojn kun IP-adresoj. Ni provizas topologian asistanton por administri IP-adreson. La nura API videbla por la uzanto estas agordi la bazan IP-adreson kaj retan maskon por uzi dum la reala adresdistribuo (ĉi tio estas farita ĉe pli malalta nivelo ene de la helpanto). La sekvaj du linioj de kodo en nia ekzempla skripto unue.cc,

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

deklaru la adreshelpan objekton kaj diru al ĝi, ke ĝi devus komenci asigni IP-adresojn de reto 10.1.1.0, uzante la 255.255.255.0 bitmaskon por determini. Defaŭlte, asignitaj adresoj komenciĝos je unu kaj pliiĝos monotone, do la unua adreso asignita de ĉi tiu bazo estos 10.1.1.1, poste 10.1.1.2, ktp. En realeco, je malalta nivelo, la sistemo ns-3 memoras ĉiujn asignitajn IP-adresojn kaj generas fatalan eraron se vi hazarde kreas situacion, kie la sama adreso estas generita dufoje (cetere, ĉi tiu eraro estas malfacile elpurigebla).

La sekva linio de kodo,

Ipv4InterfaceContainer interfaces = address.Assign (devices);

plenumas la realan adresasignon. En ns-3 ni establas konekton inter IP-adreso kaj aparato uzanta la objekton IPv4-Interfaco. Same kiel ni foje bezonas liston de retaj aparatoj kreitaj de la asistanto por posta uzo, ni foje bezonas liston de objektoj IPv4-Interfaco. IPv4InterfaceContainer provizas ĉi tiun funkcion.

Ni konstruis punkton-al-punktan reton, kun stakoj instalitaj kaj IP-adresoj asignitaj. Nun ni bezonas aplikojn en ĉiu nodo por generi trafikon.

4.2.7 Uzado de Apliko

Alia el la ĉefaj abstraktaĵoj de la sistemo ns-3 estas Apliko (aplikaĵo). En ĉi tiu scenaro ni uzas du bazklasajn specialiĝojn Apliko ns-3 vokis UdpEchoServerApplication и UdpEchoClientApplication. Kiel en antaŭaj kazoj, ni uzas helpajn objektojn por agordi kaj administri la bazajn objektojn. Ĉi tie ni uzas UdpEchoServerHelper и UdpEchoClientHelper objektoj por faciligi nian vivon.

UdpEchoServerHelper

La sekvaj linioj de kodo en nia unua.cc-ekzempla skripto estas uzataj por agordi aplikaĵon de UDP-eĥa servilo sur unu el la nodoj, kiujn ni kreis antaŭe.

UdpEchoServerHelper echoServer (9);

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

La unua linio de kodo en la supra fragmento kreas UdpEchoServerHelper. Kiel kutime, ĉi tio ne estas aplikaĵo mem, ĝi estas objekto, kiu helpas nin krei realajn aplikojn. Unu el niaj konvencioj estas transdoni la postulatajn atributojn al la konstrukciisto de la helpa objekto. En ĉi tiu kazo, la helpanto ne povas fari ion utilan krom se ĝi ricevas la havennumeron sur kiu la servilo aŭskultos por pakaĵoj, ĉi tiu nombro ankaŭ devas esti konata al la kliento. En ĉi tiu kazo, ni transdonas la pordan numeron al la helpa konstrukciisto. La konstrukciisto, siavice, simple faras AgorduAtributon kun la pasita valoro. Poste, se vi volas, vi povas uzi SetAttribute por agordi malsaman valoron por la Port-atributo.

Kiel multaj aliaj helpaj objektoj, la objekto UdpEchoServerHelper havas metodon instali. Plenumante ĉi tiun metodon efike kreas bazan eĥservilan aplikaĵon kaj ligas ĝin al la gastiganto. Interese, la metodo instali prenas NodeContainer kiel parametro same kiel la aliaj instali metodoj, kiujn ni vidis.

La C++ implica konvertiĝo laboranta ĉi tie prenas la rezulton de la metodo nodo.Get(1) (kiu resendas inteligentan montrilon al la noda objekto - Ptr ) kaj uzas ĝin en la konstrukciisto por la anonima objekto NodeContainerkiu tiam estas pasita al la metodo instali. Se vi ne povas determini en C++-kodo kiu metodo subskribo estas kompilita kaj efektivigita, tiam rigardu inter la implicaj konvertiĝoj.

Nun ni vidas tion echoServer.Instali tuj instali la aplikaĵon UdpEchoServerApplication on trovita en NodeContainerkiun ni uzas por administri niajn nodojn, nodo kun indekso 1. Metodo instali resendos ujon kiu enhavas montrilojn al ĉiuj aplikoj (en ĉi tiu kazo unu, ĉar ni pasis anoniman NodeContainer, enhavanta unu nodon) kreita de la helpanto.

Aplikoj devas specifi kiam komenci generi trafikon "komenci" kaj eble bezonos aldone specifi tempon kiam haltigi ĝin "haltu". Ni provizas ambaŭ eblojn. Ĉi tiuj tempoj estas fiksitaj per la metodoj Aplikujo komenco и ĉesigi. Ĉi tiuj metodoj akceptas parametrojn de tipo tempo. En ĉi tiu kazo ni uzas eksplicitan sekvencon de C++-konvertoj por preni C++ duobla 1.0 kaj konvertu ĝin al tns-3 Time-objekto, kiu uzas la objekton Seconds por konverti al sekundoj. Memoru, ke la konvertaj reguloj povas esti kontrolitaj de la modelaŭtoro, kaj C++ havas siajn proprajn regulojn, do vi ne ĉiam povas kalkuli, ke la parametroj estas konvertitaj kiel vi atendis. Du linioj

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

kaŭzos la eĥservilan aplikaĵon komenci (aŭtomate ŝalti) unu sekundon post kiam la simulado komenciĝas kaj ĉesos (malŝalti) post dek sekundoj de la simulado. Pro la fakto, ke ni deklaris simulan eventon (aplika haltokazaĵo), kiu estos efektivigita en dek sekundoj, almenaŭ dek sekundoj da reto-operacio estos simulita.

UdpEchoClientHelper

Klienta aplikaĵo eĥo agordita en maniero preskaŭ simila al la servilo. Estas baza objekto UdpEchoClientApplication, kiu estas kontrolita
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));;

Tamen, por la eĥa kliento ni devas agordi kvin malsamajn atributojn. La unuaj du atributoj estas fiksitaj je kreotempo UdpEchoClientHelper. Ni pasas parametrojn, kiuj estas uzataj (interne de la helpanto) por agordi la atributojn "Malproksima Adreso" и "Fora Haveno" konforme al nia interkonsento transdoni la necesajn parametrojn al la helpa konstrukciisto.

Ni memoru, ke ni uzis IPv4InterfaceContainer spuri la IP-adresojn, kiujn ni asignis al niaj aparatoj. La nula interfaco en la interfaca ujo respondas al la IP-adreso de la nula nodo en la noda ujo. La unua interfaco en la interfaca ujo respondas al la IP-adreso de la unua nodo en la noda ujo. Do, en la unua linio de kodo (supre), ni kreas helpanton kaj diras al ĝi, ke la fora adreso de la kliento estos la IP-adreso asignita al la gastiganto, kie troviĝas la servilo. Ni ankaŭ diras, ke ni devas aranĝi ke pakaĵetoj estu senditaj al haveno naŭ.

La atributo "MaxPackets" diras al la kliento la maksimuman nombron da pakoj, kiujn ni povas sendi dum la simulado. La "Intervalo" atributo rakontas al la kliento kiom longe atendi inter pakaĵetoj, kaj la "PacketSize" atributo rakontas al la kliento kiom granda la pakaĵeto devus esti. Kun ĉi tiu atributkombinaĵo ni diras al la kliento sendi ununuran 1024-bajtan paketon.

Kiel ĉe la eĥservilo, ni starigas la atributojn de la eĥa kliento komenco и ĉesigi, sed ĉi tie ni komencas la klienton sekundon post kiam la servilo estas ŝaltita (du sekundoj post la komenco de la simulado).

4.2.8 Simulilo

Je ĉi tiu punkto ni devas ruli la simuladon. Ĉi tio estas farita uzante la tutmondan funkcion Simulator::Run.

Simulator::Run ();

Kiam ni antaŭe nomis metodojn,

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

ni efektive planis eventojn en la simulilo je 1,0 sekundoj, 2,0 sekundoj, kaj du eventojn je 10,0 sekundoj. Post la voko Simulator::Run, la sistemo komencos vidi la liston de planitaj eventoj kaj ekzekuti ilin. Ĝi unue lanĉos eventon post 1,0 sekundoj, kiu ekigos la eĥservilan aplikaĵon (ĉi tiu evento povas siavice plani multajn aliajn eventojn). Ĝi tiam lanĉos eventon planitan je t=2,0 sekundoj, kiu lanĉos la eĥan klientan aplikaĵon. Denove, ĉi tiu evento eble havas multajn pliajn eventojn planitaj. La komenca evento-efektivigo en la eĥkliento komencos la datumtransigan fazon de la simulado sendante pakaĵeton al la servilo.

La ago sendi paketon al la servilo ekigos ĉenon de eventoj, kiuj estos aŭtomate planitaj malantaŭ la scenoj kaj kiuj efektivigos la mekanikon sendi eĥan paketon laŭ la tempaj parametroj, kiujn ni starigis en la skripto.

Kiel rezulto, ĉar ni sendas nur unu paketon (memoru, la atributon Maksimumaj Pakoj estis agordita al unu), la ĉeno de eventoj komencitaj de ĉi tiu ununura kliento-pingo finiĝos kaj la simulado iros en standby-reĝimon. Post kiam tio okazas, la ceteraj planitaj eventoj estos la eventoj ĉesigi por servilo kaj kliento. Kiam ĉi tiuj eventoj estas efektivigitaj, ne restos eventoj por plua prilaborado kaj Simulator::Run redonos kontrolon. La simulado estas kompleta.

Restas nur purigi post vi mem. Ĉi tio estas farita per vokado de la tutmonda funkcio Simulilo::Detruu. Ĉar la helpaj funkcioj (aŭ malaltnivela ns-3-kodo) estis nomitaj, kiuj estas organizitaj tiel ke hokoj estis enigitaj en la simulilon por detrui ĉiujn objektojn kiuj estis kreitaj. Vi ne bezonis mem spuri iun ajn el ĉi tiuj objektoj - vi nur devis telefoni Simulilo::Detruu kaj eliru. La sistemo ns-3 faros ĉi tiun malfacilan laboron por vi. La ceteraj linioj de nia unua ns-3-skripto, first.cc, faras ĝuste tion:

Simulator::Destroy ();
return 0;
}

Kiam la simulilo ĉesos?

ns-3 estas diskreta evento (DE) simulilo. En tia simulilo, ĉiu okazaĵo estas rilata al sia ekzekuttempo, kaj la simulado daŭras prilaborante okazaĵojn en la sinsekvo kiam ili okazas kiam la simulado progresas. Okazaĵoj povas kaŭzi estontajn eventojn esti planitaj (ekzemple, tempigilo povas postdatigi sin por fini kalkuli en la sekva intervalo).

Komencaj eventoj estas kutime iniciatitaj de la ento, ekzemple IPv6 planos la malkovron de servoj en la reto, najbarpetoj, ktp. La aplikaĵo planas la unuan pakaĵetan eventon, ktp. Kiam okazaĵo estas prilaborita, ĝi povas generi nul, unu aŭ pli da eventoj. Ĉar la simulado progresas, okazaĵoj okazas, aŭ finiĝante aŭ kreante novajn. La simulado ĉesos aŭtomate se la eventovico estas malplena aŭ speciala evento estas detektita ĉesigi. Evento ĉesigi generita de la funkcio Simulilo::Haltu (haltu tempon).

Estas tipa kazo kie Simulator::Stop estas nepre necesa por ĉesigi la simuladon: kiam estas memsubtenaj eventoj. Memsubtenaj (aŭ ripetaj) okazaĵoj estas eventoj, kiuj ĉiam estas postdatigitaj. Sekve, ili ĉiam tenas la eventovicon ne malplena. Estas multaj protokoloj kaj moduloj enhavantaj ripetantajn eventojn, ekzemple:

• FlowMonitor - perioda kontrolado por perditaj pakoj;

• RIPng - perioda elsendo de ĝisdatigoj de vojtabelo;

• ktp.

En tiaj kazoj Simulilo::Haltu necesas por ĉesigi la simuladon ĝuste. Aldone, kiam ns-3 estas en emuladreĝimo, la RealtimeSimulator estas uzata por sinkronigi la simulan horloĝon kun la maŝinhorloĝo, kaj Simulilo::Haltu necesa por ĉesigi la procezon.

Multaj el la simuladprogramoj en la lernolibro ne vokas Simulilo::Haltu eksplicite, ĉar ili finiĝas aŭtomate kiam la vicigitaj eventoj estas elĉerpitaj. Tamen ĉi tiuj programoj ankaŭ akceptos la Simulilon::Haltvokon. Ekzemple, la sekva kroma deklaro en la unua ekzempla programo planus eksplicitan halton je 11 sekundoj:

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

Ĉi-supra ne efektive ŝanĝos la konduton de ĉi tiu programo, ĉar ĉi tiu aparta simulado nature finiĝas post 10 sekundoj. Sed se vi ŝanĝus la halttempon en la supra deklaro de 11 sekundoj al 1 sekundo, vi rimarkus, ke la simulado ĉesas antaŭ ol iu ajn eligo trafas la ekranon (ĉar la eligo okazas post ĉirkaŭ 2 sekundoj da simulada tempo).

Gravas voki Simulator::Haltu antaŭ ol voki Simulator::Run; alie Simulator::Run eble neniam resendi kontrolon al la ĉefa programo por efektivigi la halton!

4.2.9 Konstruante vian skripton

Ni faris la kreadon de viaj simplaj skriptoj bagatela. Ĉio, kion vi devas fari, estas meti vian skripton en la scratch-dosierujon kaj ĝi estos aŭtomate konstruita se vi kuras Waf. Ni provu. Reiru al la supra nivela dosierujo kaj kopiu ekzemploj/lernilo/unua.cc al la katalogo nenio

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

Nun konstruu vian unuan specimenan skripton uzante waf:

$ ./waf

Vi devus vidi mesaĝojn indikante ke via unua ekzemplo estis kreita sukcese.

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)

Nun vi povas ruli la ekzemplon (notu, ke se vi konstruas vian programon en la scratch dosierujo, tiam vi devas ruli ĝin de nenio):

$ ./waf --run scratch/myfirst

Vi devus vidi similan eligon:

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

Ĉi tie vi povas vidi, ke la konstrusistemo kontrolas, ke la dosiero estis konstruita kaj poste rulas ĝin. Vi vidas, ke la kompona eniro sur la eĥa kliento indikas, ke ĝi sendis ununuran 1024-bajtan pakaĵon al eĥa servilo 10.1.1.2. Vi ankaŭ vidas la registradan komponenton sur la eĥservilo por diri, ke ĝi ricevis 1024 bajtojn de 10.1.1.1. La eĥservilo silente reludas la pakaĵeton kaj vi povas vidi en la protokolo de la eĥa kliento, ke ĝi ricevis sian pakaĵon reen de la servilo.

4.3 ns-3 Fontkodo

Nun kiam vi uzis iujn el la ns-3-helpiloj, vi povas rigardi iujn el la fontkodo, kiu efektivigas ĉi tiun funkcion. La plej nova kodo videblas ĉe nia retservilo ĉe la sekva ligo: https://gitlab.com/nsnam/ns-3-dev.git. Tie vi vidos la resuman paĝon de Mercurial por nia disvolva arbo ns-3. Ĉe la supro de la paĝo vi vidos plurajn ligilojn,

summary | shortlog | changelog | graph | tags | files

Iru antaŭen kaj elektu la dosierojn ligon. Jen kiel aspektos la plej alta nivelo de la plej multaj el niaj deponejoj:

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

Niaj ekzemplaj skriptoj estas en la dosierujo ekzemploj. Se vi alklakas la ekzemplojn vi vidos liston de subdosierujoj. Unu el la dosieroj en la subdosierujo lernilo - first.cc. Se vi klakas sur unue.cc vi vidos la kodon, kiun vi ĵus lernis.

La fontkodo ĉefe troviĝas en la dosierujo src. Vi povas vidi la fontkodon alklakante la dosierujon aŭ alklakante la dosierligon dekstre de la dosierujo. Se vi alklakas la src-dosierujon, vi ricevos liston de src-subdosierujoj. Se vi tiam alklakas la kerna subdosierujo, vi trovos liston de dosieroj. La unua dosiero, kiun vi vidos (en la momento de verkado de ĉi tiu gvidilo) estas aborti.h. Se vi alklakas la ligilon aborti.h, vi estos sendita al la fontdosiero por aborti.h, kiu enhavas utilajn makroojn por eliri skriptojn se nenormalaj kondiĉoj estas detektitaj. La fontkodo por la helpantoj, kiujn ni uzis en ĉi tiu ĉapitro, troviĝas en la dosierujo src/Aplikoj/helpilo. Bonvolu trarigardi la dosierujon por ekscii, kio estas kie kaj kompreni la stilon de ns-3-programoj.

fonto: www.habr.com

Aldoni komenton