ns-3 netværkssimulator tutorial. Kapitel 5

ns-3 netværkssimulator tutorial. Kapitel 5
kapitel 1,2
kapitel 3
kapitel 4

5 Indstillinger
5.1 Brug af logningsmodulet
5.1.1 Logningsoversigt
5.1.2 Aktiver logning
5.1.3 Tilføjelse af logning til din kode
5.2 Brug af kommandolinjeargumenter
5.2.1 Tilsidesættelse af standard attributværdier
5.2.2 Indfangning af dine egne kommandoer
5.3 Brug af sporingssystemet
5.3.1 ASCII-sporing
Parsing af ASCII-spor
5.3.2 PCAP-sporing

Kapitel 5

justering

5.1 Brug af logningsmodulet

Vi har allerede kort set på ns-3 logningsmodulet ved at se på scriptet første.cc. I dette kapitel vil vi se nærmere på mulige anvendelser for logningsundersystemet.

5.1.1 Logningsoversigt

Mange store systemer understøtter en form for beskedlogningsfacilitet, og ns-3 er ingen undtagelse. I nogle tilfælde skrives der kun fejlmeddelelser til "operatørkonsollen" (som normalt er stderr på Unix-baserede systemer). På andre systemer kan der blive vist advarselsmeddelelser samt mere detaljeret information. I nogle tilfælde bruges logværktøjer til at udsende fejlfindingsmeddelelser, der hurtigt kan sløre outputtet.

Den subHRD, der bruges i ns-3, antager, at alle disse niveauer af informationsindhold er nyttige, og vi tilbyder en selektiv, lagdelt tilgang til logning af beskeder. Logning kan deaktiveres fuldstændigt, aktiveres per komponent eller globalt. Til dette formål anvendes justerbare niveauer af informationsindhold. ns-3 logningsmodulet giver en relativt enkel måde at få brugbar information fra din simulering på.

Du bør forstå, at vi leverer en generel mekanisme - sporing - til at udtrække data fra dine modeller, som bør være det foretrukne output til simuleringer (for mere information om vores sporingssystem, se vejledningssektion 5.3). Logning bør være den foretrukne metode til at indhente fejlfindingsoplysninger, advarsler, fejlmeddelelser eller til hurtigt at udskrive meddelelser fra dine scripts eller modeller til enhver tid.

I øjeblikket definerer systemet syv niveauer (typer) af logmeddelelser i stigende rækkefølge af informationsindhold.

  • LOG_ERROR - logning af fejlmeddelelser (relateret makro: NS_LOG_ERROR);
  • LOG_WARN - Log advarselsmeddelelser (relateret makro: NS_LOG_WARN);
  • LOG_DEBUG - Log relativt sjældne specielle debug-meddelelser (relateret makro: NS_LOG_DEBUG);
  • LOG_INFO - registrering af informationsmeddelelser om programmets fremskridt (relateret makro: NS_LOG_INFO);
  • LOG_FUNCTION - Logs meddelelser, der beskriver hver funktion kaldet (to relaterede makroer: NS_LOG_FUNCTION, brugt til medlemsfunktioner og NS_LOG_FUNCTION_NOARGS, brugt til statiske funktioner);
  • LOG_LOGIC - logning af meddelelser, der beskriver det logiske flow i en funktion (relateret makro: NS_LOG_LOGIC);
  • LOG_ALL - Loger alt nævnt ovenfor (ingen tilknyttet makro).
    For hver type (LOG_TYPE) er der også en LOG_LEVEL_TYPE, som, hvis den bruges, tillader alle niveauer over den at blive logget ud over sit eget niveau. (Som en konsekvens er LOG_ERROR og LOG_LEVEL_ERROR, og LOG_ALL og LOG_LEVEL_ALL funktionelt ækvivalente.) Aktivering af LOG_INFO vil f.eks. kun tillade meddelelser leveret af NS_LOG_INFO-makroen, mens aktivering af LOG_LEVEL_INFO også vil inkludere meddelelser leveret af makroerne LOG_DE_LOGRN_LOGRNS,WAOR_DE_LOGRN_LOGRNS og WAOR_LOGRNS.

Vi leverer også en ubetinget logningsmakro, der altid vises, uanset logningsniveauet eller udvalgskomponenten.

  • NS_LOG_UNCOND - Ubetinget logning af den tilknyttede besked (intet tilknyttet logningsniveau).

Hvert niveau kan forespørges individuelt eller kumulativt. Logning kan konfigureres ved hjælp af sh-miljøvariablen NS_LOG eller ved at logge et systemfunktionskald. Som vist tidligere har logningssystemet Doxygen-dokumentation, og nu er det et godt tidspunkt at gennemgå det, hvis du ikke allerede har gjort det.

Nu hvor du har læst dokumentationen meget detaljeret, lad os bruge den viden til at få nogle interessante oplysninger fra eksempelscriptet scratch/myfirst.ccsom du allerede har kompileret.

5.1.2 Aktiver logning

Lad os bruge NS_LOG miljøvariablen til at køre nogle flere logfiler, men først, bare for at få dine pejlinger, kør det sidste script som du gjorde tidligere,

$ ./waf --run scratch/myfirst

Du bør se det velkendte output fra det første ns-3 eksempelprogram

$ Waf: Entering directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build' 'build'
finished successfully (0.413s)
Sent 1024 bytes to 10.1.1.2
Received 1024 bytes from 10.1.1.1
Received 1024 bytes from 10.1.1.2

Det viser sig, at de "sendte" og "modtagne" beskeder, du ser ovenfor, faktisk er loggede beskeder fra UdpEchoClientApplication и UdpEchoServerApplication. For eksempel kan vi bede klientapplikationen om at udskrive yderligere information ved at indstille dens logningsniveau via miljøvariablen NS_LOG.

Fra nu af vil jeg antage, at du bruger en sh-lignende shell, der bruger syntaksen "VARIABLE=værdi". Hvis du bruger en csh-lignende shell, så bliver du nødt til at konvertere mine eksempler til "setenv variabel værdi" syntaks, der kræves af disse skaller.

I øjeblikket reagerer UDP echo-klientapplikationen på følgende kodelinje scratch/myfirst.cc,

LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO);

Det aktiverer logningsniveauet LOG_LEVEL_INFO. Når vi passerer et logningsniveauflag, aktiverer vi faktisk det niveau og alle lavere niveauer. I dette tilfælde har vi aktiveret NS_LOG_INFO, NS_LOG_DEBUG, NS_LOG_WARN og NS_LOG_ERROR. Vi kan øge logningsniveauet og få mere information uden scriptændringer og genkompilering ved at indstille NS_LOG miljøvariablen som følger:

$ export NS_LOG=UdpEchoClientApplication=level_all

Så vi indstiller sh shell-variablen NS_LOG til følgende værdi,

UdpEchoClientApplication=level_all

Venstre side af opgaven er navnet på den loggede komponent, vi vil konfigurere, og højre side er det flag, vi vil anvende for det. I dette tilfælde vil vi aktivere alle niveauer af fejlretning i applikationen. Hvis du kører scriptet med NS_LOG indstillet på denne måde, vil ns-3-logningssystemet acceptere ændringerne, og du bør se følgende output:

Waf: Entering directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' finished successfully (0.404s)
UdpEchoClientApplication:UdpEchoClient()
UdpEchoClientApplication:SetDataSize(1024)
UdpEchoClientApplication:StartApplication()
UdpEchoClientApplication:ScheduleTransmit()
UdpEchoClientApplication:Send()
Sent 1024 bytes to 10.1.1.2
Received 1024 bytes from 10.1.1.1
UdpEchoClientApplication:HandleRead(0x6241e0, 0x624a20)
Received 1024 bytes from 10.1.1.2
UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()

Yderligere fejlretningsoplysninger leveret af applikationen er nu på NS_LOG_FUNCTION-niveauet. Det viser hver forekomst af et funktionskald under scriptudførelse. Som en generel regel er det i metodefunktioner at foretrække at bruge (som minimum)NS_LOG_FUNCTION (this). Brug NS_LOG_FUNCTION_NOARGS ()
kun i statiske funktioner. Bemærk dog, at ns-3-systemet ikke er påkrævet for at understøtte nogen logningsfunktionalitet. Beslutningen om, hvor meget information der registreres, overlades til den enkelte modeludvikler. I tilfælde af ekkoapplikationer er en stor mængde logningsoutput tilgængelig.

Du kan nu se en log over funktionsopkald, der blev foretaget af applikationen. Hvis du ser godt efter, vil du bemærke et kolon mellem stregen UdpEchoClientApplication og navnet på metoden, hvor du kan forvente at se C++ scope-operatoren (: :). Dette er bevidst.

Dette er faktisk ikke navnet på klassen, men navnet på logningskomponenten. Når der er et match mellem en kildefil og en klasse, er det normalt navnet på klassen, men du bør indse, at det faktisk ikke er navnet på klassen, og der er et enkelt kolon i stedet for et dobbelt kolon. Dette er en måde at hjælpe dig med konceptuelt at adskille logbønnenavnet fra klassenavnet på en relativt subtil måde.

Men i nogle tilfælde kan det være svært at afgøre, hvilken metode der rent faktisk genererer logmeddelelsen. Hvis du ser på teksten ovenfor, undrer du dig måske over, hvor stregen "Received 1024 bytes from 10.1.1.2" Du kan løse dette problem ved at indstille niveauet prefix_func til miljøvariablen NS_LOG. Prøv følgende:

$ export 'NS_LOG=UdpEchoClientApplication=level_all|prefix_func'

Bemærk, at anførselstegnene er nødvendige, fordi den lodrette streg, vi bruger til at repræsentere OR-operationen, også er en Unix-rørforbindelse. Hvis du nu kører scriptet, vil du se, at logningssystemet sikrer, at hver meddelelse i en given log er præfikset med komponentnavnet.

Waf: Entering directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' finished successfully (0.417s)
UdpEchoClientApplication:UdpEchoClient()
UdpEchoClientApplication:SetDataSize(1024)
UdpEchoClientApplication:StartApplication()
UdpEchoClientApplication:ScheduleTransmit()
UdpEchoClientApplication:Send()
UdpEchoClientApplication:Send(): Sent 1024 bytes to 10.1.1.2
Received 1024 bytes from 10.1.1.1
UdpEchoClientApplication:HandleRead(0x6241e0, 0x624a20)
UdpEchoClientApplication:HandleRead(): Received 1024 bytes from 10.1.1.2
UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()

Nu kan du se, at alle meddelelser, der kommer fra UDP echo-klientapplikationen, er identificeret som sådan. Besked "Received 1024 bytes from 10.1.1.2" er nu tydeligt identificeret som kommer fra echo-klientapplikationen. Den resterende besked skal komme fra UDP-ekkoserverapplikationen. Vi kan aktivere denne komponent ved at indtaste en kolon-separeret liste over komponenter i NS_LOG miljøvariablen.

$ export 'NS_LOG=UdpEchoClientApplication=level_all|prefix_func:
               UdpEchoServerApplication=level_all|prefix_func'

Advarsel: I eksempelteksten ovenfor skal du fjerne linjeskifttegnet efter kolon (:), det bruges til at formatere dokumentet. Hvis du nu kører scriptet, vil du se alle logmeddelelserne fra klient- og serverekko-applikationerne. Du kan se, at dette kan være meget nyttigt ved fejlretning.

Waf: Entering directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' finished successfully (0.406s)
UdpEchoServerApplication:UdpEchoServer()
UdpEchoClientApplication:UdpEchoClient()
UdpEchoClientApplication:SetDataSize(1024)
UdpEchoServerApplication:StartApplication()
UdpEchoClientApplication:StartApplication()
UdpEchoClientApplication:ScheduleTransmit()
UdpEchoClientApplication:Send()
UdpEchoClientApplication:Send(): Sent 1024 bytes to 10.1.1.2
UdpEchoServerApplication:HandleRead(): Received 1024 bytes from 10.1.1.1
UdpEchoServerApplication:HandleRead(): Echoing packet
UdpEchoClientApplication:HandleRead(0x624920, 0x625160)
UdpEchoClientApplication:HandleRead(): Received 1024 bytes from 10.1.1.2
UdpEchoServerApplication:StopApplication()
UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoServerApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()
UdpEchoServerApplication:~UdpEchoServer()

Det er også nogle gange nyttigt at kunne se simuleringstidspunktet, hvor logmeddelelsen blev genereret. Du kan gøre dette ved at tilføje OR-bitten præfiks_tid:

$ export 'NS_LOG=UdpEchoClientApplication=level_all|prefix_func|prefix_time: UdpEchoServerApplication=level_all|prefix_func|prefix_time'

Igen, du bliver nødt til at fjerne ovenstående nylinjetegn. Hvis du nu kører scriptet, skulle du se følgende output:

Waf: Entering directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' finished successfully (0.418s)
0s UdpEchoServerApplication:UdpEchoServer()
0s UdpEchoClientApplication:UdpEchoClient()
0s UdpEchoClientApplication:SetDataSize(1024)
1s UdpEchoServerApplication:StartApplication()
2s UdpEchoClientApplication:StartApplication()
2s UdpEchoClientApplication:ScheduleTransmit()
2s UdpEchoClientApplication:Send()
2s UdpEchoClientApplication:Send(): Sent 1024 bytes to 10.1.1.2
2.00369s UdpEchoServerApplication:HandleRead(): Received 1024 bytes from 10.1.1.1
2.00369s UdpEchoServerApplication:HandleRead(): Echoing packet
2.00737s UdpEchoClientApplication:HandleRead(0x624290, 0x624ad0)
2.00737s UdpEchoClientApplication:HandleRead(): Received 1024 bytes from 10.1.1.2
10s UdpEchoServerApplication:StopApplication()
10s UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoServerApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()
UdpEchoServerApplication:~UdpEchoServer()

Bemærk venligst, at konstruktøren for UdpEchoServer blev kaldt under simulering 0 sekunder. Dette sker faktisk før simuleringen starter, men tiden vises som nul sekunder. Det samme gælder for konstruktørmeddelelsen UdpEchoClient.

Waf: Entering directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' finished successfully (0.418s)
0s UdpEchoServerApplication:UdpEchoServer()
0s UdpEchoClientApplication:UdpEchoClient()
0s UdpEchoClientApplication:SetDataSize(1024)
1s UdpEchoServerApplication:StartApplication()
2s UdpEchoClientApplication:StartApplication()
2s UdpEchoClientApplication:ScheduleTransmit()
2s UdpEchoClientApplication:Send()
2s UdpEchoClientApplication:Send(): Sent 1024 bytes to 10.1.1.2
2.00369s UdpEchoServerApplication:HandleRead(): Received 1024 bytes from 10.1.1.1
2.00369s UdpEchoServerApplication:HandleRead(): Echoing packet
2.00737s UdpEchoClientApplication:HandleRead(0x624290, 0x624ad0)
2.00737s UdpEchoClientApplication:HandleRead(): Received 1024 bytes from 10.1.1.2
10s UdpEchoServerApplication:StopApplication()
10s UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoServerApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()
UdpEchoServerApplication:~UdpEchoServer()

Husk at scriptet scratch/first.cc startede ekkoserverapplikationen et sekund før starten af ​​simuleringen. Nu kan du se, at metoden Start applikation serveren kaldes faktisk i det første sekund. Du kan også bemærke, at ekkoklienten starter i det andet sekund af simuleringen, som vi spurgte i scriptet.

Du kan nu følge simuleringsforløbet på kald ScheduleTransmit i klienten, der kalder HandleRead-callback Send i ekkoserverapplikationen. Bemærk, at den forløbne tid til at sende en pakke over et punkt-til-punkt-link er 3,69 millisekunder. Du kan se, at ekkoserveren logger en besked om, at den har svaret på pakken, og derefter, efter en kanalforsinkelse, kan du se, at ekko-klienten modtager ekkopakken i sin HandleRead-metode.

I denne simulering sker der meget, uden at du opdager det. Men du kan spore hele processen meget nemt ved at aktivere alle logningskomponenter i systemet. Prøv at indstille NS_LOG variablen til følgende værdi,

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

Stjernen ovenfor er et jokertegn for logningskomponenten. Dette vil inkludere alle indtastninger i alle komponenter, der anvendes i simuleringen. Jeg vil ikke gengive outputtet her (i skrivende stund producerer det 1265 linjers output for en enkelt ekkopakke), men du kan omdirigere denne information til en fil og se den i din yndlingseditor.

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

Jeg bruger personligt denne ekstremt detaljerede version af logning, når jeg har et problem og ikke aner, hvor tingene gik galt. Jeg kan ret nemt følge kodeeksekveringen uden at sætte breakpoints og træde igennem koden i debuggeren. Jeg kan bare redigere outputtet i min yndlingseditor og se efter, hvad jeg forventer, og se noget ske, som jeg ikke havde forventet. Når jeg har en generel idé om, hvad der går galt, hopper jeg ind i debuggeren for at dykke ned i problemet. Denne type output kan være særlig nyttig, når dit script gør noget helt uventet. Hvis du kun bruger debuggeren, kan du gå glip af et twist helt. Registrering gør sådanne sving mærkbare.

5.1.3 Tilføjelse af logning til din kode

Du kan tilføje nye poster til dine simuleringer ved at foretage opkald til log-komponenten fra flere makroer. Lad os gøre det i et script min første.cc, som vi har i den "rene" mappe. Husk, at vi definerede en logningskomponent i dette scenarie:

NS_LOG_COMPONENT_DEFINE ("FirstScriptExample");

Du er klar over, at du kan aktivere logning af alle meddelelser fra denne komponent ved at indstille miljøvariablen NS_LOG på forskellige niveauer. Lad os gå videre og tilføje nogle poster til scriptet. Makroen, der bruges til at tilføje informationsniveaumeddelelser til loggen, er NS_LOG_INFO. Lad os tilføje en besked (lige før vi begynder at oprette noder), der fortæller dig, at scriptet er i "Creating Topology"-fasen. Dette gøres i følgende kodestykke,
Åbent scratch/myfirst.cc i din yndlingseditor og tilføj linjen,
NS_LOG_INFO ("Creating Topology");
lige før linjerne,

NodeContainer nodes;
nodes.Create (2);

Kompiler nu scriptet vha WAF, og ryd NS_LOG-variablen for at deaktivere logføringsstrømmen, vi aktiverede tidligere:

$ ./waf
$ export NS_LOG=
Теперь, если вы запустите скрипт,
$ ./waf --run scratch/myfirst

Du vil ikke se den nye meddelelse, fordi den tilknyttede logningskomponent (FirstScriptExample) ikke er blevet aktiveret. For at se din besked skal du aktivere logningskomponenten FirstScriptEksempel med et niveau, der ikke er lavere end NS_LOG_INFO. Hvis du bare vil se dette specifikke logningsniveau, kan du aktivere det på denne måde,

$ export NS_LOG=FirstScriptExample=info

Hvis du kører scriptet nu, vil du se en ny besked "Creating Topology",

Waf: Entering directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' finished successfully (0.404s)
Creating Topology
Sent 1024 bytes to 10.1.1.2
Received 1024 bytes from 10.1.1.1
Received 1024 bytes from 10.1.1.2

5.2 Brug af kommandolinjeargumenter

5.2.1 Tilsidesættelse af standard attributværdier

En anden måde at ændre adfærden af ​​ns-3 scripts uden at redigere eller bygge er at bruge kommandolinjeargumenter. Vi tilbyder en mekanisme til at parse kommandolinjeargumenter og automatisk indstille lokale og globale variabler baseret på resultaterne.

Det første trin i at bruge kommandolinjeargumentsystemet er at erklære en kommandolinjeparser. Dette er ret nemt at gøre (i dit hovedprogram), som i følgende kode,

int
main (int argc, char *argv[])
{
...
CommandLine cmd;
cmd.Parse (argc, argv);
...
}

Dette simple to-linjers uddrag er faktisk meget nyttigt i sig selv. Det åbner døren til det globale variabel- og attributsystem ns-3. Lad os tilføje to linjer kode til begyndelsen af ​​hovedscriptfunktionen scratch/myfirst.cc. Vi går videre, kompilerer scriptet og kører det, når vi kører, laver vi en anmodning om hjælp som følger,

$ ./waf --run "scratch/myfirst --PrintHelp"

Denne kommando vil spørge Waf køre script ridse/min første og send det et kommandolinjeargument - UdskrivHjælp. Anførselstegnene er nødvendige for at angive, hvilket program argumentet er beregnet til. Kommandolinjeparseren vil finde argumentet - UdskrivHjælp og vil vise svaret,

Waf: Entering directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' finished successfully (0.413s)
TcpL4Protocol:TcpStateMachine()
CommandLine:HandleArgument(): Handle arg name=PrintHelp value=
--PrintHelp: Print this help message.
--PrintGroups: Print the list of groups.
--PrintTypeIds: Print all TypeIds.
--PrintGroup=[group]: Print all TypeIds of group.
--PrintAttributes=[typeid]: Print all attributes of typeid.
--PrintGlobals: Print the list of globals.

Lad os nu se på muligheden -Printattributter. Vi har allerede nævnt ns-3 attributsystemet, når vi studerede first.cc scriptet. Vi har set følgende kodelinjer,

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

og det sagde de Datahastighed er faktisk en egenskab PointToPointNetDevice. Lad os bruge kommandolinjeargumentparseren til at se attributterne PointToPointNetDevice. Hjælpelisten siger, hvad vi skal give TypeId. Dette er navnet på den klasse, som attributterne af interesse tilhører. I vores tilfælde vil det være det ns3::PointToPointNetDevice. Lad os fortsætte fremad, ind,

$ ./waf --run "scratch/myfirst --PrintAttributes=ns3::PointToPointNetDevice"

Systemet udskriver alle attributter for denne netværksenhedstype. Du vil se, at blandt attributterne på listen er,

--ns3::PointToPointNetDevice::DataRate=[32768bps]:
The default data rate for point to point links

Dette er standardværdien, som vil blive brugt af systemet, når objektet oprettes PointToPointNetDevice. Vi vil tilsidesætte denne standardværdi ved hjælp af parameteren Attribut в PointToPointHelper højere. Lad os bruge standardværdierne for punkt-til-punkt-enheder og kanaler. For at gøre dette sletter vi opkald SetDeviceAttribute и SetChannelAttribute af min første.cc, som vi har i en ren mappe.

Dit script skal nu blot erklære PointToPointHelper og udfør ikke nogen installationshandlinger som vist i eksemplet nedenfor,

...
NodeContainer nodes;
nodes.Create (2);
PointToPointHelper pointToPoint;
NetDeviceContainer devices;
devices = pointToPoint.Install (nodes);
...

Gå videre og opret et nyt script med Waf (./waf) og lad os gå tilbage og inkludere nogle indtastninger fra UDP-ekkoserverapplikationen og inkludere tidspræfikset.

$ export 'NS_LOG=UdpEchoServerApplication=level_all|prefix_time'

Hvis du kører scriptet, bør du se følgende output:

Waf: Entering directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' finished successfully (0.405s)
0s UdpEchoServerApplication:UdpEchoServer()
1s UdpEchoServerApplication:StartApplication()
Sent 1024 bytes to 10.1.1.2
2.25732s Received 1024 bytes from 10.1.1.1
2.25732s Echoing packet
Received 1024 bytes from 10.1.1.2
10s UdpEchoServerApplication:StopApplication()
UdpEchoServerApplication:DoDispose()
UdpEchoServerApplication:~UdpEchoServer()

Husk, at sidste gang vi så på simuleringstiden, i det øjeblik pakken blev modtaget af ekkoserveren, var den 2,00369 sekunder.

2.00369s UdpEchoServerApplication:HandleRead(): Received 1024 bytes from 10.1.1.1

Nu modtager han pakken på 2.25732 sekunder. Dette skyldes, at vi simpelthen nulstiller PointToPointNetDevice-datahastigheden fra fem megabit pr. sekund til standardværdien, som er 32768 bits pr. sekund. Hvis vi skulle erstatte en ny DataRate ved hjælp af kommandolinjen, kunne vi fremskynde vores simulering igen. Vi vil gøre dette som følger i henhold til formlen, der er impliceret af hjælpeelementet:

$ ./waf --run "scratch/myfirst --ns3::PointToPointNetDevice::DataRate=5Mbps"

Dette vil returnere DataRate-attributten til dens standardværdi på fem megabit pr. sekund. Er du overrasket over resultatet? Det viser sig, at for at vende tilbage til scriptets oprindelige adfærd, skal vi også indstille kanalforsinkelsen til at matche lysets hastighed. Vi kan bede kommandolinjesystemet om at udskrive kanalattributterne, ligesom vi gjorde for netværksenheden:

$ ./waf --run "scratch/myfirst --PrintAttributes=ns3::PointToPointChannel"

Vi vil opdage, at kanalforsinkelsesattributten er indstillet som følger:

--ns3::PointToPointChannel::Delay=[0ns]:
Transmission delay through the channel

Vi kan derefter, gennem kommandolinjesystemet, indstille begge disse standardværdier.

$ ./waf --run "scratch/myfirst
--ns3::PointToPointNetDevice::DataRate=5Mbps
--ns3::PointToPointChannel::Delay=2ms"

i dette tilfælde gendanner vi den tid, vi havde, da vi eksplicit indstillede DataRate og Delay i scriptet:

Waf: Entering directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' finished successfully (0.417s)
0s UdpEchoServerApplication:UdpEchoServer()
1s UdpEchoServerApplication:StartApplication()
Sent 1024 bytes to 10.1.1.2
2.00369s Received 1024 bytes from 10.1.1.1
2.00369s Echoing packet
Received 1024 bytes from 10.1.1.2
10s UdpEchoServerApplication:StopApplication()
UdpEchoServerApplication:DoDispose()
UdpEchoServerApplication:~UdpEchoServer()

Bemærk, at pakken modtages af serveren igen efter 2,00369 sekunder. Vi kunne faktisk indstille enhver af de attributter, der blev brugt i scriptet på denne måde. Især kunne vi indstille MaxPackets-attributterne til ikke-én-værdier UdpEchoClient.

Hvordan ville du bruge det? Giv det en chance. Husk, at du skal kommentere det sted, hvor vi tilsidesætter standardattributværdien og udtrykkeligt angivet MaxPackets i manuskriptet. Så skal du genopbygge scriptet. Du kan også bruge kommandolinjen til at få syntakshjælp til at indstille en ny standardattributværdi. Når du forstår dette, kan du kontrollere antallet af pakker, der vises på kommandolinjen. Da vi er flittige mennesker, skulle vores kommandolinje se sådan ud:

$ ./waf --run "scratch/myfirst
--ns3::PointToPointNetDevice::DataRate=5Mbps
--ns3::PointToPointChannel::Delay=2ms
--ns3::UdpEchoClient::MaxPackets=2"

Det naturlige spørgsmål, der opstår på dette tidspunkt, er, hvordan man ved om eksistensen af ​​alle disse egenskaber. Igen har kommandolinjesystemet en hjælpefunktion til denne sag. Hvis vi beder kommandolinjen om hjælp, bør vi se:

$ ./waf --run "scratch/myfirst --PrintHelp"
myfirst [Program Arguments] [General Arguments]
General Arguments:
--PrintGlobals: Print the list of globals.
--PrintGroups: Print the list of groups.
--PrintGroup=[group]: Print all TypeIds of group.
--PrintTypeIds: Print all TypeIds.
--PrintAttributes=[typeid]: Print all attributes of typeid.
--PrintHelp: Print this help message.

Hvis du vælger argumentet "PrintGroups" skulle du se en liste over alle registrerede grupper TypeId. Gruppenavnene stemmer overens med navnene på modulerne i kildebiblioteket (omend med stort). At udskrive al information på én gang ville være for omfangsrig, så et ekstra filter er tilgængeligt til at udskrive oplysninger efter gruppe. Så igen med fokus på punkt-til-punkt-modulet:

./waf --run "scratch/myfirst --PrintGroup=PointToPoint"
TypeIds in group PointToPoint:
ns3::PointToPointChannel
ns3::PointToPointNetDevice
ns3::PointToPointRemoteChannel
ns3::PppHeader

Her kan du finde tilgængelige TypeId-navne til attributopslag, for eksempel i
--PrintAttributes = ns3 :: PointToPointChannelsom vist ovenfor.

En anden måde at lære om attributter er gennem Doxygen ns-3. Der er en side, der viser alle de attributter, der er registreret i simulatoren.

5.2.2 Indfangning af dine egne kommandoer

Du kan også tilføje dine egne kroge via kommandolinjesystemet. Dette gøres ganske enkelt ved at bruge kommandolinjeparsermetoden Tilføj værdi.
Lad os bruge denne funktion til at angive antallet af pakker, der skal vises på en helt anden måde. Lad os tilføje en lokal variabel kaldet nPakker ind i en funktion main. Vi indstiller den til én for at matche vores tidligere standardadfærd. For at tillade kommandolinjeparseren at ændre denne værdi, skal vi fange denne værdi i parseren. Det gør vi ved at tilføje et opkald Tilføj værdi. Gå og skift scriptet scratch/myfirst.cc så for at starte med følgende kode,

int
main (int argc, char *argv[])
{
uint32_t nPackets = 1;
CommandLine cmd;
cmd.AddValue("nPackets", "Number of packets to echo", nPackets);
cmd.Parse (argc, argv);
...

Rul ned til det punkt i scriptet, hvor vi sætter MaxPackets-attributten og ændrer den, så den sættes til nPackets-variablen i stedet for konstanten 1, som vist nedenfor.

echoClient.SetAttribute ("MaxPackets", UintegerValue (nPackets));

Hvis du nu kører scriptet og angiver -PrintHelp-argumentet, skulle du se det nye brugerargument. angivet på hjælpedisplayet. Gå ind,

$ ./waf --run "scratch/myfirst --PrintHelp"
Waf: Entering directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' finished successfully (0.403s)
--PrintHelp: Print this help message.
--PrintGroups: Print the list of groups.
--PrintTypeIds: Print all TypeIds.
--PrintGroup=[group]: Print all TypeIds of group.
--PrintAttributes=[typeid]: Print all attributes of typeid.
--PrintGlobals: Print the list of globals.
User Arguments:
--nPackets: Number of packets to echo

Hvis du vil ændre antallet af transmitterede pakker, kan du gøre det ved at indstille kommandolinjeargumentet - -nPackets.

$ ./waf --run "scratch/myfirst --nPackets=2"

Nu skulle du nu se

Waf: Entering directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' finished successfully (0.404s)
0s UdpEchoServerApplication:UdpEchoServer()
1s UdpEchoServerApplication:StartApplication()
Sent 1024 bytes to 10.1.1.2
2.25732s Received 1024 bytes from 10.1.1.1
2.25732s Echoing packet
Received 1024 bytes from 10.1.1.2
Sent 1024 bytes to 10.1.1.2
3.25732s Received 1024 bytes from 10.1.1.1
3.25732s Echoing packet
Received 1024 bytes from 10.1.1.2
10s UdpEchoServerApplication:StopApplication()
UdpEchoServerApplication:DoDispose()
UdpEchoServerApplication:~UdpEchoServer()

Du har nu sendt to pakker. Ret simpelt, er det ikke?
Du kan se, at du som ns-3-bruger kan bruge kommandolinje-argumentsystemet til at manipulere globale værdier og attributter. Hvis du er modelforfatteren, kan du tilføje nye attributter til dine objekter, og de vil automatisk være tilgængelige for konfiguration af dine brugere via kommandolinjesystemet. Hvis du er scriptforfatter, kan du tilføje nye variabler til dine scripts og problemfrit tilslutte dem til dit kommandolinjesystem.

5.3 Brug af sporingssystemet

Hele pointen med modellering er at generere output til yderligere undersøgelse, og ns-3 sporingssystemet er hovedmekanismen for dette. Da ns-3 er et C++-program, kan standardmetoder til at generere output fra et C++-program bruges:

#include <iostream>
...
int main ()
{
...
std::cout << "The value of x is " << x << std::endl;
...
}

Du kan endda bruge et logningsmodul til at tilføje lidt struktur til din løsning. Der er mange kendte problemer forårsaget af denne tilgang, og derfor har vi leveret et generelt hændelsessporing-undersystem til at løse disse problemer.

Hovedmålene for ns-3 sporingssystemet er:

  • Til grundlæggende opgaver bør sporingssystemet give brugeren mulighed for at generere en standardsporing for populære kilder og vælge objekter, der genererer sporingen;

  • Mellembrugere bør være i stand til at udvide sporingssystemet for at ændre det genererede outputformat eller for at indsætte nye sporkilder uden at ændre simulatorkernen;

  • Avancerede brugere kan ændre simulatorkernen for at tilføje nye sporkilder og dræn. ns-3-sporingssystemet er bygget på principperne om uafhængige sporingskilder og -modtagere, samt en samlet mekanisme til at forbinde kilder til forbrugere.

ns-3-sporingssystemet er bygget på principperne om uafhængige sporingskilder og -modtagere, samt en samlet mekanisme til at forbinde kilder til modtagere. Sporkilder er objekter, der kan signalere hændelser, der forekommer i simuleringen, og give adgang til de underliggende data af interesse. For eksempel kan en sporingskilde indikere, hvornår en netværksenhed har modtaget en pakke og gøre indholdet af pakken tilgængeligt for interesserede sporingsmodtagere.

Sporkilder i sig selv er ubrugelige, medmindre de er "koblet" med andre dele af koden, der rent faktisk gør noget nyttigt med informationen fra vasken. Tracers er forbrugere af begivenheder og data leveret af sporkilder. For eksempel kan du oprette en sporing, der (når den er tilsluttet sporkilden i det foregående eksempel) vil udskrive de dele af interesse i den modtagne pakke.

Begrundelsen for denne eksplicitte adskillelse er at give brugerne mulighed for at forbinde nye synketyper til eksisterende sporkilder uden at skulle redigere og omkompilere simulatorkernen. Så i eksemplet ovenfor kan brugeren kun definere en ny sporing i deres script og forbinde den til en eksisterende sporingskilde defineret i simuleringskernen ved at redigere brugerscriptet.

I denne vejledning gennemgår vi nogle af de foruddefinerede kilder og dræn og viser, hvordan de kan konfigureres med den mindste indsats fra brugerens side. Se ns-3 Manual eller how-to sektioner for information om avanceret sporingskonfiguration, herunder udvidelse af sporingsnavneområdet og oprettelse af nye sporingskilder.

5.3.1 ASCII-sporing

ns-3 giver hjælpefunktionalitet, der giver et sporingssystem på lavt niveau, der hjælper dig med detaljerne, når du opsætter enkle pakkespor. Hvis du aktiverer denne funktion, vil du se output i ASCII-filer. For dem, der er bekendt med ns-2 output, ligner denne type sporing ud.tr, som er genereret af mange scripts.

Lad os komme i gang og tilføje nogle ASCII-sporingsresultater til vores scratch/myfirst.cc-script. Lige før opkaldet Simulator :: Run (), tilføj følgende kodelinjer:
AsciiTraceHelper ascii;

pointToPoint.EnableAsciiAll (ascii.CreateFileStream ("myfirst.tr"));

Som mange andre ns-3 idiomer bruger denne kode et hjælpeobjekt til at skabe ASCII-spor. Den anden linje indeholder to indlejrede metodekald. "Indefra" metode CreateFileStream() bruger det anonyme objektformsprog til at oprette et filstreamobjekt på stakken (uden et objektnavn) og sender det til den kaldte metode. Vi vil gå dybere ind i dette i fremtiden, men alt hvad du behøver at vide på dette tidspunkt er, at du opretter et objekt, der repræsenterer en fil kaldet myfirst.tr og overfør det til ns-3. Vi overlader ns-3 til at tage sig af det oprettede objekt i hele dets levetid, hvor det løser problemer forårsaget af en lidet kendt (tilsigtet) begrænsning forbundet med C++-streamobjektkopikonstruktører.

Eksternt opkald EnableAsciiAll() fortæller assistenten, at du vil inkludere ASCII-sporing i din simulering for alle punkt-til-punkt enhedsforbindelser, og at du vil have (specificerede) sporingsmodtagere til at registrere pakkebevægelsesinformation i ASCII-format.

For dem, der er bekendt med ns-2, svarer sporede hændelser til de kendte sporpunkter, der logger hændelser "+", "-", "d" og "r".
Nu kan du bygge scriptet og køre det fra kommandolinjen:

$ ./waf --run scratch/myfirst

Som mange gange før, vil du se adskillige beskeder fra Waf, og derefter "'bygge' afsluttet med succes" med nogle beskeder fra det kørende program.

Når programmet kører, vil programmet oprette en fil med navnet myfirst.tr. På grund af arbejdets karakter Waf, som standard oprettes filen ikke i den lokale mappe, men i bibliotekets øverste niveau. Hvis du vil ændre stien, hvor spor gemmes, kan du bruge Waf-parameteren til at angive den --cwd. Vi har ikke gjort dette, så for at se på ASCII-sporingsfilen myfirst.tr i din yndlingseditor, bliver vi nødt til at navigere til biblioteket på øverste niveau i vores depot.

Parsing af ASCII-spor

Der er en masse information der i en ret tæt form, men det første du skal bemærke er, at filen består af individuelle linjer. Dette vil blive tydeligt synligt, hvis du udvider visningsvinduet bredere.

Hver linje i filen svarer til en sporingshændelse. I dette tilfælde sporer vi hændelser i transmissionskøen i hver punkt-til-punkt netværksenhed i simuleringen. Transmissionskøen er den kø, hvorigennem hver pakke skal passere for et punkt-til-punkt-link. Bemærk, at hver linje i sporingsfilen starter med et enkelt tegn (og har et mellemrum efter sig). Dette symbol vil have følgende betydning:

+: der opstod en køoperation på enhedskøen;
-: en element-hentningsoperation fandt sted i enhedskøen;
d: pakken blev droppet, normalt fordi køen var fuld;
r: Pakken blev modtaget af en netværksenhed.

Lad os se nærmere på den første linje i sporingsfilen. Jeg deler det op i dele (med fordybninger for tydelighedens skyld) og linjenummeret til venstre:

0 +
1 2
2 /NodeList/0/DeviceList/0/$ns3::PointToPointNetDevice/TxQueue/Enqueue
3 ns3::PppHeader (
4   Point-to-Point Protocol: IP (0x0021))
6   ns3::Ipv4Header (
7     tos 0x0 ttl 64 id 0 protocol 17 offset 0 flags [none]
8     length: 1052 10.1.1.1 > 10.1.1.2)
9     ns3::UdpHeader (
10      length: 1032 49153 > 9)
11      Payload (size=1024)

Den første del af denne udvidede sporingshændelse (linje 0) er operationen. Vi har her et + symbol, som svarer til driften af ​​kø til transmission. Det andet afsnit (linje 1) er simuleringstiden, udtrykt i sekunder. Du kan måske huske, hvad vi spurgte om UdpEchoClientApplication begynde at sende pakker om to sekunder. Her ser vi bekræftelse på, at det faktisk sker.

Det næste afsnit af sporingseksemplet (fra linje 2) viser, hvilken sporingskilde der genererede denne hændelse (angiver navneområdesporet). Du kan tænke på sporingsnavneområdet på samme måde som et filsystemnavneområde. Roden til navnerummet er Nodeliste. Dette svarer til den container, der administreres i ns-3-hovedkoden. Den indeholder alle de noder, der er oprettet i scriptet. Ligesom et filsystem kan have mapper i roden, Nodeliste vi kan have mange noder. Så linjen /NodeList/0 refererer til null-noden i NodeList, som vi normalt tænker på som "node 0". Hver node har en liste over enheder, der er blevet installeret. Denne liste er placeret ved siden af ​​i navnerummet. Du kan se, at denne sporbegivenhed kommer fra Enhedsliste/0, som er nul-enheden installeret i noden.

Næste understreng, $ ns3 :: PointToPointNetDevice, fortæller hvilken enhed der er i position nul: enhedslisten for node nul. Husk på, at +-operationen fundet i linje 0 betød, at et element blev tilføjet til enhedens sendekø. Dette afspejles i de sidste segmenter af "sporstien": TxQueue/Enqueue.

De resterende sektioner i sporet skal være ret intuitive. Linje 3-4 angiver, at pakken er indkapslet i en punkt-til-punkt protokol. Linje 5-7 viser, at pakken har en IP4-versionsheader og stammer fra IP-adressen 10.1.1.1 og er beregnet til 10.1.1.2. Linje 8-9 viser, at denne pakke har en UDP-header og endelig viser linje 10, at nyttelasten er de forventede 1024 bytes.

Den næste linje i sporingsfilen viser, at den samme pakke blev trukket fra transmissionskøen på den samme node.

Den tredje linje i sporingsfilen viser, at pakken blev modtaget af en netværksenhed på ekkoserverværten. Jeg har gengivet begivenheden nedenfor.

0 r
1 2.25732
2 /NodeList/1/DeviceList/0/$ns3::PointToPointNetDevice/MacRx
3   ns3::Ipv4Header (
4     tos 0x0 ttl 64 id 0 protocol 17 offset 0 flags [none]
5     length: 1052 10.1.1.1 > 10.1.1.2)
6     ns3::UdpHeader (
7       length: 1032 49153 > 9)
8       Payload (size=1024)

Bemærk, at sporingsoperationen nu er r, og simuleringstiden er blevet øget til 2,25732 sekunder. Hvis du fulgte vejledningen omhyggeligt, betyder det, at du forlod netværksenhedernes DataRate og Link Delay på deres standardværdier. Denne tid burde være bekendt, som du så i det foregående afsnit.

Sporingskildens navneområdeindgang (linje 2) er blevet ændret for at afspejle, at denne hændelse stammer fra node 1 (/Nodeliste/1) og pakken modtages af sporingskilden (/MacRx). Det burde være ret nemt for dig at følge pakkens bevægelse gennem topologien ved at se på de resterende spor i filen.

5.3.2 PCAP-sporing

ns-3 Device Helpers kan også bruges til at oprette sporingsfiler i .pcap-format. Akronym pcap (normalt skrevet med små bogstaver) står for packet capture og er faktisk en API, der inkluderer definition af .pcap-filformatet. Det mest populære program, der kan læse og vise dette format er Wireshark (tidligere kaldt Ethereal). Der er dog mange trafiksporingsanalysatorer, der bruger dette pakkeformat. Vi opfordrer brugerne til at bruge de mange tilgængelige værktøjer til at analysere pcap-spor. I denne tutorial vil vi fokusere på at se pcap-spor ved hjælp af tcpdump.

Aktivering af pcap-sporing udføres med én kodelinje.

pointToPoint.EnablePcapAll ("myfirst");

Indsæt denne kodelinje efter ASCII-sporingskoden, vi lige har tilføjet scratch/myfirst.cc. Bemærk, at vi kun bestod strengen "myfirst", ikke "myfirst.pcap" eller noget lignende. Dette skyldes, at parameteren er et præfiks, ikke et fuldt filnavn. Under simuleringen vil assistenten faktisk oprette en sporingsfil for hver punkt-til-punkt enhed. Filnavne vil blive konstrueret ved hjælp af præfiks, nodenummer, enhedsnummer og suffiks ".pcap'.

For vores eksempelscript ender vi med at se filer med navnet "myfirst-0-0.pcap"Og"myfirst-1-0.pcap", som er pcap-spor for henholdsvis node 0-enhed 0 og node 1-enhed 0. Når du har tilføjet kodelinjen for at aktivere pcap-sporing, kan du køre scriptet på den sædvanlige måde:

$ ./waf --run scratch/myfirst

Hvis du kigger i mappen på øverste niveau i din distribution, bør du se tre filer: en ASCII-sporingsfil myfirst.tr, som vi tidligere har studeret, filer myfirst-0-0.pcap и myfirst-1-0.pcap - nye pcap-filer, som vi lige har genereret.

Læser output med tcpdump

Indtil videre er den nemmeste måde at se pcap-filer på at bruge tcpdump.

$ tcpdump -nn -tt -r myfirst-0-0.pcap
reading from file myfirst-0-0.pcap, link-type PPP (PPP)
2.000000 IP 10.1.1.1.49153 > 10.1.1.2.9: UDP, length 1024
2.514648 IP 10.1.1.2.9 > 10.1.1.1.49153: UDP, length 1024
tcpdump -nn -tt -r myfirst-1-0.pcap
reading from file myfirst-1-0.pcap, link-type PPP (PPP)
2.257324 IP 10.1.1.1.49153 > 10.1.1.2.9: UDP, length 1024
2.257324 IP 10.1.1.2.9 > 10.1.1.1.49153: UDP, length 1024

På lossepladsen myfirst-0-0.pcap (klientenhed) kan du se ekkopakken sendes efter 2 sekunders simulering. Hvis du ser på den anden losseplads (myfirst-1-0.pcap), vil du se, at pakken modtages på 2,257324 sekunder. Du vil se i det andet dump, at pakken returneres ved 2.257324 sekunder, og til sidst, at pakken blev modtaget tilbage af klienten i det første dump ved 2.514648 sekunder.

Læseoutput med Wireshark

Hvis du ikke er bekendt med Wireshark, er der en hjemmeside, hvorfra du kan downloade programmer og dokumentation: http://www.wireshark.org/. Wireshark er en GUI, der kan bruges til at vise disse sporingsfiler. Hvis du har Wireshark, kan du åbne enhver af sporingsfilerne og vise indholdet, som om du havde fanget pakkerne ved hjælp af en pakkesniffer.

Kilde: www.habr.com

Tilføj en kommentar