Εκμάθηση προσομοιωτή δικτύου ns-3. κεφάλαιο 5

Εκμάθηση προσομοιωτή δικτύου ns-3. κεφάλαιο 5
κεφάλαιο 1,2
Κεφάλαιο 3
Κεφάλαιο 4

5 Ρυθμίσεις
5.1 Χρήση της μονάδας καταγραφής
5.1.1 Επισκόπηση καταγραφής
5.1.2 Ενεργοποίηση καταγραφής
5.1.3 Προσθήκη καταγραφής στον κώδικά σας
5.2 Χρήση ορισμάτων γραμμής εντολών
5.2.1 Παράκαμψη προεπιλεγμένων τιμών χαρακτηριστικών
5.2.2 Λήψη των δικών σας εντολών
5.3 Χρήση του συστήματος ανίχνευσης
5.3.1 Ανίχνευση ASCII
Ανάλυση ιχνών ASCII
5.3.2 PCAP Trace

Κεφάλαιο 5

προσαρμογή

5.1 Χρήση της μονάδας καταγραφής

Έχουμε ήδη εξετάσει εν συντομία τη μονάδα καταγραφής ns-3 κοιτάζοντας το σενάριο πρώτο.cc. Σε αυτό το κεφάλαιο, θα ρίξουμε μια πιο προσεκτική ματιά στις πιθανές χρήσεις για το υποσύστημα καταγραφής.

5.1.1 Επισκόπηση καταγραφής

Πολλά μεγάλα συστήματα υποστηρίζουν κάποιο είδος δυνατότητας καταγραφής μηνυμάτων και το ns-3 δεν αποτελεί εξαίρεση. Σε ορισμένες περιπτώσεις, μόνο μηνύματα σφάλματος γράφονται στην "κονσόλα χειριστή" (η οποία συνήθως είναι stderr σε συστήματα που βασίζονται σε Unix). Σε άλλα συστήματα, ενδέχεται να εμφανίζονται προειδοποιητικά μηνύματα καθώς και πιο λεπτομερείς πληροφορίες. Σε ορισμένες περιπτώσεις, τα εργαλεία καταγραφής χρησιμοποιούνται για την έξοδο μηνυμάτων εντοπισμού σφαλμάτων που μπορούν να θολώσουν γρήγορα την έξοδο.

Το subHRD που χρησιμοποιείται στο ns-3 υποθέτει ότι όλα αυτά τα επίπεδα περιεχομένου πληροφοριών είναι χρήσιμα και παρέχουμε μια επιλεκτική, πολυεπίπεδη προσέγγιση για την καταγραφή μηνυμάτων. Η καταγραφή μπορεί να απενεργοποιηθεί πλήρως, να ενεργοποιηθεί ανά στοιχείο ή καθολικά. Για το σκοπό αυτό, χρησιμοποιούνται ρυθμιζόμενα επίπεδα περιεχομένου πληροφοριών. Η μονάδα καταγραφής ns-3 παρέχει έναν σχετικά απλό τρόπο απόκτησης χρήσιμων πληροφοριών από την προσομοίωση σας.

Θα πρέπει να καταλάβετε ότι παρέχουμε έναν μηχανισμό γενικού σκοπού - ανίχνευση - για την εξαγωγή δεδομένων από τα μοντέλα σας, που θα πρέπει να είναι η προτιμώμενη έξοδος για προσομοιώσεις (για περισσότερες πληροφορίες σχετικά με το σύστημα ανίχνευσης, ανατρέξτε στην ενότητα εκμάθησης 5.3). Η καταγραφή θα πρέπει να είναι η προτιμώμενη μέθοδος για τη λήψη πληροφοριών εντοπισμού σφαλμάτων, προειδοποιήσεων, μηνυμάτων σφάλματος ή για γρήγορη έξοδο μηνυμάτων από τα σενάρια ή τα μοντέλα σας ανά πάσα στιγμή.

Επί του παρόντος, το σύστημα ορίζει επτά επίπεδα (τύπους) μηνυμάτων καταγραφής με αυξανόμενη σειρά περιεχομένου πληροφοριών.

  • LOG_ERROR - καταγραφή μηνυμάτων σφάλματος (σχετική μακροεντολή: NS_LOG_ERROR).
  • LOG_WARN - Προειδοποιητικά μηνύματα καταγραφής (σχετική μακροεντολή: NS_LOG_WARN).
  • LOG_DEBUG - Καταγραφή σχετικά σπάνιων ειδικών μηνυμάτων εντοπισμού σφαλμάτων (σχετική μακροεντολή: NS_LOG_DEBUG).
  • LOG_INFO - εγγραφή ενημερωτικών μηνυμάτων σχετικά με την πρόοδο του προγράμματος (σχετική μακροεντολή: NS_LOG_INFO).
  • LOG_FUNCTION - Καταγράφει μηνύματα που περιγράφουν κάθε συνάρτηση που ονομάζεται (δύο σχετικές μακροεντολές: NS_LOG_FUNCTION, που χρησιμοποιείται για συναρτήσεις μέλους και NS_LOG_FUNCTION_NOARGS, που χρησιμοποιείται για στατικές συναρτήσεις).
  • LOG_LOGIC - καταγραφή μηνυμάτων που περιγράφουν τη λογική ροή μέσα σε μια συνάρτηση (σχετική μακροεντολή: NS_LOG_LOGIC).
  • LOG_ALL - Καταγράφει όλα όσα αναφέρονται παραπάνω (χωρίς συσχετισμένη μακροεντολή).
    Για κάθε τύπο (LOG_TYPE) υπάρχει επίσης ένα LOG_LEVEL_TYPE το οποίο, εάν χρησιμοποιείται, επιτρέπει την καταγραφή όλων των επιπέδων πάνω από αυτό, εκτός από το δικό του επίπεδο. (Συνεπώς, τα LOG_ERROR και LOG_LEVEL_ERROR, και LOG_ALL και LOG_LEVEL_ALL είναι λειτουργικά ισοδύναμα.) Για παράδειγμα, η ενεργοποίηση του LOG_INFO θα επιτρέψει μόνο μηνύματα που παρέχονται από τη μακροεντολή NS_LOG_INFO, ενώ η ενεργοποίηση των LOG_LEVEL_INFO θα περιλαμβάνει επίσης τα μηνύματα LOG_LEVEL_INFO που παρέχονται από την μακροεντολή LOG_LEVEL_INFO _WARN και NS_LOG_ERROR.

Παρέχουμε επίσης μια μακροεντολή καταγραφής άνευ όρων που εμφανίζεται πάντα, ανεξάρτητα από το επίπεδο καταγραφής ή το στοιχείο επιλογής.

  • NS_LOG_UNCOND - Καταγραφή άνευ όρων του συσχετισμένου μηνύματος (χωρίς σχετικό επίπεδο καταγραφής).

Κάθε επίπεδο μπορεί να ερωτηθεί μεμονωμένα ή αθροιστικά. Η καταγραφή μπορεί να διαμορφωθεί χρησιμοποιώντας τη μεταβλητή περιβάλλοντος sh NS_LOG ή καταγράφοντας μια κλήση λειτουργίας συστήματος. Όπως αναφέρθηκε προηγουμένως, το σύστημα καταγραφής διαθέτει τεκμηρίωση Doxygen και τώρα είναι η κατάλληλη στιγμή να το ελέγξετε εάν δεν το έχετε ήδη κάνει.

Τώρα που διαβάσατε την τεκμηρίωση με μεγάλη λεπτομέρεια, ας χρησιμοποιήσουμε αυτή τη γνώση για να λάβουμε μερικές ενδιαφέρουσες πληροφορίες από το παράδειγμα σεναρίου scratch/myfirst.ccπου έχετε ήδη συντάξει.

5.1.2 Ενεργοποίηση καταγραφής

Ας χρησιμοποιήσουμε τη μεταβλητή περιβάλλοντος NS_LOG για να εκτελέσουμε μερικά ακόμη αρχεία καταγραφής, αλλά πρώτα, απλώς για να λάβετε τα ρουλεμάν σας, εκτελέστε το τελευταίο σενάριο όπως κάνατε νωρίτερα,

$ ./waf --run scratch/myfirst

Θα πρέπει να δείτε τη γνωστή έξοδο από το πρώτο παράδειγμα προγράμματος 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

Αποδεικνύεται ότι τα μηνύματα "απεσταλμένα" και "ληφθέντα" που βλέπετε παραπάνω είναι στην πραγματικότητα καταγεγραμμένα μηνύματα από Εφαρμογή UdpEchoClient и Εφαρμογή UdpEchoServer. Για παράδειγμα, μπορούμε να ζητήσουμε από την εφαρμογή πελάτη να εκτυπώσει πρόσθετες πληροφορίες ορίζοντας το επίπεδο καταγραφής της μέσω της μεταβλητής περιβάλλοντος NS_LOG.

Από εδώ και πέρα, θα υποθέσω ότι χρησιμοποιείτε ένα κέλυφος τύπου sh που χρησιμοποιεί τη σύνταξη "VARIABLE=value". Εάν χρησιμοποιείτε ένα κέλυφος τύπου csh, τότε θα πρέπει να μετατρέψετε τα παραδείγματά μου στη σύνταξη "τιμή μεταβλητής setenv" που απαιτείται από αυτά τα κελύφη.

Επί του παρόντος, η εφαρμογή πελάτη UDP echo ανταποκρίνεται στην ακόλουθη γραμμή κώδικα στο scratch/myfirst.cc,

LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO);

Ενεργοποιεί το επίπεδο καταγραφής LOG_LEVEL_INFO. Όταν περνάμε μια σημαία επιπέδου καταγραφής, στην πραγματικότητα ενεργοποιούμε αυτό το επίπεδο και όλα τα χαμηλότερα επίπεδα. Σε αυτήν την περίπτωση, έχουμε ενεργοποιήσει τα NS_LOG_INFO, NS_LOG_DEBUG, NS_LOG_WARN και NS_LOG_ERROR. Μπορούμε να αυξήσουμε το επίπεδο καταγραφής και να λάβουμε περισσότερες πληροφορίες, χωρίς αλλαγές σεναρίου και εκ νέου μεταγλώττιση, ορίζοντας τη μεταβλητή περιβάλλοντος NS_LOG ως εξής:

$ export NS_LOG=UdpEchoClientApplication=level_all

Οπότε ορίσαμε τη μεταβλητή shll NS_LOG στην ακόλουθη τιμή,

UdpEchoClientApplication=level_all

Η αριστερή πλευρά της ανάθεσης είναι το όνομα του καταγεγραμμένου στοιχείου που θέλουμε να διαμορφώσουμε και η δεξιά πλευρά είναι η σημαία που θέλουμε να εφαρμόσουμε για αυτό. Σε αυτήν την περίπτωση, θα ενεργοποιήσουμε όλα τα επίπεδα εντοπισμού σφαλμάτων στην εφαρμογή. Εάν εκτελέσετε το σενάριο με το NS_LOG που έχει οριστεί με αυτόν τον τρόπο, το σύστημα καταγραφής 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.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()

Οι πρόσθετες πληροφορίες εντοπισμού σφαλμάτων που παρέχονται από την εφαρμογή βρίσκονται πλέον στο επίπεδο NS_LOG_FUNCTION. Εμφανίζει κάθε περίπτωση κλήσης συνάρτησης κατά την εκτέλεση του σεναρίου. Κατά γενικό κανόνα, στις συναρτήσεις μεθόδου είναι προτιμότερο να χρησιμοποιείται (τουλάχιστον)NS_LOG_FUNCTION (this)... Χρήση NS_LOG_FUNCTION_NOARGS ()
μόνο σε στατικές συναρτήσεις. Ωστόσο, σημειώστε ότι το σύστημα ns-3 δεν απαιτείται να υποστηρίζει καμία λειτουργία καταγραφής. Η απόφαση για το πόσες πληροφορίες καταγράφονται επαφίεται στον μεμονωμένο προγραμματιστή του μοντέλου. Στην περίπτωση εφαρμογών ηχούς, είναι διαθέσιμη μεγάλη ποσότητα εξόδου καταγραφής.

Τώρα μπορείτε να προβάλετε ένα αρχείο καταγραφής κλήσεων συναρτήσεων που πραγματοποιήθηκαν από την εφαρμογή. Αν κοιτάξετε προσεκτικά, θα παρατηρήσετε μια άνω και κάτω τελεία ανάμεσα στη γραμμή Εφαρμογή UdpEchoClient και το όνομα της μεθόδου, όπου μπορείτε να περιμένετε να δείτε τον τελεστή εμβέλειας C++ (: :). Αυτό είναι σκόπιμα.

Αυτό δεν είναι στην πραγματικότητα το όνομα της κλάσης, αλλά το όνομα του στοιχείου καταγραφής. Όταν υπάρχει αντιστοιχία μεταξύ ενός αρχείου προέλευσης και μιας κλάσης, είναι συνήθως το όνομα της κλάσης, αλλά θα πρέπει να συνειδητοποιήσετε ότι στην πραγματικότητα δεν είναι το όνομα της κλάσης και ότι υπάρχει μία άνω και κάτω τελεία αντί για διπλή άνω και κάτω τελεία. Αυτός είναι ένας τρόπος για να σας βοηθήσει να διαχωρίσετε εννοιολογικά το όνομα του φασολιού υλοτομίας από το όνομα της τάξης με έναν σχετικά διακριτικό τρόπο.

Ωστόσο, σε ορισμένες περιπτώσεις μπορεί να είναι δύσκολο να προσδιοριστεί ποια μέθοδος δημιουργεί πραγματικά το μήνυμα καταγραφής. Αν κοιτάξετε το παραπάνω κείμενο, μπορεί να αναρωτιέστε πού είναι η γραμμή "Received 1024 bytes from 10.1.1.2" Μπορείτε να λύσετε αυτό το πρόβλημα ρυθμίζοντας το επίπεδο prefix_func στη μεταβλητή περιβάλλοντος NS_LOG. Δοκιμάστε τα εξής:

$ export 'NS_LOG=UdpEchoClientApplication=level_all|prefix_func'

Σημειώστε ότι τα εισαγωγικά είναι απαραίτητα επειδή η κατακόρυφη μπάρα που χρησιμοποιούμε για να αναπαραστήσουμε τη λειτουργία OR είναι επίσης σύνδεσμος σωλήνα Unix. Τώρα, εάν εκτελέσετε το σενάριο, θα δείτε ότι το σύστημα καταγραφής διασφαλίζει ότι κάθε μήνυμα σε ένα δεδομένο αρχείο καταγραφής έχει το πρόθεμα του ονόματος στοιχείου.

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

Τώρα μπορείτε να δείτε ότι όλα τα μηνύματα που προέρχονται από την εφαρμογή πελάτη UDP echo αναγνωρίζονται ως τέτοια. Μήνυμα "Received 1024 bytes from 10.1.1.2" αναγνωρίζεται πλέον ξεκάθαρα ότι προέρχεται από την εφαρμογή πελάτη echo. Το υπόλοιπο μήνυμα πρέπει να προέρχεται από την εφαρμογή διακομιστή UDP echo. Μπορούμε να ενεργοποιήσουμε αυτό το στοιχείο εισάγοντας μια λίστα στοιχείων διαχωρισμένη με άνω και κάτω τελεία στη μεταβλητή περιβάλλοντος NS_LOG.

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

Προειδοποίηση: Στο παραπάνω παράδειγμα κειμένου, θα χρειαστεί να αφαιρέσετε τον χαρακτήρα νέας γραμμής μετά την άνω και κάτω τελεία (:), που χρησιμοποιείται για τη μορφοποίηση του εγγράφου. Τώρα, εάν εκτελέσετε το σενάριο, θα δείτε όλα τα μηνύματα καταγραφής από τις εφαρμογές echo του πελάτη και του διακομιστή. Μπορείτε να δείτε ότι αυτό μπορεί να είναι πολύ χρήσιμο κατά τον εντοπισμό σφαλμάτων.

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

Μερικές φορές είναι επίσης χρήσιμο να μπορείτε να δείτε τον χρόνο προσομοίωσης κατά τον οποίο δημιουργήθηκε το μήνυμα καταγραφής. Μπορείτε να το κάνετε αυτό προσθέτοντας το bit OR prefix_time:

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

Και πάλι, θα πρέπει να αφαιρέσετε τον παραπάνω χαρακτήρα νέας γραμμής. Εάν εκτελείτε τώρα το σενάριο, θα πρέπει να δείτε την ακόλουθη έξοδο:

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

Σημειώστε ότι ο κατασκευαστής για UdpEchoServer κλήθηκε κατά τη διάρκεια της προσομοίωσης 0 δευτερόλεπτα. Αυτό συμβαίνει στην πραγματικότητα πριν ξεκινήσει η προσομοίωση, αλλά ο χρόνος εμφανίζεται ως μηδέν δευτερόλεπτα. Το ίδιο ισχύει και για το μήνυμα του κατασκευαστή 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()

Θυμίζουμε ότι το σενάριο γρατσουνιά/πρώτο.κ.εκ ξεκίνησε την εφαρμογή διακομιστή echo ένα δευτερόλεπτο πριν από την έναρξη της προσομοίωσης. Τώρα μπορείτε να δείτε ότι η μέθοδος StartApplication ο διακομιστής καλείται πραγματικά στο πρώτο δευτερόλεπτο. Μπορεί επίσης να παρατηρήσετε ότι το echo client ξεκινά στο δεύτερο δευτερόλεπτο της προσομοίωσης, όπως ζητήσαμε στο σενάριο.

Τώρα μπορείτε να παρακολουθείτε την πρόοδο της προσομοίωσης κατά την κλήση Πρόγραμμα Μετάδοσης στον υπολογιστή-πελάτη που καλεί την επανάκληση HandleRead Αποστολή στην εφαρμογή διακομιστή echo. Σημειώστε ότι ο χρόνος που έχει παρέλθει για την αποστολή ενός πακέτου μέσω μιας σύνδεσης από σημείο σε σημείο είναι 3,69 χιλιοστά του δευτερολέπτου. Μπορείτε να δείτε ότι ο διακομιστής echo καταγράφει ένα μήνυμα ότι ανταποκρίθηκε στο πακέτο και στη συνέχεια, μετά από καθυστέρηση καναλιού, βλέπετε ότι ο πελάτης echo λαμβάνει το πακέτο echo στη μέθοδο HandleRead.

Σε αυτήν την προσομοίωση, πολλά συμβαίνουν χωρίς να το προσέξετε. Αλλά μπορείτε να παρακολουθείτε όλη τη διαδικασία πολύ εύκολα ενεργοποιώντας όλα τα στοιχεία καταγραφής στο σύστημα. Δοκιμάστε να ορίσετε τη μεταβλητή NS_LOG στην ακόλουθη τιμή,

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

Ο παραπάνω αστερίσκος είναι ένας χαρακτήρας μπαλαντέρ για το στοιχείο καταγραφής. Αυτό θα περιλαμβάνει όλες τις καταχωρήσεις σε όλα τα στοιχεία που χρησιμοποιούνται στην προσομοίωση. Δεν θα αναπαράγω την έξοδο εδώ (τη στιγμή που γράφονται αυτές οι γραμμές παράγει 1265 γραμμές εξόδου για ένα μόνο πακέτο ηχούς), αλλά μπορείτε να ανακατευθύνετε αυτές τις πληροφορίες σε ένα αρχείο και να τις προβάλετε στον αγαπημένο σας επεξεργαστή.

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

Προσωπικά χρησιμοποιώ αυτήν την εξαιρετικά περιεκτική έκδοση της καταγραφής όταν έχω πρόβλημα και δεν έχω ιδέα πού πήγαν στραβά τα πράγματα. Μπορώ να ακολουθήσω την εκτέλεση του κώδικα αρκετά εύκολα χωρίς να βάλω σημεία διακοπής και να περνώ από τον κώδικα στο πρόγραμμα εντοπισμού σφαλμάτων. Μπορώ απλώς να επεξεργαστώ την έξοδο στον αγαπημένο μου επεξεργαστή και να αναζητήσω αυτό που περιμένω και να δω να συμβαίνει κάτι που δεν περίμενα. Μόλις έχω μια γενική ιδέα για το τι πάει στραβά, μπαίνω στο πρόγραμμα εντοπισμού σφαλμάτων για να διερευνήσω το πρόβλημα. Αυτός ο τύπος εξόδου μπορεί να είναι ιδιαίτερα χρήσιμος όταν το σενάριό σας κάνει κάτι εντελώς απροσδόκητο. Εάν χρησιμοποιείτε μόνο το πρόγραμμα εντοπισμού σφαλμάτων, μπορεί να χάσετε εντελώς μια ανατροπή. Η εγγραφή κάνει τέτοιες στροφές αισθητές.

5.1.3 Προσθήκη καταγραφής στον κώδικά σας

Μπορείτε να προσθέσετε νέες καταχωρήσεις στις προσομοιώσεις σας πραγματοποιώντας κλήσεις στο στοιχείο καταγραφής από πολλές μακροεντολές. Ας το κάνουμε σε σενάριο myfirst.cc, που έχουμε στον κατάλογο «καθαρό». Θυμηθείτε ότι ορίσαμε ένα στοιχείο καταγραφής σε αυτό το σενάριο:

NS_LOG_COMPONENT_DEFINE ("FirstScriptExample");

Γνωρίζετε ότι μπορείτε να ενεργοποιήσετε την καταγραφή όλων των μηνυμάτων από αυτό το στοιχείο ορίζοντας τη μεταβλητή περιβάλλοντος NS_LOG σε διαφορετικά επίπεδα. Ας προχωρήσουμε και ας προσθέσουμε μερικές καταχωρήσεις στο σενάριο. Η μακροεντολή που χρησιμοποιείται για την προσθήκη μηνυμάτων σε επίπεδο πληροφοριών στο αρχείο καταγραφής είναι NS_LOG_INFO. Ας προσθέσουμε ένα μήνυμα (λίγο πριν ξεκινήσουμε τη δημιουργία κόμβων) που σας λέει ότι το σενάριο βρίσκεται στη φάση "Δημιουργία Τοπολογίας". Αυτό γίνεται στο παρακάτω απόσπασμα κώδικα,
Άνοιγμα scratch/myfirst.cc στον αγαπημένο σας επεξεργαστή και προσθέστε τη γραμμή,
NS_LOG_INFO ("Creating Topology");
ακριβώς πριν από τις γραμμές,

NodeContainer nodes;
nodes.Create (2);

Τώρα μεταγλωττίστε το σενάριο χρησιμοποιώντας WAFκαι διαγράψτε τη μεταβλητή NS_LOG για να απενεργοποιήσετε τη ροή καταγραφής που ενεργοποιήσαμε νωρίτερα:

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

Δεν θα δείτε το νέο μήνυμα επειδή το συσχετισμένο στοιχείο καταγραφής (FirstScriptExample) δεν έχει ενεργοποιηθεί. Για να δείτε το μήνυμά σας, πρέπει να ενεργοποιήσετε το στοιχείο καταγραφής FirstScriptExample με επίπεδο όχι χαμηλότερο από NS_LOG_INFO. Εάν θέλετε απλώς να δείτε αυτό το συγκεκριμένο επίπεδο καταγραφής, μπορείτε να το ενεργοποιήσετε ως εξής,

$ export NS_LOG=FirstScriptExample=info

Εάν εκτελέσετε το σενάριο τώρα, θα δείτε ένα νέο μήνυμα "Δημιουργία Τοπολογίας",

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 Χρήση ορισμάτων γραμμής εντολών

5.2.1 Παράκαμψη προεπιλεγμένων τιμών χαρακτηριστικών

Ένας άλλος τρόπος για να αλλάξετε τη συμπεριφορά των σεναρίων ns-3 χωρίς επεξεργασία ή δημιουργία είναι να χρησιμοποιήσετε ορίσματα γραμμής εντολών. Παρέχουμε έναν μηχανισμό για την ανάλυση των ορισμάτων της γραμμής εντολών και τον αυτόματο ορισμό τοπικών και καθολικών μεταβλητών με βάση τα αποτελέσματα.

Το πρώτο βήμα στη χρήση του συστήματος ορισμάτων γραμμής εντολών είναι να δηλώσετε έναν αναλυτή γραμμής εντολών. Αυτό είναι αρκετά εύκολο να γίνει (στο κύριο πρόγραμμα σας), όπως στον παρακάτω κώδικα,

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

Αυτό το απλό απόσπασμα δύο γραμμών είναι πραγματικά πολύ χρήσιμο από μόνο του. Ανοίγει την πόρτα στην καθολική μεταβλητή και το σύστημα χαρακτηριστικών ns-3. Ας προσθέσουμε δύο γραμμές κώδικα στην αρχή της κύριας συνάρτησης σεναρίου scratch/myfirst.cc. Προχωρώντας, μεταγλωττίζουμε το σενάριο και το εκτελούμε, όταν εκτελείται κάνουμε ένα αίτημα βοήθειας ως εξής:

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

Αυτή η εντολή θα ρωτήσει βάφ εκτέλεση σεναρίου γρατσουνίζω/πρώτος μου και περάστε του ένα όρισμα γραμμής εντολών —PrintHelp. Τα εισαγωγικά απαιτούνται για να υποδείξουν ποιο πρόγραμμα προορίζεται το όρισμα. Ο αναλυτής της γραμμής εντολών θα εντοπίσει το όρισμα —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.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.

Τώρα ας δούμε την επιλογή —PrintAttributes. Έχουμε ήδη αναφέρει το σύστημα χαρακτηριστικών ns-3 κατά τη μελέτη του σεναρίου first.cc. Έχουμε δει τις ακόλουθες γραμμές κώδικα,

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

και το είπαν αυτό Ρυθμός δεδομένων είναι στην πραγματικότητα ένα χαρακτηριστικό Συσκευή PointToPointNet. Ας χρησιμοποιήσουμε τον αναλυτή ορίσματος γραμμής εντολών για να προβάλουμε τα χαρακτηριστικά Συσκευή PointToPointNet. Η λίστα βοήθειας λέει τι πρέπει να παρέχουμε TypeId. Αυτό είναι το όνομα της κλάσης στην οποία ανήκουν τα χαρακτηριστικά ενδιαφέροντος. Στην περίπτωσή μας θα είναι ns3::PointToPointNetDevice. Ας συνεχίσουμε να προχωράμε, μπείτε,

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

Το σύστημα θα εκτυπώσει όλα τα χαρακτηριστικά αυτού του τύπου συσκευής δικτύου. Θα δείτε ότι μεταξύ των χαρακτηριστικών στη λίστα είναι:

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

Αυτή είναι η προεπιλεγμένη τιμή που θα χρησιμοποιηθεί από το σύστημα κατά τη δημιουργία του αντικειμένου Συσκευή PointToPointNet. Θα παρακάμψουμε αυτήν την προεπιλεγμένη τιμή χρησιμοποιώντας την παράμετρο Χαρακτηριστικό в PointToPointHelper πιο ψηλά. Ας χρησιμοποιήσουμε τις προεπιλεγμένες τιμές για συσκευές και κανάλια από σημείο σε σημείο. Για να γίνει αυτό, θα διαγράψουμε κλήσεις SetDeviceAttribute и SetChannelAttribute του myfirst.cc, το οποίο έχουμε σε έναν καθαρό κατάλογο.

Το σενάριό σας θα πρέπει τώρα απλώς να δηλώνει PointToPointHelper και μην εκτελείτε εργασίες εγκατάστασης όπως φαίνεται στο παρακάτω παράδειγμα,

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

Προχωρήστε και δημιουργήστε ένα νέο σενάριο με βάφ (./waff) και ας επιστρέψουμε και ας συμπεριλάβουμε κάποια καταχώρηση από την εφαρμογή διακομιστή UDP echo και ας συμπεριλάβουμε το πρόθεμα χρόνου.

$ export 'NS_LOG=UdpEchoServerApplication=level_all|prefix_time'

Εάν εκτελέσετε το σενάριο, θα πρέπει να δείτε την ακόλουθη έξοδο:

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

Θυμηθείτε ότι την τελευταία φορά που εξετάσαμε τον χρόνο προσομοίωσης, τη στιγμή που ελήφθη το πακέτο από τον διακομιστή echo, ήταν 2,00369 δευτερόλεπτα.

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

Τώρα λαμβάνει το πακέτο σε 2.25732 δευτερόλεπτα. Αυτό συμβαίνει επειδή απλώς επαναφέρουμε τον ρυθμό δεδομένων PointToPointNetDevice από πέντε megabit ανά δευτερόλεπτο στην προεπιλεγμένη τιμή, η οποία είναι 32768 bit ανά δευτερόλεπτο. Εάν επρόκειτο να αντικαταστήσουμε ένα νέο DataRate χρησιμοποιώντας τη γραμμή εντολών, θα μπορούσαμε να επιταχύνουμε ξανά την προσομοίωση μας. Θα το κάνουμε ως εξής, σύμφωνα με τον τύπο που υπονοείται από το στοιχείο βοήθειας:

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

Αυτό θα επιστρέψει το χαρακτηριστικό DataRate στην προεπιλεγμένη τιμή των πέντε megabit ανά δευτερόλεπτο. Είστε έκπληκτοι από το αποτέλεσμα; Αποδεικνύεται ότι για να επιστρέψουμε την αρχική συμπεριφορά του σεναρίου, πρέπει επίσης να ρυθμίσουμε την καθυστέρηση καναλιού ώστε να ταιριάζει με την ταχύτητα του φωτός. Μπορούμε να ζητήσουμε από το σύστημα της γραμμής εντολών να εκτυπώσει τα χαρακτηριστικά του καναλιού, όπως κάναμε για τη συσκευή δικτύου:

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

Θα διαπιστώσουμε ότι το χαρακτηριστικό καθυστέρησης καναλιού έχει οριστεί ως εξής:

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

Μπορούμε στη συνέχεια, μέσω του συστήματος της γραμμής εντολών, να ορίσουμε και τις δύο αυτές προεπιλεγμένες τιμές.

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

Σε αυτήν την περίπτωση επαναφέρουμε τον χρόνο που είχαμε όταν ορίσαμε ρητά το DataRate και το Delay στο σενάριο:

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

Σημειώστε ότι το πακέτο λαμβάνεται ξανά από τον διακομιστή μετά από 2,00369 δευτερόλεπτα. Θα μπορούσαμε πραγματικά να ορίσουμε οποιοδήποτε από τα χαρακτηριστικά που χρησιμοποιούνται στο σενάριο με αυτόν τον τρόπο. Συγκεκριμένα, θα μπορούσαμε να ορίσουμε τα χαρακτηριστικά MaxPackets σε μη μία τιμές UdpEchoClient.

Πώς θα το χρησιμοποιούσατε; Δοκίμασε το. Θυμηθείτε ότι πρέπει να σχολιάσετε το μέρος όπου παρακάμπτουμε την προεπιλεγμένη τιμή χαρακτηριστικού και ορίζουμε ρητά MaxPackets στο σενάριο. Στη συνέχεια, πρέπει να δημιουργήσετε ξανά το σενάριο. Μπορείτε επίσης να χρησιμοποιήσετε τη γραμμή εντολών για να λάβετε βοήθεια σύνταξης για τον ορισμό μιας νέας προεπιλεγμένης τιμής χαρακτηριστικού. Μόλις καταλάβετε αυτό, μπορείτε να ελέγξετε τον αριθμό των πακέτων που εμφανίζονται στη γραμμή εντολών. Δεδομένου ότι είμαστε φιλομαθείς άνθρωποι, η γραμμή εντολών μας θα πρέπει να μοιάζει κάπως έτσι:

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

Το φυσικό ερώτημα που τίθεται σε αυτό το σημείο είναι πώς να γνωρίζουμε για την ύπαρξη όλων αυτών των ιδιοτήτων. Και πάλι, το σύστημα της γραμμής εντολών έχει μια λειτουργία βοήθειας για αυτό το θέμα. Εάν ζητήσουμε βοήθεια από τη γραμμή εντολών, θα πρέπει να δούμε:

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

Εάν επιλέξετε το όρισμα "PrintGroups", θα πρέπει να δείτε μια λίστα με όλες τις καταχωρημένες ομάδες TypeId. Τα ονόματα των ομάδων είναι σύμφωνα με τα ονόματα των λειτουργικών μονάδων στον κατάλογο προέλευσης (αν και με κεφαλαία). Η εκτύπωση όλων των πληροφοριών ταυτόχρονα θα ήταν πολύ ογκώδης, επομένως είναι διαθέσιμο ένα πρόσθετο φίλτρο για την εκτύπωση πληροφοριών ανά ομάδα. Έτσι, εστιάζοντας ξανά στην ενότητα από σημείο σε σημείο:

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

Εδώ μπορείτε να βρείτε διαθέσιμα ονόματα TypeId για αναζητήσεις χαρακτηριστικών, για παράδειγμα στο
--PrintAttributes = ns3 :: PointToPointChannelόπως φαίνεται παραπάνω.

Ένας άλλος τρόπος για να μάθετε για τα χαρακτηριστικά είναι μέσω του Doxygen ns‑3. Υπάρχει μια σελίδα που παραθέτει όλα τα χαρακτηριστικά που είναι καταχωρημένα στον προσομοιωτή.

5.2.2 Λήψη των δικών σας εντολών

Μπορείτε επίσης να προσθέσετε τα δικά σας άγκιστρα μέσω του συστήματος της γραμμής εντολών. Αυτό γίνεται πολύ απλά χρησιμοποιώντας τη μέθοδο ανάλυσης της γραμμής εντολών AddValue.
Ας χρησιμοποιήσουμε αυτή τη δυνατότητα για να καθορίσουμε τον αριθμό των πακέτων που θα εμφανίζονται με εντελώς διαφορετικό τρόπο. Ας προσθέσουμε μια τοπική μεταβλητή που ονομάζεται nΠακέτα σε μια συνάρτηση κύριος. Θα το ορίσουμε σε ένα για να ταιριάζει με την προηγούμενη προεπιλεγμένη συμπεριφορά μας. Για να επιτρέψουμε στον αναλυτή της γραμμής εντολών να αλλάξει αυτήν την τιμή, πρέπει να καταγράψουμε αυτήν την τιμή στον αναλυτή. Αυτό το κάνουμε προσθέτοντας μια κλήση AddValue. Πήγαινε και άλλαξε το σενάριο scratch/myfirst.cc για να ξεκινήσουμε με τον παρακάτω κώδικα,

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

Κάντε κύλιση προς τα κάτω στο σημείο του σεναρίου όπου ορίσαμε το χαρακτηριστικό MaxPackets και το αλλάξαμε έτσι ώστε να οριστεί στη μεταβλητή nPackets αντί για τη σταθερά 1, όπως φαίνεται παρακάτω.

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

Τώρα, εάν εκτελέσετε το σενάριο και παρέχετε το όρισμα -PrintHelp, θα πρέπει να δείτε το όρισμα νέου χρήστη. εμφανίζεται στην οθόνη βοήθειας. Εισαγω,

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

Εάν θέλετε να αλλάξετε τον αριθμό των πακέτων που μεταδίδονται, μπορείτε να το κάνετε ορίζοντας το όρισμα της γραμμής εντολών - -nPackets.

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

Τώρα πρέπει να δείτε

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

Τώρα έχετε στείλει δύο πακέτα. Πολύ απλό, έτσι δεν είναι;
Μπορείτε να δείτε ότι ως χρήστης ns-3, μπορείτε να χρησιμοποιήσετε το σύστημα ορισμάτων γραμμής εντολών για να χειριστείτε καθολικές τιμές και χαρακτηριστικά. Εάν είστε ο συγγραφέας του μοντέλου, μπορείτε να προσθέσετε νέα χαρακτηριστικά στα αντικείμενά σας και θα είναι αυτόματα διαθέσιμα για διαμόρφωση από τους χρήστες σας μέσω του συστήματος της γραμμής εντολών. Εάν είστε συγγραφέας σεναρίων, μπορείτε να προσθέσετε νέες μεταβλητές στα σενάρια σας και να τις συνδέσετε απρόσκοπτα στο σύστημα της γραμμής εντολών σας.

5.3 Χρήση του συστήματος ανίχνευσης

Το όλο θέμα της μοντελοποίησης είναι να δημιουργηθούν αποτελέσματα για περαιτέρω μελέτη, και το σύστημα ιχνών ns-3 είναι ο κύριος μηχανισμός για αυτό. Δεδομένου ότι το ns-3 είναι ένα πρόγραμμα C++, μπορούν να χρησιμοποιηθούν τυπικά μέσα παραγωγής εξόδου από ένα πρόγραμμα C++:

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

Μπορείτε ακόμη να χρησιμοποιήσετε μια μονάδα καταγραφής για να προσθέσετε μια μικρή δομή στη λύση σας. Υπάρχουν πολλά γνωστά προβλήματα που προκαλούνται από αυτήν την προσέγγιση, και ως εκ τούτου παρέχουμε ένα γενικό υποσύστημα ανίχνευσης συμβάντων για την επίλυση αυτών των προβλημάτων.

Οι κύριοι στόχοι του συστήματος ανίχνευσης ns-3 είναι:

  • Για βασικές εργασίες, το σύστημα ανίχνευσης θα πρέπει να επιτρέπει στο χρήστη να δημιουργεί ένα τυπικό ίχνος για δημοφιλείς πηγές και να επιλέγει αντικείμενα που δημιουργούν το ίχνος.

  • Οι ενδιάμεσοι χρήστες θα πρέπει να μπορούν να επεκτείνουν το σύστημα ανίχνευσης για να αλλάξουν τη μορφή εξόδου που δημιουργείται ή να εισάγουν νέες πηγές ίχνους, χωρίς να τροποποιήσουν τον πυρήνα του προσομοιωτή.

  • Οι προχωρημένοι χρήστες μπορούν να τροποποιήσουν τον πυρήνα του προσομοιωτή για να προσθέσουν νέες πηγές ίχνους και καταβόθρες. Το σύστημα ανίχνευσης ns-3 βασίζεται στις αρχές των ανεξάρτητων πηγών και δεκτών παρακολούθησης, καθώς και σε έναν ενοποιημένο μηχανισμό για τη σύνδεση των πηγών με τους καταναλωτές.

Το σύστημα ανίχνευσης ns-3 βασίζεται στις αρχές των ανεξάρτητων πηγών και δεκτών ανίχνευσης, καθώς και ενός ενοποιημένου μηχανισμού για τη σύνδεση πηγών με δέκτες. Οι πηγές ίχνους είναι αντικείμενα που μπορούν να σηματοδοτήσουν συμβάντα που συμβαίνουν στην προσομοίωση και να παρέχουν πρόσβαση στα υποκείμενα δεδομένα ενδιαφέροντος. Για παράδειγμα, μια πηγή ίχνους μπορεί να υποδεικνύει πότε μια συσκευή δικτύου έλαβε ένα πακέτο και να κάνει τα περιεχόμενα του πακέτου διαθέσιμα στους ενδιαφερόμενους δέκτες ίχνους.

Οι πηγές ανίχνευσης από μόνες τους είναι άχρηστες, εκτός εάν «συνδυάζονται» με άλλα μέρη του κώδικα που στην πραγματικότητα κάνουν κάτι χρήσιμο με τις πληροφορίες που παρέχονται από το νεροχύτη. Οι ανιχνευτές είναι καταναλωτές γεγονότων και δεδομένων που παρέχονται από πηγές ιχνών. Για παράδειγμα, μπορείτε να δημιουργήσετε μια καταβόθρα ανίχνευσης που (όταν συνδεθεί με την πηγή ίχνους του προηγούμενου παραδείγματος) θα εκτυπώσει τα μέρη που ενδιαφέρουν στο ληφθέν πακέτο.

Το σκεπτικό αυτού του ρητού διαχωρισμού είναι να επιτραπεί στους χρήστες να συνδέουν νέους τύπους καταβόθρων με υπάρχουσες πηγές ίχνους χωρίς να χρειάζεται να επεξεργαστούν και να μεταγλωττίσουν εκ νέου τον πυρήνα του προσομοιωτή. Έτσι, στο παραπάνω παράδειγμα, ο χρήστης μπορεί να ορίσει ένα νέο ανιχνευτή στο σενάριο του και να το συνδέσει με μια υπάρχουσα πηγή ίχνους που ορίζεται στον πυρήνα προσομοίωσης μόνο με την επεξεργασία του σεναρίου χρήστη.

Σε αυτό το σεμινάριο, θα εξετάσουμε μερικές από τις προκαθορισμένες πηγές και καταβόθρες και θα δείξουμε πώς μπορούν να διαμορφωθούν με τη μικρότερη δυνατή προσπάθεια εκ μέρους του χρήστη. Ανατρέξτε στις ενότητες Εγχειρίδιο ns-3 ή οδηγίες για πληροφορίες σχετικά με τη διαμόρφωση προηγμένων ιχνών, συμπεριλαμβανομένης της επέκτασης του χώρου ονομάτων του ίχνους και της δημιουργίας νέων πηγών ανίχνευσης.

5.3.1 Ανίχνευση ASCII

Το ns-3 παρέχει βοηθητική λειτουργία που παρέχει ένα σύστημα ανίχνευσης χαμηλού επιπέδου για να σας βοηθήσει με τις λεπτομέρειες κατά τη ρύθμιση απλών ιχνών πακέτων. Εάν ενεργοποιήσετε αυτήν τη δυνατότητα, θα δείτε την έξοδο σε αρχεία ASCII. Για όσους είναι εξοικειωμένοι με την έξοδο ns-2, αυτός ο τύπος ίχνους είναι παρόμοιος με έξω.τρ, το οποίο δημιουργείται από πολλά σενάρια.

Ας ξεκινήσουμε τη δουλειά και ας προσθέσουμε μερικά αποτελέσματα ανίχνευσης ASCII στο σενάριο scratch/myfirst.cc. Ακριβώς πριν την κλήση Simulator :: Run (), προσθέστε τις ακόλουθες γραμμές κώδικα:
AsciiTraceHelper ascii;

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

Όπως πολλοί άλλοι ιδιωματισμοί ns-3, αυτός ο κώδικας χρησιμοποιεί ένα αντικείμενο βοήθειας για τη δημιουργία ιχνών ASCII. Η δεύτερη γραμμή περιέχει δύο κλήσεις ένθετων μεθόδων. Μέθοδος «μέσα». CreateFileStream() χρησιμοποιεί το ιδίωμα ανώνυμου αντικειμένου για να δημιουργήσει ένα αντικείμενο ροής αρχείου στη στοίβα (χωρίς όνομα αντικειμένου) και το μεταβιβάζει στην καλούμενη μέθοδο. Θα πάμε πιο βαθιά σε αυτό στο μέλλον, αλλά το μόνο που χρειάζεται να γνωρίζετε σε αυτό το σημείο είναι ότι δημιουργείτε ένα αντικείμενο που αντιπροσωπεύει ένα αρχείο που ονομάζεται myfirst.tr και μεταφέρετέ το στο ns-3. Αναθέτουμε στο ns-3 τη φροντίδα του δημιουργημένου αντικειμένου για ολόκληρη τη διάρκεια ζωής του, κατά τη διάρκεια της οποίας επιλύει προβλήματα που προκαλούνται από έναν ελάχιστα γνωστό (εσκεμμένο) περιορισμό που σχετίζεται με κατασκευαστές αντιγραφής αντικειμένων ροής C++.

Εξωτερική κλήση EnableAsciiAll() λέει στον βοηθό ότι θέλετε να συμπεριλάβετε την ανίχνευση ASCII στην προσομοίωση σας για όλες τις συνδέσεις συσκευής από σημείο σε σημείο και ότι θέλετε οι (καθορισμένοι) δέκτες παρακολούθησης να καταγράφουν πληροφορίες κίνησης πακέτων σε μορφή ASCII.

Για όσους είναι εξοικειωμένοι με το ns-2, τα συμβάντα παρακολούθησης είναι ισοδύναμα με τα γνωστά σημεία παρακολούθησης που καταγράφουν συμβάντα "+", "-", "d" και "r".
Τώρα μπορείτε να δημιουργήσετε το σενάριο και να το εκτελέσετε από τη γραμμή εντολών:

$ ./waf --run scratch/myfirst

Όπως πολλές φορές πριν, θα δείτε πολλά μηνύματα από το Waf και, στη συνέχεια, θα "η δημιουργία" ολοκληρώθηκε με επιτυχία" με μερικά μηνύματα από το πρόγραμμα που εκτελείται.

Κατά την εκτέλεση, το πρόγραμμα θα δημιουργήσει ένα αρχείο με το όνομα myfirst.tr. Λόγω της φύσης της εργασίας βάφ, από προεπιλογή το αρχείο δεν δημιουργείται στον τοπικό κατάλογο, αλλά στον κατάλογο ανώτατου επιπέδου του αποθετηρίου. Εάν θέλετε να αλλάξετε τη διαδρομή όπου αποθηκεύονται τα ίχνη, τότε μπορείτε να χρησιμοποιήσετε την παράμετρο Waf για να την καθορίσετε --cwd. Δεν το έχουμε κάνει, επομένως για να δούμε το αρχείο ίχνους ASCII myfirst.tr στον αγαπημένο σας επεξεργαστή, θα χρειαστεί να πλοηγηθούμε στον κατάλογο ανώτατου επιπέδου του αποθετηρίου μας.

Ανάλυση ιχνών ASCII

Υπάρχουν πολλές πληροφορίες εκεί σε αρκετά πυκνή μορφή, αλλά το πρώτο πράγμα που πρέπει να προσέξετε είναι ότι το αρχείο αποτελείται από μεμονωμένες γραμμές. Αυτό θα γίνει καθαρά ορατό εάν επεκτείνετε το παράθυρο προβολής ευρύτερα.

Κάθε γραμμή στο αρχείο αντιστοιχεί σε ένα συμβάν παρακολούθησης. Σε αυτήν την περίπτωση, ανιχνεύουμε συμβάντα στην ουρά μετάδοσης που υπάρχουν σε κάθε συσκευή δικτύου από σημείο σε σημείο στην προσομοίωση. Η ουρά μετάδοσης είναι η ουρά από την οποία πρέπει να περάσει κάθε πακέτο για μια σύνδεση από σημείο σε σημείο. Σημειώστε ότι κάθε γραμμή στο αρχείο παρακολούθησης ξεκινά με έναν μόνο χαρακτήρα (και έχει ένα κενό μετά από αυτόν). Αυτό το σύμβολο θα έχει την εξής σημασία:

+: συνέβη μια λειτουργία ουράς στην ουρά της συσκευής.
-: έλαβε χώρα μια λειτουργία ανάκτησης στοιχείων στην ουρά της συσκευής.
δ: το πακέτο απορρίφθηκε, συνήθως επειδή η ουρά ήταν γεμάτη.
r: Το πακέτο ελήφθη από μια συσκευή δικτύου.

Ας ρίξουμε μια πιο προσεκτική ματιά στην πρώτη γραμμή του αρχείου παρακολούθησης. Θα το χωρίσω σε μέρη (με εσοχές για σαφήνεια) και τον αριθμό γραμμής στα αριστερά:

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)

Το πρώτο τμήμα αυτού του συμβάντος εκτεταμένου ίχνους (γραμμή 0) είναι η λειτουργία. Εδώ έχουμε ένα σύμβολο +, το οποίο αντιστοιχεί στη λειτουργία της ουράς για μετάδοση. Το δεύτερο τμήμα (γραμμή 1) είναι ο χρόνος προσομοίωσης, εκφρασμένος σε δευτερόλεπτα. Ίσως θυμάστε τι ζητήσαμε Εφαρμογή UdpEchoClient ξεκινήστε την αποστολή πακέτων σε δύο δευτερόλεπτα. Εδώ βλέπουμε την επιβεβαίωση ότι αυτό όντως συμβαίνει.

Η επόμενη ενότητα του παραδείγματος ανίχνευσης (από τη γραμμή 2) δείχνει ποια πηγή ίχνους δημιούργησε αυτό το συμβάν (υποδεικνύοντας το ίχνος του χώρου ονομάτων). Μπορείτε να σκεφτείτε τον χώρο ονομάτων ίχνους όπως θα κάνατε έναν χώρο ονομάτων συστήματος αρχείων. Η ρίζα του χώρου ονομάτων είναι NodeList. Αυτό αντιστοιχεί στο κοντέινερ που διαχειρίζεται ο κύριος κώδικας ns-3. Περιέχει όλους τους κόμβους που δημιουργούνται στο σενάριο. Ακριβώς όπως ένα σύστημα αρχείων μπορεί να έχει καταλόγους στη ρίζα του, NodeList μπορούμε να έχουμε πολλούς κόμβους. Έτσι, η γραμμή /NodeList/0 αναφέρεται στον μηδενικό κόμβο στο NodeList, τον οποίο συνήθως θεωρούμε "κόμβος 0". Κάθε κόμβος έχει μια λίστα συσκευών που έχουν εγκατασταθεί. Αυτή η λίστα βρίσκεται δίπλα στον χώρο ονομάτων. Μπορείτε να δείτε ότι αυτό το ίχνος συμβάντος προέρχεται από Λίστα συσκευών/0, που είναι η μηδενική συσκευή που είναι εγκατεστημένη στον κόμβο.

Επόμενη υποσυμβολοσειρά, $ ns3 :: PointToPointNetDevice, λέει ποια συσκευή βρίσκεται στη θέση μηδέν: τη λίστα συσκευών του κόμβου μηδέν. Θυμηθείτε ότι η λειτουργία + που βρέθηκε στη γραμμή 0 σήμαινε ότι ένα στοιχείο προστέθηκε στην ουρά μετάδοσης της συσκευής. Αυτό αντικατοπτρίζεται στα τελευταία τμήματα της «διαδρομής διαδρομής»: TxQueue/Enqueue.

Τα υπόλοιπα τμήματα στο ίχνος θα πρέπει να είναι αρκετά διαισθητικά. Οι γραμμές 3-4 υποδεικνύουν ότι το πακέτο είναι ενθυλακωμένο σε ένα πρωτόκολλο από σημείο σε σημείο. Οι γραμμές 5-7 δείχνουν ότι το πακέτο έχει μια κεφαλίδα έκδοσης IP4 και προέρχεται από τη διεύθυνση IP 10.1.1.1 και προορίζεται για 10.1.1.2. Οι γραμμές 8-9 δείχνουν ότι αυτό το πακέτο έχει μια κεφαλίδα UDP και τέλος η γραμμή 10 δείχνει ότι το ωφέλιμο φορτίο είναι τα αναμενόμενα 1024 byte.

Η επόμενη γραμμή στο αρχείο παρακολούθησης δείχνει ότι το ίδιο πακέτο τραβήχτηκε από την ουρά μετάδοσης στον ίδιο κόμβο.

Η τρίτη γραμμή στο αρχείο παρακολούθησης δείχνει ότι το πακέτο ελήφθη από μια συσκευή δικτύου στον κεντρικό υπολογιστή του διακομιστή echo. Έχω αναπαράγει το συμβάν παρακάτω.

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)

Σημειώστε ότι η λειτουργία ανίχνευσης είναι πλέον r και ο χρόνος προσομοίωσης έχει αυξηθεί στα 2,25732 δευτερόλεπτα. Εάν ακολουθήσατε προσεκτικά το σεμινάριο, αυτό σημαίνει ότι αφήσατε το DataRate και το Link Delay των συσκευών δικτύου στις προεπιλεγμένες τιμές τους. Αυτός ο χρόνος πρέπει να είναι οικείος, όπως είδατε στην προηγούμενη ενότητα.

Η καταχώρηση χώρου ονομάτων της πηγής παρακολούθησης (γραμμή 2) έχει τροποποιηθεί ώστε να αντικατοπτρίζει ότι αυτό το συμβάν προέρχεται από τον κόμβο 1 (/NodeList/1) και το πακέτο λαμβάνεται από την πηγή ίχνους (/MacRx). Θα πρέπει να είναι αρκετά εύκολο για εσάς να παρακολουθείτε την κίνηση του πακέτου μέσω της τοπολογίας κοιτάζοντας τα υπόλοιπα ίχνη στο αρχείο.

5.3.2 PCAP Trace

Οι βοηθοί συσκευών ns-3 μπορούν επίσης να χρησιμοποιηθούν για τη δημιουργία αρχείων ανίχνευσης σε μορφή .pcap. Αρκτικόλεξο pcap (συνήθως γραμμένο με πεζά) σημαίνει σύλληψη πακέτων και είναι στην πραγματικότητα ένα API που περιλαμβάνει τον καθορισμό της μορφής αρχείου .pcap. Το πιο δημοφιλές πρόγραμμα που μπορεί να διαβάσει και να εμφανίσει αυτή τη μορφή είναι Wireshark (παλαιότερα κλήθηκε Αιθέριος). Ωστόσο, υπάρχουν πολλοί αναλυτές ιχνών κυκλοφορίας που χρησιμοποιούν αυτήν τη μορφή πακέτου. Ενθαρρύνουμε τους χρήστες να χρησιμοποιούν τα πολλά διαθέσιμα εργαλεία για την ανάλυση των ιχνών pcap. Σε αυτό το σεμινάριο θα επικεντρωθούμε στην προβολή ιχνών pcap χρησιμοποιώντας tcpdump.

Η ενεργοποίηση της ανίχνευσης pcap γίνεται με μία γραμμή κώδικα.

pointToPoint.EnablePcapAll ("myfirst");

Επικολλήστε αυτήν τη γραμμή κώδικα μετά τον κώδικα ανίχνευσης ASCII που μόλις προσθέσαμε scratch/myfirst.cc. Σημειώστε ότι περάσαμε μόνο τη συμβολοσειρά "myfirst", όχι "myfirst.pcap" ή κάτι παρόμοιο. Αυτό συμβαίνει επειδή η παράμετρος είναι ένα πρόθεμα, όχι ένα πλήρες όνομα αρχείου. Κατά τη διάρκεια της προσομοίωσης, ο βοηθός θα δημιουργήσει πραγματικά ένα αρχείο παρακολούθησης για κάθε συσκευή από σημείο σε σημείο. Τα ονόματα αρχείων θα δημιουργηθούν χρησιμοποιώντας το πρόθεμα, τον αριθμό κόμβου, τον αριθμό συσκευής και το επίθημα ".pcap».

Για το παράδειγμά μας σενάριο, θα καταλήξουμε να δούμε αρχεία με το όνομα "myfirst-0-0.pcap"Και"myfirst-1-0.pcap", τα οποία είναι ίχνη pcap για τον κόμβο 0-συσκευή 0 και τον κόμβο 1-συσκευή 0 αντίστοιχα. Αφού προσθέσετε τη γραμμή κώδικα για να ενεργοποιήσετε την ανίχνευση pcap, μπορείτε να εκτελέσετε το σενάριο με τον συνηθισμένο τρόπο:

$ ./waf --run scratch/myfirst

Εάν κοιτάξετε στον κατάλογο ανώτατου επιπέδου της διανομής σας, θα πρέπει να δείτε τρία αρχεία: ένα αρχείο παρακολούθησης ASCII myfirst.tr, που μελετήσαμε προηγουμένως, αρχεία myfirst-0-0.pcap и myfirst-1-0.pcap - νέα αρχεία pcap που μόλις δημιουργήσαμε.

Ανάγνωση εξόδου με το tcpdump

Προς το παρόν, ο ευκολότερος τρόπος προβολής αρχείων pcap είναι να χρησιμοποιήσετε το 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

Στη χωματερή myfirst-0-0.pcap (συσκευή πελάτη) μπορείτε να δείτε ότι το πακέτο ηχούς αποστέλλεται μετά από 2 δευτερόλεπτα προσομοίωσης. Αν κοιτάξετε τη δεύτερη χωματερή (myfirst-1-0.pcap), θα δείτε ότι το πακέτο λαμβάνεται στα 2,257324 δευτερόλεπτα. Θα δείτε στη δεύτερη ένδειξη ότι το πακέτο επιστρέφεται στα 2.257324 δευτερόλεπτα και τέλος ότι το πακέτο ελήφθη πίσω από τον πελάτη στην πρώτη ένδειξη στα 2.514648 δευτερόλεπτα.

Ανάγνωση εξόδου με το Wireshark

Εάν δεν είστε εξοικειωμένοι με Wireshark, υπάρχει ένας ιστότοπος από τον οποίο μπορείτε να κατεβάσετε προγράμματα και τεκμηρίωση: http://www.wireshark.org/. Wireshark είναι ένα GUI που μπορεί να χρησιμοποιηθεί για την εμφάνιση αυτών των αρχείων παρακολούθησης. Εάν έχετε Wireshark, μπορείτε να ανοίξετε οποιοδήποτε από τα αρχεία παρακολούθησης και να εμφανίσετε τα περιεχόμενα σαν να είχατε καταγράψει τα πακέτα χρησιμοποιώντας έναν ανιχνευτή πακέτων.

Πηγή: www.habr.com

Προσθέστε ένα σχόλιο