Tutorial sul simulatore di rete ns-3. capitolo 5

Tutorial sul simulatore di rete ns-3. capitolo 5
capitolo 1,2
capitolo 3
capitolo 4

5 Impostazione
5.1 Utilizzo del modulo di logging
5.1.1 Panoramica della registrazione
5.1.2 Abilita la registrazione
5.1.3 Aggiunta della registrazione al codice
5.2 Utilizzo degli argomenti della riga di comando
5.2.1 Sostituzione dei valori degli attributi predefiniti
5.2.2 Catturare i propri comandi
5.3 Utilizzo del sistema di tracciabilità
5.3.1 Tracciatura ASCII
Analisi delle tracce ASCII
5.3.2 Traccia PCAP

Capitolo 5

registrazione

5.1 Utilizzo del modulo di logging

Abbiamo già esaminato brevemente il modulo di registrazione ns-3 osservando lo script prima.cc. In questo capitolo esamineremo più da vicino i possibili utilizzi del sottosistema di logging.

5.1.1 Panoramica della registrazione

Molti sistemi di grandi dimensioni supportano qualche tipo di funzionalità di registrazione dei messaggi e ns-3 non fa eccezione. In alcuni casi, solo i messaggi di errore vengono scritti sulla "console dell'operatore" (che di solito è stderr sui sistemi basati su Unix). Su altri sistemi potrebbero essere visualizzati messaggi di avviso e informazioni più dettagliate. In alcuni casi, gli strumenti di registrazione vengono utilizzati per generare messaggi di debug che possono rapidamente offuscare l'output.

Il subHRD utilizzato in ns-3 presuppone che tutti questi livelli di contenuto informativo siano utili e forniamo un approccio selettivo e stratificato alla registrazione dei messaggi. La registrazione può essere disabilitata completamente, abilitata per componente o globalmente. A questo scopo vengono utilizzati livelli regolabili di contenuto informativo. Il modulo di registrazione ns-3 fornisce un modo relativamente semplice per ottenere informazioni utili dalla simulazione.

Dovresti capire che forniamo un meccanismo generale, il tracciamento, per estrarre i dati dai tuoi modelli, che dovrebbe essere l'output preferito per le simulazioni (per ulteriori informazioni sul nostro sistema di tracciamento, vedere la sezione 5.3 del tutorial). La registrazione dovrebbe essere il metodo preferito per ottenere informazioni di debug, avvisi, messaggi di errore o per generare rapidamente messaggi dai propri script o modelli in qualsiasi momento.

Attualmente il sistema definisce sette livelli (tipi) di messaggi di log in ordine crescente di contenuto informativo.

  • LOG_ERROR - registrazione dei messaggi di errore (macro correlata: NS_LOG_ERROR);
  • LOG_WARN - Registra messaggi di avviso (macro correlata: NS_LOG_WARN);
  • LOG_DEBUG - Registra messaggi di debug speciali relativamente rari (macro correlata: NS_LOG_DEBUG);
  • LOG_INFO - registrazione dei messaggi informativi sullo stato di avanzamento del programma (macro correlata: NS_LOG_INFO);
  • LOG_FUNCTION - Registra i messaggi che descrivono ciascuna funzione chiamata (due macro correlate: NS_LOG_FUNCTION, utilizzata per le funzioni membro e NS_LOG_FUNCTION_NOARGS, utilizzata per le funzioni statiche);
  • LOG_LOGIC - messaggi di registrazione che descrivono il flusso logico all'interno di una funzione (macro correlata: NS_LOG_LOGIC);
  • LOG_ALL - Registra tutto ciò che è stato menzionato sopra (nessuna macro associata).
    Per ogni tipo (LOG_TYPE) esiste anche un LOG_LEVEL_TYPE che, se utilizzato, consente di registrare tutti i livelli superiori oltre al proprio livello. (Di conseguenza, LOG_ERROR e LOG_LEVEL_ERROR e LOG_ALL e LOG_LEVEL_ALL sono funzionalmente equivalenti.) Ad esempio, l'abilitazione di LOG_INFO consentirà solo i messaggi forniti dalla macro NS_LOG_INFO, mentre l'abilitazione di LOG_LEVEL_INFO includerà anche i messaggi forniti dalle macro NS_LOG_DEBUG, NS_LOG_WARN e NS_LOG_ERROR.

Forniamo anche una macro di registrazione incondizionata che viene sempre visualizzata, indipendentemente dal livello di registrazione o dal componente di selezione.

  • NS_LOG_UNCOND: registrazione incondizionata del messaggio associato (nessun livello di registrazione associato).

Ogni livello può essere interrogato individualmente o cumulativamente. La registrazione può essere configurata utilizzando la variabile di ambiente sh NS_LOG o registrando una chiamata di funzione di sistema. Come mostrato in precedenza, il sistema di registrazione dispone della documentazione Doxygen e ora è il momento giusto per esaminarla se non l'hai già fatto.

Ora che hai letto la documentazione in modo molto dettagliato, utilizziamo questa conoscenza per ottenere alcune informazioni interessanti dallo script di esempio gratta/ilmioprimo.ccche hai già compilato.

5.1.2 Abilita la registrazione

Usiamo la variabile d'ambiente NS_LOG per eseguire altri log, ma prima, giusto per orientarti, esegui l'ultimo script come hai fatto prima,

$ ./waf --run scratch/myfirst

Dovresti vedere l'output familiare del primo programma di esempio ns-3

$ 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

Si scopre che i messaggi "inviati" e "ricevuti" che vedi sopra sono in realtà messaggi registrati Applicazione UdpEchoClient и UdpEchoServerApplicazione. Ad esempio, possiamo chiedere all'applicazione client di stampare informazioni aggiuntive impostando il suo livello di registrazione tramite la variabile d'ambiente NS_LOG.

D'ora in poi, suppongo che tu stia utilizzando una shell simile a sh che utilizza la sintassi "VARIABILE=valore". Se stai usando una shell simile a csh, dovrai convertire i miei esempi nella sintassi "setenv variable value" richiesta da quelle shell.

Attualmente, l'applicazione client echo UDP risponde alla seguente riga di codice in gratta/ilmioprimo.cc,

LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO);

Abilita il livello di registrazione LOG_LEVEL_INFO. Quando passiamo un flag di livello di registrazione, abilitiamo effettivamente quel livello e tutti i livelli inferiori. In questo caso, abbiamo abilitato NS_LOG_INFO, NS_LOG_DEBUG, NS_LOG_WARN e NS_LOG_ERROR. Possiamo aumentare il livello di logging e ottenere maggiori informazioni, senza modifiche allo script e ricompilazione, impostando la variabile d'ambiente NS_LOG come segue:

$ export NS_LOG=UdpEchoClientApplication=level_all

Quindi impostiamo la variabile della shell sh NS_LOG sul valore seguente,

UdpEchoClientApplication=level_all

Il lato sinistro dell'assegnazione è il nome del componente registrato che vogliamo configurare e il lato destro è il flag che vogliamo applicargli. In questo caso, abiliteremo tutti i livelli di debug nell'applicazione. Se esegui lo script con NS_LOG impostato in questo modo, il sistema di registrazione ns-3 accetterà le modifiche e dovresti vedere il seguente 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()

Ulteriori informazioni di debug fornite dall'applicazione sono ora al livello NS_LOG_FUNCTION. Mostra ogni istanza di una chiamata di funzione durante l'esecuzione dello script. Come regola generale, nelle funzioni di metodo è preferibile utilizzare (come minimo)NS_LOG_FUNCTION (this)... Utilizzo NS_LOG_FUNCTION_NOARGS ()
solo nelle funzioni statiche. Tuttavia, tieni presente che il sistema ns-3 non è tenuto a supportare alcuna funzionalità di registrazione. La decisione sulla quantità di informazioni da registrare è lasciata al singolo sviluppatore del modello. Nel caso delle applicazioni echo è disponibile una grande quantità di output di registrazione.

È ora possibile visualizzare un registro delle chiamate di funzione effettuate dall'applicazione. Se guardi da vicino, noterai i due punti tra la linea Applicazione UdpEchoClient e il nome del metodo, dove potresti aspettarti di vedere l'operatore di ambito C++ (: :). Questo è intenzionale.

Questo non è in realtà il nome della classe, ma il nome del componente di registrazione. Quando c'è una corrispondenza tra un file sorgente e una classe, di solito è il nome della classe, ma dovresti tenere presente che in realtà non è il nome della classe e ci sono due punti singoli invece di due punti doppi. Questo è un modo per aiutarti a separare concettualmente il nome del bean di registrazione dal nome della classe in modo relativamente sottile.

Tuttavia, in alcuni casi può essere difficile determinare quale metodo sta effettivamente generando il messaggio di registro. Se guardi il testo sopra, potresti chiederti dove si trova la riga "Received 1024 bytes from 10.1.1.2" Puoi risolvere questo problema impostando il livello prefisso_funzione alla variabile di ambiente NS_LOG. Prova quanto segue:

$ export 'NS_LOG=UdpEchoClientApplication=level_all|prefix_func'

Tieni presente che le virgolette sono necessarie perché anche la barra verticale che usiamo per rappresentare l'operazione OR è un connettore di pipe Unix. Ora, se esegui lo script, vedrai che il sistema di registrazione garantisce che ogni messaggio in un dato registro abbia il prefisso con il nome del componente.

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

Ora puoi vedere che tutti i messaggi provenienti dall'applicazione client echo UDP sono identificati come tali. Messaggio "Received 1024 bytes from 10.1.1.2" è ora chiaramente identificato come proveniente dall'applicazione client echo. Il messaggio rimanente deve provenire dall'applicazione server echo UDP. Possiamo abilitare questo componente inserendo un elenco di componenti separati da due punti nella variabile di ambiente NS_LOG.

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

Attenzione: nel testo di esempio sopra, dovrai rimuovere il carattere di nuova riga dopo i due punti (:), viene utilizzato per formattare il documento. Ora se esegui lo script, vedrai tutti i messaggi di registro dalle applicazioni echo client e server. Puoi vedere che questo può essere molto utile durante il debug.

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

A volte è anche utile poter vedere l'ora della simulazione in cui è stato generato il messaggio di registro. Puoi farlo aggiungendo il bit OR prefisso_ora:

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

Ancora una volta, dovrai rimuovere il carattere di nuova riga sopra. Se ora esegui lo script dovresti vedere il seguente 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()

Si prega di notare che il costruttore for UdpEchoServer è stato chiamato durante la simulazione 0 secondi. Ciò avviene effettivamente prima dell'inizio della simulazione, ma il tempo viene visualizzato come zero secondi. Lo stesso vale per il messaggio del costruttore 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()

Ricordiamo che la sceneggiatura graffio/primo.cc ha avviato l'applicazione echo server un secondo prima dell'inizio della simulazione. Ora puoi vedere che il metodo AvviaApplicazione il server viene effettivamente chiamato nel primo secondo. Potresti anche notare che il client echo si avvia nel secondo secondo della simulazione, come richiesto nello script.

Ora puoi seguire l'avanzamento della simulazione durante la chiamata ProgrammaTrasmissione nel client che chiama il callback HandleRead Invia nell'applicazione echo server. Si noti che il tempo trascorso per inviare un pacchetto su un collegamento punto a punto è 3,69 millisecondi. Puoi vedere che l'echo server registra un messaggio di risposta al pacchetto e poi, dopo un ritardo del canale, vedi che l'echo client riceve il pacchetto echo nel suo metodo HandleRead.

In questa simulazione succedono molte cose senza che tu te ne accorga. Ma puoi monitorare l'intero processo molto facilmente abilitando tutti i componenti di registrazione nel sistema. Prova a impostare la variabile NS_LOG sul seguente valore,

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

L'asterisco sopra è un carattere jolly per il componente di registrazione. Ciò includerà tutte le voci in tutti i componenti utilizzati nella simulazione. Non riprodurrò l'output qui (al momento in cui scrivo produce 1265 righe di output per un singolo pacchetto echo), ma puoi reindirizzare queste informazioni su un file e visualizzarle nel tuo editor preferito.

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

Personalmente utilizzo questa versione estremamente dettagliata della registrazione quando ho un problema e non ho idea di dove le cose siano andate storte. Posso seguire l'esecuzione del codice abbastanza facilmente senza impostare punti di interruzione e senza scorrere il codice nel debugger. Posso semplicemente modificare l'output nel mio editor preferito e cercare ciò che mi aspetto e vedere accadere qualcosa che non mi aspettavo. Una volta che ho un'idea generale di cosa non va, entro nel debugger per approfondire il problema. Questo tipo di output può essere particolarmente utile quando il tuo script fa qualcosa di completamente inaspettato. Se usi solo il debugger, potresti perdere completamente una svolta. La registrazione rende evidenti tali svolte.

5.1.3 Aggiunta della registrazione al codice

Puoi aggiungere nuove voci alle tue simulazioni effettuando chiamate al componente log da più macro. Facciamolo in uno script mioprimo.cc, che abbiamo nella directory "clean". Ricordiamo che abbiamo definito un componente di registrazione in questo scenario:

NS_LOG_COMPONENT_DEFINE ("FirstScriptExample");

Sei consapevole che puoi abilitare la registrazione di tutti i messaggi da questo componente impostando la variabile di ambiente NS_LOG a livelli diversi. Andiamo avanti e aggiungiamo alcune voci allo script. La macro utilizzata per aggiungere messaggi a livello di informazioni al registro è NS_LOG_INFO. Aggiungiamo un messaggio (appena prima di iniziare a creare i nodi) che informa che lo script è nella fase di "Creazione della topologia". Questo viene fatto nel seguente frammento di codice,
Apri gratta/ilmioprimo.cc nel tuo editor preferito e aggiungi la riga,
NS_LOG_INFO ("Creating Topology");
proprio prima delle righe,

NodeContainer nodes;
nodes.Create (2);

Ora compila lo script usando wafe deselezionare la variabile NS_LOG per disabilitare il flusso di registrazione abilitato in precedenza:

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

Non vedrai il nuovo messaggio perché il componente di registrazione associato (FirstScriptExample) non è stato abilitato. Per vedere il tuo messaggio devi abilitare il componente di registrazione FirstScriptEsempio con un livello non inferiore a NS_LOG_INFO. Se vuoi solo vedere questo livello di registrazione specifico, puoi abilitarlo in questo modo,

$ export NS_LOG=FirstScriptExample=info

Se esegui lo script ora, vedrai un nuovo messaggio "Creazione della topologia",

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 Utilizzo degli argomenti della riga di comando

5.2.1 Sostituzione dei valori degli attributi predefiniti

Un altro modo per modificare il comportamento degli script ns-3 senza modificarli o compilarli è utilizzare gli argomenti della riga di comando. Forniamo un meccanismo per analizzare gli argomenti della riga di comando e impostare automaticamente variabili locali e globali in base ai risultati.

Il primo passo nell'utilizzo del sistema di argomenti della riga di comando è dichiarare un parser della riga di comando. Questo è abbastanza facile da fare (nel tuo programma principale), come nel seguente codice,

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

Questo semplice snippet di due righe è in realtà molto utile di per sé. Apre le porte al sistema di variabili e attributi globali ns-3. Aggiungiamo due righe di codice all'inizio della funzione dello script principale gratta/ilmioprimo.cc. Andando avanti, compiliamo lo script e lo eseguiamo, durante l'esecuzione facciamo una richiesta di aiuto come segue,

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

Questo comando chiederà Waf eseguire lo script graffio/il mio primo e passargli un argomento della riga di comando —StampaAiuto. Le virgolette sono necessarie per indicare a quale programma è destinato l'argomento. Il parser della riga di comando rileverà l'argomento —StampaAiuto e visualizzerà la risposta,

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.

Ora diamo un'occhiata all'opzione —Attributi di stampa. Abbiamo già menzionato il sistema di attributi ns-3 studiando lo script first.cc. Abbiamo visto le seguenti righe di codice,

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

e lo hanno detto Velocità dati è in realtà un attributo Dispositivo PointToPointNet. Usiamo il parser degli argomenti della riga di comando per visualizzare gli attributi Dispositivo PointToPointNet. L'elenco degli aiuti dice cosa dobbiamo fornire ID tipo. Questo è il nome della classe a cui appartengono gli attributi di interesse. Nel nostro caso lo sarà ns3::PointToPointNetDevice. Continuiamo ad andare avanti, entriamo,

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

Il sistema stamperà tutti gli attributi di questo tipo di dispositivo di rete. Vedrai che tra gli attributi nell'elenco ci sono,

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

Questo è il valore predefinito che verrà utilizzato dal sistema durante la creazione dell'oggetto Dispositivo PointToPointNet. Sostituiremo questo valore predefinito utilizzando il parametro Attributo в PuntoAPuntoHelper più alto. Usiamo i valori predefiniti per dispositivi e canali punto-punto. Per fare ciò, elimineremo le chiamate Imposta attributo dispositivo и SetChannelAttribute di mioprimo.cc, che abbiamo in una directory pulita.

Il tuo script ora dovrebbe semplicemente dichiarare PuntoAPuntoHelper e non eseguire alcuna operazione di installazione come mostrato nell'esempio seguente,

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

Vai avanti e crea un nuovo script con Waf (./waf) e torniamo indietro e includiamo alcune voci dall'applicazione server echo UDP e includiamo il prefisso temporale.

$ export 'NS_LOG=UdpEchoServerApplication=level_all|prefix_time'

Se esegui lo script dovresti vedere il seguente 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()

Ricordiamo che l'ultima volta che abbiamo osservato il tempo di simulazione, nel momento in cui il pacchetto è stato ricevuto dall'echo server, era di 2,00369 secondi.

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

Ora riceve il pacchetto in 2.25732 secondi. Questo perché abbiamo semplicemente reimpostato la velocità dati PointToPointNetDevice da cinque megabit al secondo al valore predefinito, ovvero 32768 bit al secondo. Se dovessimo sostituire un nuovo DataRate utilizzando la riga di comando, potremmo accelerare nuovamente la nostra simulazione. Lo faremo come segue, secondo la formula implicita nell'elemento help:

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

Ciò riporterà l'attributo DataRate al valore predefinito di cinque megabit al secondo. Sei sorpreso dal risultato? Si scopre che per restituire il comportamento originale dello script, dobbiamo anche impostare il ritardo del canale in modo che corrisponda alla velocità della luce. Possiamo chiedere al sistema a riga di comando di stampare gli attributi del canale, proprio come abbiamo fatto per il dispositivo di rete:

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

Troveremo che l'attributo di ritardo del canale è impostato come segue:

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

Possiamo quindi, tramite il sistema a riga di comando, impostare entrambi questi valori predefiniti.

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

in questo caso ripristiniamo il tempo che avevamo quando abbiamo impostato esplicitamente DataRate e Delay nello script:

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

Si noti che il pacchetto viene ricevuto nuovamente dal server dopo 2,00369 secondi. Potremmo effettivamente impostare qualsiasi attributo utilizzato nello script in questo modo. In particolare, potremmo impostare gli attributi MaxPackets su valori diversi da uno UdpEchoClient.

Come lo useresti? Provaci. Ricorda che devi commentare il punto in cui sovrascriviamo il valore dell'attributo predefinito e lo impostiamo esplicitamente MaxPackets nella sceneggiatura. Quindi è necessario ricostruire lo script. È inoltre possibile utilizzare la riga di comando per ottenere assistenza sulla sintassi per l'impostazione di un nuovo valore di attributo predefinito. Una volta compreso questo, puoi controllare il numero di pacchetti visualizzati sulla riga di comando. Dato che siamo persone studiose, la nostra riga di comando dovrebbe assomigliare a questa:

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

La domanda naturale che sorge a questo punto è come conoscere l’esistenza di tutti questi attributi. Ancora una volta, il sistema a riga di comando ha una funzione di aiuto per questo argomento. Se chiediamo aiuto alla riga di comando, dovremmo vedere:

$ ./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.

Se selezioni l'argomento "PrintGroups" dovresti vedere un elenco di tutti i gruppi registrati ID tipo. I nomi dei gruppi sono coerenti con i nomi dei moduli nella directory di origine (anche se in maiuscolo). Stampare tutte le informazioni in una volta sarebbe troppo voluminoso, quindi è disponibile un filtro aggiuntivo per stampare le informazioni per gruppo. Quindi, concentrandoci ancora una volta sul modulo punto-punto:

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

Qui puoi trovare i nomi TypeId disponibili per le ricerche di attributi, ad esempio in
--PrintAttributes = ns3 :: PointToPointChannelcome mostrato sopra.

Un altro modo per conoscere gli attributi è tramite Doxygen ns‑3. C'è una pagina che elenca tutti gli attributi registrati nel simulatore.

5.2.2 Catturare i propri comandi

Puoi anche aggiungere i tuoi hook tramite il sistema a riga di comando. Questo viene fatto semplicemente utilizzando il metodo parser della riga di comando Aggiungere valore.
Usiamo questa funzionalità per specificare il numero di pacchetti da visualizzare in un modo completamente diverso. Aggiungiamo una variabile locale chiamata nPacchetti in una funzione principale. Lo imposteremo su uno in modo che corrisponda al nostro comportamento predefinito precedente. Per consentire al parser della riga di comando di modificare questo valore, dobbiamo acquisire questo valore nel parser. Lo facciamo aggiungendo una chiamata Aggiungere valore. Vai e cambia la sceneggiatura gratta/ilmioprimo.cc quindi per iniziare con il seguente codice,

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

Scorri verso il basso fino al punto dello script in cui impostiamo l'attributo MaxPackets e modificalo in modo che sia impostato sulla variabile nPackets anziché sulla costante 1, come mostrato di seguito.

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

Ora se esegui lo script e fornisci l'argomento -PrintHelp, dovresti vedere il nuovo argomento utente. elencati nella schermata della guida. Accedere,

$ ./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

Se desideri modificare il numero di pacchetti trasmessi, puoi farlo impostando l'argomento della riga di comando - -nPackets.

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

Ora dovresti vedere

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

Ora hai inviato due pacchi. Abbastanza semplice, non è vero?
Puoi vedere che come utente ns-3, puoi utilizzare il sistema di argomenti della riga di comando per manipolare valori e attributi globali. Se sei l'autore del modello, puoi aggiungere nuovi attributi ai tuoi oggetti e questi saranno automaticamente disponibili per la configurazione da parte dei tuoi utenti tramite il sistema a riga di comando. Se sei un autore di script, puoi aggiungere nuove variabili ai tuoi script e inserirli facilmente nel tuo sistema a riga di comando.

5.3 Utilizzo del sistema di tracciabilità

Lo scopo principale della modellazione è generare risultati per ulteriori studi e il sistema di tracce ns-3 è il meccanismo principale per questo. Poiché ns-3 è un programma C++, è possibile utilizzare mezzi standard per generare output da un programma C++:

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

Puoi anche utilizzare un modulo di registrazione per aggiungere una piccola struttura alla tua soluzione. Esistono molti problemi noti causati da questo approccio e pertanto abbiamo fornito un sottosistema generale di tracciamento degli eventi per risolverli.

Gli obiettivi principali del sistema di tracciamento ns-3 sono:

  • Per le attività di base, il sistema di tracciamento dovrebbe consentire all'utente di generare una traccia standard per fonti popolari e selezionare gli oggetti che generano la traccia;

  • Gli utenti intermedi dovrebbero essere in grado di estendere il sistema di tracciamento per modificare il formato di output generato o per inserire nuove fonti di tracciamento, senza modificare il nucleo del simulatore;

  • Gli utenti avanzati possono modificare il core del simulatore per aggiungere nuove origini e sink di traccia. Il sistema di tracciamento ns-3 si basa sui principi del tracciamento di fonti e ricevitori indipendenti, nonché su un meccanismo unificato per collegare le fonti ai consumatori.

Il sistema di tracciamento ns-3 si basa sui principi di sorgenti e ricevitori di tracciamento indipendenti, nonché su un meccanismo unificato per il collegamento di sorgenti e ricevitori. Le sorgenti di traccia sono oggetti che possono segnalare eventi che si verificano nella simulazione e fornire accesso ai dati sottostanti di interesse. Ad esempio, una sorgente di traccia può indicare quando un dispositivo di rete ha ricevuto un pacchetto e rendere disponibile il contenuto del pacchetto ai ricevitori di traccia interessati.

I sorgenti di traccia da soli sono inutili a meno che non siano "accoppiati" con altre parti del codice che effettivamente fanno qualcosa di utile con le informazioni fornite dal sink. I traccianti sono consumatori di eventi e dati forniti da origini di traccia. Ad esempio, è possibile creare un trace sink che (quando connesso alla sorgente di traccia dell'esempio precedente) stamperà le parti di interesse nel pacchetto ricevuto.

La logica di questa separazione esplicita è consentire agli utenti di connettere nuovi tipi di sink alle origini di traccia esistenti senza dover modificare e ricompilare il core del simulatore. Pertanto, nell'esempio precedente, l'utente può definire un nuovo tracciante nel proprio script e collegarlo a un'origine di traccia esistente definita nel nucleo della simulazione solo modificando lo script utente.

In questo tutorial, esamineremo alcune delle origini e dei sink predefiniti e mostreremo come possono essere configurati con il minimo sforzo da parte dell'utente. Consulta il manuale ns-3 o le sezioni pratiche per informazioni sulla configurazione avanzata della traccia, inclusa l'espansione dello spazio dei nomi della traccia e la creazione di nuove origini di traccia.

5.3.1 Tracciatura ASCII

ns-3 fornisce funzionalità di supporto che forniscono un sistema di tracciamento di basso livello per aiutarti con i dettagli durante l'impostazione di semplici tracce di pacchetti. Se abiliti questa funzione, vedrai l'output in file ASCII. Per chi ha familiarità con l'output di ns-2, questo tipo di traccia è simile a fuori.tr, che viene generato da molti script.

Andiamo al sodo e aggiungiamo alcuni risultati di tracciamento ASCII al nostro script scratch/myfirst.cc. Subito prima della chiamata Simulator :: Run (), aggiungi le seguenti righe di codice:
AsciiTraceHelper ascii;

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

Come molti altri idiomi ns-3, questo codice utilizza un oggetto helper per creare tracce ASCII. La seconda riga contiene due chiamate di metodi nidificati. Metodo "dentro". CreaFileStream() utilizza l'idioma dell'oggetto anonimo per creare un oggetto flusso di file nello stack (senza un nome oggetto) e lo passa al metodo chiamato. Approfondiremo questo argomento in futuro, ma tutto ciò che devi sapere a questo punto è che stai creando un oggetto che rappresenta un file chiamato il mio primo.tr e trasferirlo su ns-3. Affidiamo a ns-3 la cura dell'oggetto creato per tutta la sua vita, durante la quale risolve i problemi causati da una limitazione (intenzionale) poco conosciuta associata ai costruttori di copie di oggetti del flusso C++.

Chiamata esterna AbilitaAsciiTutto() indica all'assistente che desideri includere la traccia ASCII nella simulazione per tutte le connessioni dei dispositivi punto a punto e che desideri che i ricevitori di traccia (specificati) registrino le informazioni sul movimento dei pacchetti in formato ASCII.

Per chi ha familiarità con ns-2, gli eventi tracciati sono equivalenti ai noti tracepoint che registrano gli eventi "+", "-", "d" e "r".
Ora puoi creare lo script ed eseguirlo dalla riga di comando:

$ ./waf --run scratch/myfirst

Come molte volte prima, vedrai diversi messaggi da Waf, e poi "'build' terminato con successo" con alcuni messaggi dal programma in esecuzione.

Durante l'esecuzione, il programma creerà un file denominato il mio primo.tr. A causa della natura del lavoro Waf, per impostazione predefinita il file non viene creato nella directory locale, ma nella directory di livello superiore del repository. Se desideri modificare il percorso in cui vengono salvate le tracce, puoi utilizzare il parametro Waf per specificarlo --cwd. Non l'abbiamo fatto, quindi per esaminare il file di traccia ASCII myfirst.tr nel tuo editor preferito, dovremo accedere alla directory di livello superiore del nostro repository.

Analisi delle tracce ASCII

Ci sono molte informazioni in una forma abbastanza densa, ma la prima cosa che devi notare è che il file è composto da singole righe. Ciò diventerà chiaramente visibile se si espande ulteriormente la finestra di visualizzazione.

Ogni riga nel file corrisponde a un evento di traccia. In questo caso tracciamo gli eventi nella coda di trasmissione presente in ciascun dispositivo di rete punto-punto nella simulazione. La coda di trasmissione è la coda attraverso la quale deve passare ciascun pacchetto per un collegamento punto a punto. Tieni presente che ogni riga nel file di traccia inizia con un singolo carattere (e ha uno spazio dopo). Questo simbolo avrà il seguente significato:

+: si è verificata un'operazione di accodamento sulla coda del dispositivo;
-: si è verificata un'operazione di recupero di un elemento nella coda del dispositivo;
d: il pacchetto è stato scartato, solitamente perché la coda era piena;
r: il pacchetto è stato ricevuto da un dispositivo di rete.

Diamo un'occhiata più da vicino alla prima riga nel file di traccia. Lo suddividerò in parti (con rientranze per chiarezza) e il numero di riga a sinistra:

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)

La prima sezione di questo evento di traccia estesa (riga 0) è l'operazione. Qui abbiamo un simbolo +, che corrisponde all'operazione di accodamento per la trasmissione. La seconda sezione (riga 1) è il tempo di simulazione, espresso in secondi. Forse ricorderai cosa abbiamo chiesto Applicazione UdpEchoClient iniziare a inviare pacchetti tra due secondi. Qui vediamo la conferma che ciò sta effettivamente accadendo.

La sezione successiva dell'esempio di traccia (dalla riga 2) mostra quale origine di traccia ha generato questo evento (indicando la traccia dello spazio dei nomi). Puoi pensare allo spazio dei nomi di traccia in modo molto simile a uno spazio dei nomi di un filesystem. La radice dello spazio dei nomi è Elenco dei nodi. Questo corrisponde al contenitore gestito nel codice principale ns-3. Contiene tutti i nodi creati nello script. Proprio come un file system può avere directory alla radice, Elenco dei nodi possiamo avere molti nodi. Quindi la riga /NodeList/0 si riferisce al nodo nullo nella NodeList, che solitamente consideriamo "nodo 0". Ogni nodo ha un elenco di dispositivi che sono stati installati. Questo elenco si trova successivamente nello spazio dei nomi. Puoi vedere da dove proviene questo evento di traccia Elenco dispositivi/0, che è il dispositivo null installato nel nodo.

Sottostringa successiva, $ ns3 :: PointToPointNetDevice, indica quale dispositivo si trova nella posizione zero: l'elenco dei dispositivi del nodo zero. Ricordiamo che l'operazione + trovata nella riga 0 significava che un elemento era stato aggiunto alla coda di trasmissione del dispositivo. Ciò si riflette negli ultimi segmenti del “percorso del binario”: TxCoda/accodamento.

Le restanti sezioni della traccia dovrebbero essere abbastanza intuitive. Le righe 3-4 indicano che il pacchetto è incapsulato in un protocollo punto-punto. Le righe 5-7 mostrano che il pacchetto ha un'intestazione della versione IP4 e ha avuto origine nell'indirizzo IP 10.1.1.1 ed è destinato a 10.1.1.2. Le righe 8-9 mostrano che questo pacchetto ha un'intestazione UDP e infine la riga 10 mostra che il carico utile è pari ai 1024 byte previsti.

La riga successiva nel file di traccia mostra che lo stesso pacchetto è stato estratto dalla coda di trasmissione sullo stesso nodo.

La terza riga nel file di traccia mostra che il pacchetto è stato ricevuto da un dispositivo di rete sull'host del server echo. Ho riprodotto l'evento qui sotto.

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)

Si noti che l'operazione di traccia è ora r e il tempo di simulazione è stato aumentato a 2,25732 secondi. Se hai seguito attentamente il tutorial, significa che hai lasciato DataRate e Link Delay dei dispositivi di rete sui valori predefiniti. Questo tempo verbale dovrebbe esserti familiare, come hai visto nella sezione precedente.

La voce dello spazio dei nomi dell'origine di traccia (riga 2) è stata modificata per riflettere che questo evento ha origine dal nodo 1 (/Elenco dei nodi/1) e il pacchetto viene ricevuto dall'origine della traccia (/MacRx). Dovrebbe essere abbastanza semplice seguire il movimento del pacchetto attraverso la topologia osservando le tracce rimanenti nel file.

5.3.2 Traccia PCAP

Gli ns-3 Device Helper possono essere utilizzati anche per creare file di traccia in formato .pcap. Acronimo pcap (di solito scritto in minuscolo) sta per cattura di pacchetti ed è in realtà un'API che include la definizione del formato del file .pcap. Il programma più popolare in grado di leggere e visualizzare questo formato è Wireshark (precedentemente chiamato Etereo). Tuttavia, esistono molti analizzatori di tracciamento del traffico che utilizzano questo formato di pacchetto. Incoraggiamo gli utenti a utilizzare i numerosi strumenti disponibili per analizzare le tracce pcap. In questo tutorial ci concentreremo sulla visualizzazione delle tracce pcap utilizzando tcpdump.

L'abilitazione della traccia pcap viene eseguita con una riga di codice.

pointToPoint.EnablePcapAll ("myfirst");

Incolla questa riga di codice dopo il codice di traccia ASCII che abbiamo appena aggiunto gratta/ilmioprimo.cc. Tieni presente che abbiamo passato solo la stringa "myfirst", non "myfirst.pcap" o qualcosa di simile. Questo perché il parametro è un prefisso, non un nome file completo. Durante la simulazione l'assistente creerà effettivamente un file di traccia per ogni dispositivo punto-punto. I nomi dei file verranno costruiti utilizzando il prefisso, il numero del nodo, il numero del dispositivo e il suffisso ".pcap'.

Per il nostro script di esempio, finiremo per vedere i file denominati "mioprimo-0-0.pcap"E"mioprimo-1-0.pcap", che sono tracce pcap rispettivamente per il nodo 0-dispositivo 0 e il nodo 1-dispositivo 0. Dopo aver aggiunto la riga di codice per abilitare la traccia pcap, puoi eseguire lo script nel solito modo:

$ ./waf --run scratch/myfirst

Se guardi nella directory di livello superiore della tua distribuzione, dovresti vedere tre file: un file di traccia ASCII il mio primo.tr, che abbiamo studiato in precedenza, file mioprimo-0-0.pcap и mioprimo-1-0.pcap - nuovi file pcap che abbiamo appena generato.

Lettura dell'output con tcpdump

Per ora, il modo più semplice per visualizzare i file pcap è utilizzare 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

Nella discarica mioprimo-0-0.pcap (dispositivo client) è possibile vedere che il pacchetto echo viene inviato dopo 2 secondi di simulazione. Se guardi il secondo dump (mioprimo-1-0.pcap), vedrai che il pacchetto viene ricevuto in 2,257324 secondi. Vedrai nel secondo dump che il pacchetto viene restituito a 2.257324 secondi e infine che il pacchetto è stato ricevuto dal client nel primo dump a 2.514648 secondi.

Lettura dell'output con Wireshark

сли вы не знакомы с Wireshark, esiste un sito web da cui è possibile scaricare programmi e documentazione: http://www.wireshark.org/. Wireshark è una GUI che può essere utilizzata per visualizzare questi file di traccia. Se disponi di Wireshark, puoi aprire qualsiasi file di traccia e visualizzare il contenuto come se avessi catturato i pacchetti utilizzando uno sniffer di pacchetti.

Fonte: habr.com

Aggiungi un commento