
4 Koncepció áttekintése
4.1 Kulcsfontosságú absztrakciók
4.1.1 Csomópont (Node)
4.1.2 Alkalmazás (Application)
4.1.3 Csatorna (Channel)
4.1.4 Hálózati eszköz (Net Device)
4.1.5 Topológiai segítők
4.2 Első ns-3 szkript
4.2.1 Alap kód
4.2.2 Bekapcsolható modulok
4.2.3 ns3 névtér
4.2.4 Naplózás
4.2.5 Fő függvény
4.2.6 Topológiai segítők használata
4.2.7 Alkalmazás használata
4.2.8 Szimulátor
4.2.9 Az Ön forgatókönyvének összeállítása
4.3 ns-3 Forráskód
4. fejezet
Koncepció áttekintése
Első lépésként, mielőtt elkezdenénk a ns-3 kód írását vagy tanulmányozását, magyarázzunk el néhány alapvető fogalmat és absztrakciót a rendszerben. Sokak számára ez nyilvánvalónak tűnhet, de javasoljuk, hogy szánjon időt ennek a résznek az elolvasására, hogy biztos legyen abban, hogy szilárd alapokra építkezik.
4.1 Kulcsfontosságú absztrakciók
Ebben a részben áttekintjük azokat a kifejezéseket, amelyeket általában a hálózatban használnak, de a ns-3-ban különös jelentéssel bírnak.
4.1.1 Csomópont (Node)
Az internetes zsargonban a számítógép, amely csatlakozik a hálózathoz, hosztnak vagy néha végső rendszernek nevezzük. Mivel a ns-3 hálózati szimulátor, és nem internet szimulátor, szándékosan nem használjuk a hoszt kifejezést, mivel ez szorosan kapcsolódik az internethez és protokolljaihoz. Ehelyett egy általánosabb kifejezést használunk, amelyet más szimulátorok is alkalmaznak, és amely a gráfelméletből származik - csomópont (Node)node).
A ns-3-ban a számítógépes eszköz alapvető absztrakciója csomópontnak (Node) nevezzük. Ezt az absztrakciót a C++ Node osztály reprezentálja. Csomópont (Node) Az osztály módszereket biztosít a számítógépes eszközök szimulációkban való megjelenítésének kezelésére.
Meg kell értenie Node mint egy számítógép, amelyhez funkciókat fog hozzáadni. Olyan dolgokat fog hozzáadni, mint az alkalmazások, protokolltömbök és perifériakártyák illesztőprogramokkal, amelyek lehetővé teszik a számítógép számára, hogy hasznos munkát végezzen. Ugyanezt az alapvető modellt használjuk a ns-3-ban.
4.1.2 Alkalmazás (Application)
Általában a számítógépes szoftver két széles kategóriára osztható. A rendszer szoftver különböző számítógépes erőforrásokat, mint például a memóriát, a processzor ciklusait, a lemezt, a hálózatot stb., szervez egy bizonyos számítási modell szerint. A rendszer szoftver általában nem használja ezeket az erőforrásokat olyan feladatok végrehajtására, amelyek közvetlen előnyöket nyújtanak a felhasználónak. A felhasználó egy meghatározott cél eléréséhez általában elindít egy alkalmazást, amely megszerzi és felhasználja a rendszer szoftver által vezérelt erőforrásokat.
Gyakran a határvonal a rendszer- és az alkalmazás szoftver között a privilégiumok szintjének megváltozásánál húzódik, amely a operációs rendszer hívásaiban történik. Az ns-3-ban nincs igazi operációs rendszer fogalom, és ennek megfelelően nincs privilégiumszintek vagy rendszerhívások fogalma. Van azonban egy alkalmazás ötletünk. Akárcsak a "valós világban", az alkalmazási szoftverek feladatok végrehajtására számítógépeken működnek, az ns-3 alkalmazások az ns-3 csomópontoknál futnak a szimulált világban végzett szimulációk irányítására.
Az ns-3-ban a felhasználói program alapvető absztrakciója, amely valamilyen aktivitást generál a modellezéshez, az alkalmazás. Ezt az absztrakciót a C++ Application (alkalmazás) osztálya képviseli. Az Application osztály módszereket biztosít a szimulációkban a felhasználói szintű alkalmazások verzióinak kezelése érdekében. A fejlesztőktől elvárják, hogy új alkalmazások létrehozásához specializálják az Application osztályt a objektum-orientált programozás értelemében. Ebben az útmutatóban az Application osztály specializációit fogjuk használni, amelyeket nevezünk UdpEchoClientApplication és UdpEchoServerApplication. Ahogy vártuk, ezek az alkalmazások egy ügyfél/szerver alkalmazásokból álló készletet képviselnek, amelyeket hálózati csomagok generálására és eho-szimulációkra használnak.
4.1.3 Csatorna (Channel)
A valós világban számítógépet lehet csatlakoztatni egy hálózathoz. Gyakran a hálózatokban az adatok átvitelére használt környezeteket csatornáknak nevezik. Amikor Ethernet kábelt dugunk a falban lévő aljzatba, a számítógépet az Ethernet kommunikációs csatornához kapcsoljuk. A modellezett világban az ns‑3 csomópont csatlakozik egy objektumhoz, amely a kommunikációs csatornát képviseli. Itt a kommunikációs alhálózat fő absztrakciója csatorna, amelyet a C++ Channel (csatorna) osztály képvisel.
Osztály CsatornaCsatorna metódusokat biztosít az alhálózat objektumai közötti interakció kezelésére és a csomópontokhoz való csatlakozásra. A csatornákat a fejlesztők objektumorientált programozás szempontjából is specializálhatják. A csatorna specializáció modellálhat valami egyszerűt, mint egy vezeték. A specializált csatorna olyan bonyolult dolgokat is modellezhet, mint egy nagy Ethernet switch vagy egy háromdimenziós tér, tele akadályokkal vezeték nélküli hálózatok esetén.
Ebben az útmutatóban speciális csatorna verziókat fogunk használni, amelyeket CsmaChannelCsmaChannel, PointToPointChannelPointToPointChannel és WifiChannelWifiChannel. CsmaChannel, például, modelláz egy olyan kommunikációs alhálózat verziót, amely megvalósítja a hordozó-vezérlős több hozzáférésű kommunikációs környezetet. Ez Ethernet-szerű funkcionalitást biztosít számunkra.
4.1.4 Hálózati eszköz (Net Device)
Régen, ha számítógépet akartál csatlakoztatni a hálózathoz, meg kellett vásárolnod egy bizonyos hálózati kábelt és egy hardveres eszközt, amelyet (PC terminológiában) perifériás kártyának neveztek, és amelyet be kellett építeni a számítógépbe. Ha a perifériás kártyán néhány hálózati funkció valósult meg, akkor azt hálózati interfész kártyáknak vagy hálózati kártyáknak nevezték. Ma a legtöbb számítógép beépített hálózati interfész hardverrel érkezik, és a felhasználók nem tekintik őket külön eszközökként.
A hálózati kártya nem fog működni anélkül, hogy egy programozási illesztőprogram irányítsa a hardverét. Unix-ban (vagy Linux-ban) a perifériás eszközök része device-ként kategorizálódik. Az eszközöket eszközillesztők (device drivers) vezérlik, és a hálózati eszközök (NIC) a hálózati eszközillesztők révén (hálózati eszközillesztők) és összegyűjtő néven hálózati eszközöknek (hálózati eszközök). Unix és Linux rendszereken a hálózati eszközökhöz olyan neveken keresztül férhet hozzá, mint például eth0.
Az ns-3-ban a hálózati eszköz absztraktja magában foglalja mind a szoftveres meghajtót, mind a modellezett hardvert. A szimuláció során a hálózati eszköz „telepítve” van egy csomópontban, lehetővé téve számára, hogy kapcsolatba lépjen más csomópontokkal csatornákon keresztül. Mint egy valódi számítógép esetében, a csomópont több csatornához is csatlakozhat több eszközön keresztül NetDevices.
A hálózati eszköz absztrakcióját a C++ osztály képviseli NetDevice. Az osztály NetDevice módszereket biztosít a Node és Channel objektumokkal való kapcsolatok kezelésére; és a fejlesztők az objektum-orientált programozás szempontjából specializálhatják azokat. Ebben a útmutatóban néhány specializált NetDevice verziót fogunk használni, amelyek nevei CsmaNetDevice, PointToPointNetDevice és WifiNetDevice. Akárcsak az Ethernet hálózati adaptert a hálózathoz való kapcsolódásra tervezték, Ethernet, CsmaNetDevice az a CsmaChannel, PointToPointNetDevice az a PointToPointChannel, és WifiNetDevice — az a WifiChannel.
4.1.5 Topológiai segítők
Egy valódi hálózatban host számítógépeket fog találni, kiegészítő (vagy beépített) hálózati kártyákkal. Az ns-3-ban azt mondanánk, hogy csomópontokat fog látni csatlakoztatott NetDevices-szal. Egy nagyobb modellezett hálózatban kapcsolatok kialakítására lesz szüksége sok objektum között Node, NetDevice és Csatorna.
Mivel a NetDevices csomópontokhoz, a NetDevices csatornákhoz való csatlakoztatása, IP-címek hozzárendelése stb. az ns-3-ban általános feladat, ezért annak érdekében, hogy ezt a lehető legegyszerűbben végezhessük, úgynevezett topológiai segédprogramokat biztosítunk. Például egy NetDevice létrehozásához számos ns-3 alapműveletet kell végrehajtani, MAC-címet kell hozzáadni, ezt a hálózati eszközt a Node-ra kell helyezni, be kell állítani a csomópont protokoll veremét, majd csatlakoztatni a NetDevice-ot a Channel-hez. Még több művelet lesz szükséges ahhoz, hogy több eszközt csatlakoztasson többszörös csatornákhoz, majd az egyes hálózatokat egyesítse egy hálózattá (Internetworks). Olyan segédobjektumokat biztosítunk, amelyek az Ön kényelme érdekében egyesítik ezeket a számos műveletet egy könnyen használható modellbe.
4.2 Első ns-3 szkript
Ha a rendszert a fent ajánlott módon telepítette, az ns-3 kiadása a repos nevű könyvtárban lesz az otthoni könyvtárában. Lépjen a könyvtárba release
Ha nincs ilyen könyvtár, akkor a ns-3 kiadási verziójának összeállításakor nem adta meg a kimeneti könyvtárat, hajtsa végre az építést így:
$ . /waf configure —build-profile=release —out=build/release,
$ . /waf build
itt látnod kell egy mappa struktúrát, ami hasonlít a következőre:
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.pycLépjen be a könyvtárba examples/tutorial. Ott kell látnia egy fájlt, aminek a neve first.cc. Ez egy szkript, ami létrehoz egy egyszerű pont-pont kapcsolatot két csomópont között, és egy csomagot továbbít a csomópontok között. Nézzük meg ezt a szkriptet soronként, nyissuk meg a first.cc fájlt a kedvenc szerkesztőnkben.
4.2.1 Alap kód
A fájl első sora az editor módja ) és ha fejlesztési tárolókat használnak, a verzióellenőrző rendszerek Git. A legtöbb kezdő felhasználónak nem kell aggódnia, ha a konfigurációja hiányzó ns-3 funkciókat jelez, de azok számára, akik teljes telepítést szeretnének, a projekt egy wikivel is rendelkezik, amely hasznos tanácsokat és útmutatásokat tartalmaz. Az egyik ilyen oldal az „Installáció” oldal, amely telepítési utasításokat tartalmaz különböző rendszerekhez, elérhető a következő címen:. Ez közli az emacs-szal a formázási konvenciókat (kódolási stílus), amelyeket használni fogunk a forráskódunkban.
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */Ez mindig elég vitatott kérdés, ezért tisztáznunk kell, hogy ezt azonnal eltávolítsuk az útból. Az ns-3 projekt, mint a legtöbb nagyobb projekt, elfogadta a kódolási stílust, amelynek meg kell felelnie az összes megadott kódnak. Ha szeretné a kódját beilleszteni a projektbe, végül meg kell felelnie az ns-3 kódolási standardnak, ahogy azt a doc/codingstd.txt fájlban vagy a projekt weboldalán bemutatják: .
Javasoljuk, hogy szokja meg az ns-3 kódját és alkalmazza ezt a standardot, valahányszor a kódunkkal dolgozik. Az összes fejlesztő és együttműködő egyetértett ezzel, némi morgás után. A fenti emacs mód sora megkönnyíti a helyes formázást, ha az emacs szerkesztőt használja.
Az ns-3 szimulátor a GNU Általános Nyilvános Licenc alatt van. Minden ns-3 terjesztési fájlban láthatja a megfelelő jogi fejlécet. Gyakran láthat egy szerzői jogi értesítést egy olyan intézményről, amely részt vesz az ns-3 projektben, a GPL szövege és az alábbi szerző neve fölött.
/*
* 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 Bekapcsolható modulok
A tényleges kód egy sor #include direktívával kezdődik (include).
#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"A nagy szintű szkriptek felhasználóinak segítése érdekében az összes fejléct fájl összegyűjtésére, amelyek a rendszerben jelen vannak, azokat az összehasználásuk szerint nagy modulokba csoportosítjuk. Egy olyan fejlécet biztosítunk, amely rekurszívan betölti az adott modulban használt összes fejléc fájlt. Ahelyett, hogy megpróbálná kitalálni, melyik fejlécet keres, és esetleg megfelelő függőségeket keresne, lehetőséget adunk arra, hogy csoportosan tölthesse le a fájlokat, nagy részletességgel. Ez nem a leghatékonyabb megközelítés, de kétségtelenül megkönnyíti a szkriptek írását.
Minden egyes belső fájl, amely az ns-3-ba be van ágyazva, a következő mappába kerül, amelynek neve ns3 (a fordítási alkönyvtár), hogy elkerülje a fájlnevek ütközését a fordítási folyamat során. A fájl ns3/core-module.h a ns-3 modulnak felel meg, amit a következő könyvtárban talál meg: src/core a telepített verzióban. E könyvtár listájában számos fejlécfájlt fog találni. Amikor fordít, Waf a nyilvános fejléc fájlokat a ns3 mappába helyezi a következő alkönyvtárba: build/debug
Ha nincs ilyen könyvtár, akkor a ns-3 kiadási verziójának összeállításakor nem adta meg a kimeneti könyvtárat, hajtsa végre az építést így:
$ ./waf configure —build-profile=debug —out=build/debug
$ . /waf build
vagy
$ ./waf configure —build-profile=optimized —out=build/optimized
$ . /waf build
vagy build/optimized, a konfigurációjától függően. Waf Automatikusan generál egy modulpéldányt is, amely az összes nyilvános fejlécfájlt betölti. Mivel természetesen szigorúan követi ezt az útmutatót, már végrehajtotta
$ ./waf -d debug --enable-examples --enable-tests configurehogy beállítsa a projektet a példák és tesztek belefoglalását lehetővé tevő hibakeresési fordításokra. Ön azt is megcsinálta,
$ . /wafhogy összeállítsa a projektet. Így most, amikor megnézi a könyvtárt ../..../build/debug/ns3, ott, többek között, megtalálja a fent említett négy modul fejlécfájlait. Megnézheti ezen fájlok tartalmát, és észreveheti, hogy mindegyik tartalmazza a megfelelő modulok által használt összes nyilvános fájlt.
4.2.3 ns3 névtér
A következő sor a szkripten first.cc az űrtartalom bejelentése.
using namespace ns3;Az ns‑3 projekt a C++ névtérben valósult meg, amely ns3 néven ismert. Ez csoportosítja az összes ns‑3-hoz kapcsolódó deklarációt a globális névtér láthatóságán kívül, ami, reméljük, segít az integrációban más kódokkal. A C++ operátor használata az ns‑3 névteret a jelenlegi (globális) deklaratív régióba vezeti be. Ez egy furcsa módja annak, hogy elmondjuk, hogy a deklaráció után nem kell használni az ns3 :: scope határozó operátort minden ns‑3 kód esetében. Ha nem ismeri a névtereket, bármely C++ tankönyvben megtalálja őket, és összehasonlíthatja az ns3 névteret a std névtér használatával és deklarációjával. using namespace std; a kimeneti operátorral kapcsolatos példákban cout és áramlások.
4.2.4 Naplózás
A következő sor a szkriptekben:
NS_LOG_COMPONENT_DEFINE ("FirstScriptExample");Ezt az állítást kényelmes helyként fogjuk használni a dokumentációs rendszerünk megbeszélésére. Doxygen. Ha megnézi az ns‑3 projekt weboldalát, talál egy "Dokumentáció" (Documentation) hivatkozást a navigációs sávon. Ha ezt a hivatkozást választja, a dokumentációs oldalunkra kerül. Van egy hivatkozás az "Utolsó kiadás"-ra, amely a legutolsó stabil ns‑3 verzió dokumentációjához vezet. Ha az "API Documentation" hivatkozást választja, az ns‑3 API dokumentációs oldalára irányítják.
Az oldal bal oldalán talál egy grafikus ábrázolást a dokumentáció struktúrájáról. Jó hely a kezdéshez a ns‑3 Modules "könyve" az ns‑3 navigációs fában. Ha kibővíti Modulok, láthatja az ns‑3 modulok dokumentációs listáját. Ahogy fent említettük, a modul fogalma közvetlenül kapcsolódik a fenti modul fájlokhoz. Az ns‑3 naplózó (loggoló) alrendszerét a Naplózó modul használata, így később visszatérünk rá ebben az útmutatóban, de a fent említett állításhoz kapcsolódóan a Mag, majd nyissa meg a "könyv"-et Debugging tools, majd válassza a Loggingoldalt. Kattintson Logging.
Most át kell néznie a dokumentációt Doxygen a modulhoz Logging. A list of macros at the top of the page will show you the entry for NS_LOG_COMPONENT_DEFINE. Before clicking the link, make sure to check the "Detailed Description" of the logging module to understand its overall functionality. You can do this by scrolling down or by selecting "More..." below the diagram.
Once you have a general understanding of what is happening, continue and take a look at the documentation for the specific NS_LOG_COMPONENT_DEFINE. I won't duplicate the documentation here, but to summarize, this line declares a logging component named FirstScriptExample, which allows you to enable and disable console logging of messages linked to the name.
4.2.5 Fő függvény
In the following lines of the script, you will see
int
main (int argc, char *argv[])
{ This is simply the declaration of the main function of your program (script). As with any C++ program, you need to define the main function, which runs first. There’s nothing special about it. Your ns-3 script is just a C++ program. The next line sets the time resolution to 1 nanosecond, which is the default value:
Time::SetResolution (Time::NS);Time resolution, or simply resolution, is the smallest time value that can be used (the smallest representable difference between two time values). You can change the resolution only once. The mechanism that provides this flexibility consumes memory, so once the resolution is explicitly set, we free the memory to prevent further updates. (If you do not explicitly set the resolution, it defaults to one nanosecond, and the memory will be freed at the start of the simulation.)
The next two lines of the script are used to enable two logging components that are built into the applications EchoClient és EchoServer:
LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO); LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO);Ha elolvasta a Logging komponens dokumentációját, láthatja, hogy több részletességi szint létezik, amelyet engedélyezhet minden komponens számára. Ezek a két sor kód lehetővé teszi a debug naplózást INFO szintre az echo klienseknél és szervereknél. Ezen a szinten az alkalmazás a modellezés során üzeneteket fog nyomtatni, amikor csomagokat küld vagy fogad.
Most közvetlenül rátérünk a topológia létrehozására és a szimuláció elindítására. A topológiai segédobjektumokat fogjuk használni, hogy ezt a munkát a lehető legegyszerűbbé tegyük.
4.2.6 Topológiai segítők használata
A következő két sor kód a szkriptünkben valójában létre fog hozni ns-3 Node objektumokat, amelyek a szimulációban számítógépeket képviselnek.
NodeContainer nodes;
nodes.Create (2);Mielőtt folytatnánk, keressük meg a NodeContainerosztály dokumentációját. Egy másik módja a dokumentáció elérésének az adott osztály számára a Classes fülön keresztül Doxygen. Ha már megnyitotta a Doxygen-t, egyszerűen görgessen vissza az oldal tetejére, és válassza a Classes fület. Látni fog egy új fülsort, amelyből az egyik az osztályok listáját tartalmazza. E fül alatt láthatja az összes ns-3 osztályt. Görgessen lefelé, amíg el nem éri a ns3 :: NodeContainer. Amikor megtalálta az osztályt, válassza ki azt, hogy átadja a dokumentációt az osztályhoz.
Ahogy emlékszünk, a kulcsfontosságú absztrakcióink egyike a csomópont. Ez képviseli azt a számítógépet, amelyhez olyan dolgokat fogunk hozzáadni, mint például protokolltartalmak, alkalmazások és perifériás kártyák. A topológiai segéd NodeContainer kellemes módot biztosít a létrehozott, kezelt és elérhetővé tett objektumokhoz, Nodeamelyeket a szimuláció futtatásához készítünk. Az első sor feljebb egyszerűen deklarálja a NodeContainerváltozót, amelyet nodes-nak nevezünk. A második sor meghívja a Create metódust a nodes objektum számára, és kéri a konténert, hogy hozzon létre két csomópontot. Amint azt a Doxygenleírja, a konténer kéri az ns-3 rendszerét, hogy hozzon létre két objektumot, Node és megőrzi a mutatóikat magában.
A szkriptben létrehozott csomópontok egyelőre nem végeznek semmilyen műveletet. A topológia felépítésének következő lépése az, hogy csatlakoztassuk a csomópontjainkat a hálózathoz. A legegyszerűbb hálózati forma, amelyet támogatunk, a két csomópont közötti pont-pont kapcsolat. Most létrehozzuk ezt a kapcsolatot.
PointToPointHelper
Kétpontos kapcsolatot hozunk létre, egy nekünk ismerős sablon szerint, topológiai segédobjektumot használva a csatlakozáshoz szükséges alacsony szintű munka elvégzéséhez. Emlékezzünk, hogy két kulcsfontosságú absztrakciónk van. NetDevice és Csatorna. A valós világban ezek a kifejezések nagyjából megfelelnek a perifériás kártyáknak és a hálózati kábeleknek. Általában ezek a dolgok szorosan összefüggenek egymással, és senki sem számíthat átadásra, például eszközökön Ethernet vezeték nélküli csatornán. Topológiai segítőink követik ezt a szoros kapcsolatot, ezért ebben a forgatókönyvben egy objektumot fog használni PointToPointHelper az ns‑3 objektumok konfigurálásához és kapcsolódásához. PointToPointNetDevice és PointToPointChannelA következő három sor a forgatókönyvben:
PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));Az első sor,
PointToPointHelper pointToPoint;példányt hoz létre a veremben. PointToPointHelperA legfelső szint szempontjából a következő sor,
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));az objektumnak azt mondja, PointToPointHelper hogy használja az "5 Mbit/s" (öt megabit másodpercenként) értéket, mint "DataRate».
A konkrétabb nézőpontból a "DataRate" sor megfelel annak, amit attribútumnak hívunk. PointToPointNetDeviceHa megnézi a Doxygen osztályt ns3::PointToPointNetDevice és a GetTypeId metódus dokumentációját,DataRateennél fogva egy listát talál az eszközre definiált attribútumokkal. Köztük ott lesz az "
. A felhasználó által látható ns‑3 objektumok többsége hasonló attribútumlistákkal rendelkezik. Ezt a mechanizmust használjuk, hogy egyszerűen beállítsuk a szimulációt újraépítés nélkül, amint azt a következő szakaszban látni fogja.DataRateHasonlóan az "
" a PointToPointNetDevice-ben, megtalálja a "Delay" attribútumot is, amely a PointToPointChannel-hez kapcsolódik. Az utolsó sor,mondja PointToPointHelper pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
az "2 ms" (két millimásodperc) értéket használja a késleltetési értéknek a létrehozott, később létrehozott pont-pont csatornán.
NetDeviceContainer NodeContainerEddig van egy szkriptünk, amely PointToPointHelper, amely tartalmaz két csomópontot. Van egy , amely elő van készítve a PointToPointNetDevices PointToPointHelper létrehozására és azokat a PointToPointChannel objektummal való összekapcsolására. Ahogyan a NodeContainer topológiai segédobjektumot használtuk a csomópontok létrehozásához, kérni fogjuk, NetDevicehogy végezze el a nálunk a berendezések létrehozásával, beállításával és telepítésével kapcsolatos munkát. Szükségünk lesz a létrehozott objektumok listájára, az "2 ms" (két millimásodperc) értéket használja a késleltetési értéknek a létrehozott, később létrehozott pont-pont csatornán. a tárolásukhoz, ahogyan azt használtuk NodeContainer az általunk létrehozott csomópontok tárolásához. A következő két sor kód
NetDeviceContainer devices;
devices = pointToPoint.Install (nodes);befejezi az eszközök és a csatorna beállítását. Az első sor deklarálja a fent említett eszközkontejnert, a második pedig a fő munkát végzi. A módszer Telepítés területen PointToPointHelper acceptálja NodeContainer mint paraméter. A belső az "2 ms" (két millimásodperc) értéket használja a késleltetési értéknek a létrehozott, később létrehozott pont-pont csatornán. minden csomópont számára, amely a NodeContainer létrejön (a pont-pont kapcsolat érdekében pontosan kettőnek kell lennie) PointToPointNetDevice létrejön és az eszközkontejnerben tárolódik. PointToPointChannel létrejön, és két , amely elő van készítve a. Az objektumok létrehozása után a PointToPointHelper, tárolt attribútumokat használják a létrehozott objektumok megfelelő attribútumainak inicializálására.
A hívás végrehajtása után pointToPoint.Install (nodes) két csomópontunk lesz, mindkettőben telepítve van a «pont-pont» hálózati eszköz és egy «pont-pont» csatorna a közöttük. Mindkét eszköz úgy lesz beállítva, hogy öt megabit per másodperc sebességgel adatokat továbbítson, a csatornán pedig két milliszekundum késleltetéssel.
InternetStackHelper
Most már be vannak állítva a csomópontok és az eszközök, de a csomópontjainkon nincsenek protokollstackek telepítve. A következő két sor kód gondoskodik erről.
InternetStackHelper stack;
stack.Install (nodes);InternetStackHelper — egy topológiai segéd az interneti stackekhez, hasonlóan a PointToPointHelper-hez a kétpontú hálózati eszközöknél. A módszer Telepítés NodeContainer-t fogad el paraméterként. A végrehajtás során internetstacket (TCP, UDP, IP stb.) állít be minden konténer csomópontján.
Ipv4AddressHelper
Ezután az eszközeinket IP-címekhez kell kapcsolnunk. A címek elosztásának kezelésére topológiai segédet biztosítunk. Az egyetlen felhasználó számára látható API a bázis IP-cím és a maszk beállítása, amelyet a tényleges címelosztás során használnak (ez alacsonyabb szinten történik a segédben). A következő két sor kód a példascriptünkben first.cc,
Ipv4AddressHelper address;
address.SetBase ("10.1.1.0", "255.255.255.0");deklárolják a segéd cím objektumot, és azt mondják neki, hogy kezdje el IP-címek kiosztását a 10.1.1.0 hálózatból, a bitmaszk 255.255.255.0 használatával. Alapértelmezés szerint a kiosztott címek az egyestől kezdődnek, és monoton növekednek, így az első cím, amely a bázisból kiosztásra kerül, a 10.1.1.1, majd a 10.1.1.2 stb. Valójában az ns-3 alacsony szinten nyomon követi az összes kiosztott IP-címet, és fatális hibát generál, ha véletlenül olyan helyzetet teremt, ahol ugyanaz a cím kétszer lesz generálva (egyébként ezt a hibát nehéz debuggolni).
A következő kódsor
Ipv4InterfaceContainer interfaces = address.Assign (devices);végrehajtja a cím tényleges hozzárendelését. Az ns-3-ban összekapcsoljuk az IP-címet az eszközzel a Ipv4Interfaceobjektum segítségével. Ahogyan néha szükségünk van a segéd által létrehozott hálózati eszközök listájára az későbbi felhasználásra, néha szükségünk van az Ipv4Interface. Ipv4InterfaceContainer objektumokra, amelyek ezt a funkciót nyújtják.
Pont-pont hálózatot építettünk, telepített veremmel és kiosztott IP-címekkel. Most minden csomóponthoz alkalmazásra van szükségünk a forgalom generálásához.
4.2.7 Alkalmazás használata
Az ns-3 rendszerének másik alapvető absztrakciója a Alkalmazás (alkalmazás). Ebben a forgatókönyvben a következő két specializálást használjuk a Alkalmazás ns-3 alaposztályból, az UdpEchoServerApplication és UdpEchoClientApplication. Mint a korábbi esetekben, segédobjektumokat használunk az alapobjektumok beállításához és kezeléséhez. Itt a UdpEchoServerHelper és UdpEchoClientHelperobjektumokat használjuk, hogy megkönnyítsük a dolgunkat.
UdpEchoServerHelper
A következő kódsorok a first.cc példa scriptünkben az UDP echo szerver alkalmazás beállítására szolgálnak az egyik olyan csomóponton, amelyet korábban létrehoztunk.
UdpEchoServerHelper echoServer (9);
ApplicationContainer serverApps = echoServer.Install (nodes.Get (1));
serverApps.Start (Seconds (1.0));
serverApps.Stop (Seconds (10.0));A fenti kódrészlet első sora létrehozza UdpEchoServerHelper. Mint ahogyan megszokhattuk, ez nem önálló alkalmazás, hanem egy objektum, amely segít nekünk valódi alkalmazásokat létrehozni. Az egyik megállapodásunk az, hogy átadjuk a szükséges attribútumokat a segédobjektum (segítő) konstruktorának. Ebben az esetben a segítő nem tud semmi hasznosat tenni, ha nem kapja meg a portszámot, amelyen a szerver várni fogja a csomagokat, ezt a számot az ügyfélnek is ismernie kell. Ebben az esetben a konstruktorhoz átadjuk a portszámot. A konstruktor viszont egyszerűen végrehajtja SetAttribute a megadott értékkel. Később, ha szükséges, a SetAttribute segítségével más port attribútum értéket is beállíthat.
Sok más segédobjhoz hasonlóan az objektum UdpEchoServerHelper rendelkezik egy metódussal Telepítés. Ennek a metódusnak a végrehajtása gyakorlatilag egy alap echo-szerver alkalmazást hoz létre, és hozzákapcsolja a csomóponthoz. Érdekes, hogy a metódus Telepítés acceptálja NodeContainter paraméterként, akárcsak más Telepítés módszerek, amelyeket már láttunk.
A C++ nyelv implicit átkonvertálása, ami itt működik, a metódus node.Get (1) (ami egy csomópont objektum okos mutatóját adja vissza — Ptr) és használja azt a konstruktor számára egy névtelen objektumban NodeContainer, ami aztán átadásra kerül a metódusnak Telepítés. Ha nem tudja a C++ kódban meghatározni, hogy melyik aláírással rendelkező metódus fordul le és hajtódik végre, keresse meg az implicit átkonvertálásokat.
Most látjuk, hogy echoServer.Install az alkalmazás telepítését tervezi UdpEchoServerApplication a kiválasztott csomópontra, NodeContaineramit a csomópontjaink kezelésére használunk, az 1-es indexű csomópont. A metódus Telepítés visszaad egy konténert, amely tartalmazza az összes alkalmazásra mutató mutatót (jelen esetben egyet, mivel egy névtelen NodeContainer, amely tartalmaz egy csomópontot) a segítő által létrehozva.
Az alkalmazásoknak meg kell határozniuk a forgalomgenerálás indításának időpontját "start" és szükség lehet továbbá a leállítási időpont megadására is "stop".Mindkét paramétert megadjuk. Ezek az időpontok az ApplicationContainer osztályának és Megállítmódszerekkel állíthatók be. Ezek a módszerek paramétereket típusként Időfogadnak. Ebben az esetben egy explicit C++ átalakulási sorrendet használunk, hogy a C++-t double 1.0 és átalakítani egy tns‑3 Time objektummá, amely a Seconds objektumot használja a másodpercekbe való átváltáshoz. Ne feledje, hogy az átalakítási szabályokat a modell szerzője vezérelheti, és a C++-nak megvannak a saját szabályai, ezért nem mindig lehet számítani arra, hogy a paraméterek az elvárt módon lesznek átalakítva. Két sor,
serverApps.Start (Seconds (1.0));
serverApps.Stop (Seconds (10.0));ez ahhoz vezet, hogy az echo server alkalmazás egy másodperccel a szimuláció kezdete után automatikusan elindul (bekapcsol), és tíz másodperc múlva leáll (kikapcsol). Mivel bejelentettük a szimulációs eseményt (az alkalmazás leállítási eseménye), amely tíz másodperc múlva fog végrehajtódni, legalább tíz másodpercnyi hálózati működés szimulálásra kerül.
UdpEchoClientHelper
A kliens alkalmazás echo gyakorlatilag hasonló módon kerül konfigurálásra, mint a szerver. Van egy alap objektum, UdpEchoClientApplication, amelyet a következő irányít
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));;Az echo kliens esetében azonban öt különböző attribútumot kell beállítanunk. Az első két attribútumot a létrehozás során határozzuk meg UdpEchoClientHelper. Azokat a paramétereket adjuk át, amelyeket a (segédprogramon belül) az attribútumok beállításához használnak "RemoteAddress" és "RemotePort" a segédprogram konstruktorába történő szükséges paraméterek átadásának megállapodásaink szerint.
Ne feledjük, hogy a Ipv4InterfaceContainer IP-címek nyomon követésére használtuk, amelyeket hozzárendeltünk az eszközeinkhez. Az interfész 0 a kapcsolati konténerben a csomópont 0 IP-címének felel meg. Az első interfész a kapcsolati konténerben a csomópont 1 IP-címének felel meg. Tehát a kód első sorában (fent) létrehozzuk a segédprogramot, és megmondjuk neki, hogy a kliens távoli címe a szerverrel rendelkező csomópontnak rendelt IP-cím legyen. Azt is mondjuk, hogy a csomagok küldését a kilencedik portra kell megszervezni.
A „MaxPackets” attribútum tájékoztatja az ügyfelet a legnagyobb csomagszámról, amelyet a szimuláció során elküldhetünk. Az „Interval” attribútum arról tájékoztatja az ügyfelet, hogy mennyi ideig várakozzon a csomagok között, míg a „PacketSize” attribútum azt mondja el az ügyfélnek, hogy mekkora legyen a csomag hasznos terhe. E szempontok kombinációjával azt mondjuk az ügyfélnek, hogy küldjön egy 1024 bájtos csomagot.
Ahogyan az echoszerver esetében, itt is beállítjuk az eho-ügyfél attribútumait, osztályának és Megállít, de itt egy másodperccel azután indítjuk el az ügyfelet, hogy a szerver bekapcsolt (két másodperccel a szimuláció elindítása után).
4.2.8 Szimulátor
Ebben a szakaszban el kell indítanunk a szimulációt. Ezt egy globális függvény segítségével tesszük meg, Simulator::Run.
Simulator::Run ();Amikor korábban meghívtuk a módszereket,
serverApps.Start (Seconds (1.0));
serverApps.Stop (Seconds (10.0));
...
clientApps.Start (Seconds (2.0));
clientApps.Stop (Seconds (10.0));tulajdonképpen eseményeket ütemeztünk a szimulátorban 1,0 másodpercre, 2,0 másodpercre és két eseményt 10,0 másodpercre. Miután meghívtuk, Simulator::Run, a rendszer elkezdi végigjárni az ütemezett események listáját és végrehajtani azokat. Először egy eseményt indít el 1,0 másodperc múlva, ami aktiválja az echoszerver alkalmazást (ez az esemény más eseményeket is ütemezhet). Ezután elindít egy eseményt 2,0 másodpercnél, ami elindítja az eho-ügyfél alkalmazást. Ismételten, ez az esemény is ütemezhet további eseményeket. Az eho-ügyfél indító eseményének megvalósítása elindítja az adatátviteli szimulációs szakaszt, elküldve egy csomagot a szerverre.
A csomag szerverre küldése eseménysorozatot indít el, amelyek automatikusan ütemezve lesznek a háttérben, és megvalósítják a csomag echosugárzásának küldési mechanikáját a szinkronizálási beállításaink szerint, amelyeket a forgatókönyvünkben meghatároztunk.
Végső soron, mivel csak egy csomagot küldünk el (ne feledjük, hogy az attribútum MaxPackets egyetlen egységre lett beállítva), a csomag eho-igénylésével kezdeményezett eseménysorozat befejeződik, és a szimuláció várakozó állapotba lép. Amint ez megtörténik, a hátralévő ütemezett események a Megállít szerver és az ügyfél eseményei lesznek. Amikor ezek az események végbemennek, nem marad további esemény a feldolgozásra, és Simulator::Run visszaadja a vezérlést. A modellezés befejeződött.
Csak annyit kell tennünk, hogy rendet rakjunk. Ezt a globális függvény meghívásával végezzük: Simulator::Destroy. Mivel segédprogramok (vagy alacsony szintű ns-3 kód) hívódnak meg, amelyek úgy vannak megszervezve, hogy a szimulátorba horgonyokat építsenek be az összes létrehozott objektum megsemmisítésére. Nem kell nyomon követnie ezeket az objektumokat - amit tennie kell, az az, hogy hívja meg Simulator::Destroy és kilép. Az ns-3 rendszer elvégzi ezt a nehéz munkát helyette. Az első ns-3 szkriptünk maradék sorai, a first.cc, pontosan ezt végzik:
Simulator::Destroy ();
return 0;
}Mikor áll meg a szimulátor?
Az ns-3 egy diszkrét események szimulátora (DE). Egy ilyen szimulátorban minden esemény az esemény végrehajtásának idejéhez van kötve, és a szimuláció az események feldolgozásával folytatódik, a megjelenésük sorrendjében a szimuláció során. Az események jövőbeli események ütemezését is okozhatják (például egy időzítő átütemezheti magát, hogy befejezze a számítást a következő intervallumban).
A kezdeti eseményeket általában egy objektum indítja el, például az IPv6 ütemezni fogja a szolgáltatások meghatározását a hálózaton, a szomszédok lekérdezéseit stb. Az alkalmazás ütemezi az első csomagküldési eseményt stb. Amikor egy eseményt feldolgoznak, az generálhat zérót, egyet vagy több eseményt. Ahogy a szimuláció halad, a történések egyszerűen befejeződnek vagy újakat generálnak. A szimuláció automatikusan leáll, ha az események sora üres marad, vagy ha egy speciális eseményt észlelnek. Megállít. Az esemény Megállít a következő funkcióval generálódik Simulator::Stop (leállítja az időt).
Van egy tipikus eset, amikor a Simulator::Stop abszolút szükséges a szimuláció leállításához: amikor önfenntartó események vannak. Az önfenntartó (vagy ismétlődő) események olyan események, amelyek mindig átütemeződnek. Ennek következtében mindig fenntartják az események sorát nem üresen. Számos protokoll és modul van, amelyek ismétlődő eseményeket tartalmaznak, például:
• FlowMonitor – időszakos ellenőrzés a elveszett csomagok miatt;
• RIPng – időszakos frissítés a routing táblákra;
• stb.
Ilyen esetekben Simulator::Stop szükséges a szimuláció megfelelő leállításához. Továbbá, amikor az ns-3 emulációs módban van, a RealtimeSimulator-t használják az órák szinkronizálására a gép óráival, és Simulator::Stop szükséges a folyamat leállításához.
A tankönyvben szereplő sok szimulációs program nem hívja meg Simulator::Stop Ez nyilvánvaló, mivel ezek automatikusan befejeződnek, amikor a sorban lévő események kimerülnek. Ezek a programok azonban a Simulator::Stop hívását is fogják teljesíteni. Például az alábbi kiegészítő utasítás az első példában ütemez egy explicit leállítást a 11. másodpercre:
+ Simulator::Stop (Seconds (11.0));
Simulator::Run ();
Simulator::Destroy ();
return 0;
}A fentiek lényegében nem módosítják ennek a programnak a viselkedését, mivel ez a konkrét szimuláció természetes módon 10 másodperc alatt ér véget. De ha megváltoztatná a leállítási időt a fenti utasításban 11 másodpercről 1 másodpercre, észrevenné, hogy a szimuláció megáll, mielőtt bármilyen kimenet megjelenik a képernyőn (mivel a kimenet körülbelül 2 másodperc alatt történik meg a szimulációs időben).
Fontos, hogy a Simulator::Stop-t a Simulator::Run hívása előtt hívja meg; különben a Simulator::Run soha nem adhatja vissza a vezérlést a fő programnak a leállításhoz!
4.2.9 Az Ön forgatókönyvének összeállítása
Egyszerűvé tettük a szkriptjeid létrehozását. Csak annyit kell tenned, hogy a szkriptedet a scratch mappába helyezed, és automatikusan össze lesz állítva, ha futtatod Waf. Próbáljuk meg. Térj vissza a gyökérmappába, és másold át examples/tutorial/first.cc a mappába scratch
$ cd ../..
$ cp examples/tutorial/first.cc scratch/myfirst.ccMost építsd meg az első példa szkriptedet a következő használatával waf:
$ . /wafLátnod kell az üzeneteket arról, hogy az első példád sikeresen létrejött.
Waf: Belépés a könyvtárba `/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: Kilépés a könyvtárból `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' sikeresen befejezve (2.357s)Most futtathatod a példát (jegyezd meg, hogy ha a programodat a scratch könyvtárban építed, akkor onnan is kell futtatnod) scratch):
$ ./waf --run scratch/myfirstLátnod kell hasonló kimenetet:
Waf: Belépés a könyvtárba `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Kilépés a könyvtárból `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' sikeresen befejezve (0.418s) 1024 bájt küldve a 10.1.1.2 címre
1024 bájt fogadva a 10.1.1.1 címről
1024 bájt fogadva a 10.1.1.2 címrőlItt látja, hogy a build rendszer ellenőrzi, hogy a fájl összeállt-e, majd elindítja azt. Látja, hogy az echo kliensben van egy bejegyzés, amely jelzi, hogy egy 1024 bájtos csomagot küldött az echo szerverre 10.1.1.2. Ön is láthatja az echo szerver naplózási komponensét, amely azt mutatja, hogy 1024 bájtot kapott 10.1.1.1-től. Az echo szerver csendben visszaküldi a csomagot, és Ön az echo kliens naplójában látja, hogy visszakapta a csomagját a szervertől.
4.3 ns-3 Forráskód
Most, hogy használt néhány ns-3 segédprogramot, nézze meg néhány forráskódot, amely ezt a funkciót valósítja meg. A legfrissebb kódot a webkiszolgálónkon találja az alábbi linken: . Itt egy Mercurial összefoglaló oldalt lát, amely a ns-3 fejlesztési fáfáinkat tartalmazza. Az oldal tetején néhány linket fog látni,
összefoglaló | rövidnapló | változásnapló | grafikon | címkék | fájlokFolytassa, és válassza a fájlok hivatkozását. Így fog kinézni a legtöbb repónk felső szintje:
drwxr-xr-x [fel]
drwxr-xr-x bindings python fájlok
drwxr-xr-x doc fájlok
drwxr-xr-x examples fájlok
drwxr-xr-x ns3 fájlok
drwxr-xr-x scratch fájlok
drwxr-xr-x src fájlok
drwxr-xr-x utils fájlok
-rw-r--r-- 2009-07-01 12:47 +0200 560 .hgignore fájl | verziók | annotálás
-rw-r--r-- 2009-07-01 12:47 +0200 1886 .hgtags fájl | verziók | annotálás
-rw-r--r-- 2009-07-01 12:47 +0200 1276 AUTHORS fájl | verziók | annotálás
-rw-r--r-- 2009-07-01 12:47 +0200 30961 CHANGES.html fájl | verziók | annotálás
-rw-r--r-- 2009-07-01 12:47 +0200 17987 LICENSE fájl | verziók | annotálás
-rw-r--r-- 2009-07-01 12:47 +0200 3742 README fájl | verziók | annotálás
-rw-r--r-- 2009-07-01 12:47 +0200 16171 RELEASE_NOTES fájl | verziók | annotálás
-rw-r--r-- 2009-07-01 12:47 +0200 6 VERSION fájl | verziók | annotálás
-rwxr-xr-x 2009-07-01 12:47 +0200 88110 waf fájl | verziók | annotálás
-rwxr-xr-x 2009-07-01 12:47 +0200 28 waf.bat fájl | verziók | annotálás
-rw-r--r-- 2009-07-01 12:47 +0200 35395 wscript fájl | verziók | annotálás
-rw-r--r-- 2009-07-01 12:47 +0200 7673 wutils.py fájl | verziók | annotálásA példáink szkriptjei a következő könyvtárban találhatók: példák. Ha rákattint a példákra, akkor a almappa listáját fogja látni. Az egyik fájl az almappában tutorial — first.cc. Ha rákattint a first.cc meglátja a kódot, amelyet éppen megtanult.
A forráskód főként a könyvtárban található srcA forrást kódot úgy tekintheti meg, hogy rákattint a könyvtár nevére, vagy rákattint a fájlokra jobbra a könyvtár neve mellett. Ha rákattint a src könyvtárra, megkapja a src alkönyvtárait. Ha ezután rákattint a core alkönyvtárra, meg fogja találni a fájlok listáját. Az első fájl, amit látni fog (a kézikönyv írásának időpontjában) — abort.h. Ha rákattint a linkre abort.h, a forrásfájlra lesz irányítva, amely abort.h, hasznos makrókat tartalmaz a szkriptekből való kilépéshez, ha rendellenes körülményeket észlelnek. Az ebben a fejezetben használt segédfájlok forráskódját a következő könyvtárban találja: src/Applications/helper. Ne habozzon ásni a könyvtárfa ügyében, hogy megértsen mindent és hozzájusson az ns-3 programozási stílusához.
Forrás: habr.com
