Εργαστηριακή Άσκηση 3 1) Σκοπός της εργαστηριακής άσκησης Με αυτή την άσκηση εξετάζουμε τη συμπεριφορά του σημείου πρόσβασης (access point) σε ένα δίκτυο IEEE 802.11. Ακόμα, με αυτή την άσκηση θα μάθουμε τον τρόπο που εκτελούμε προσομοιώσεις εκτός του scratch. Το ασύρματο δίκτυο που εξετάζουμε αποτελείται συνολικά από τρεις κόμβους, ένας εκ των οποίων είναι και σημείο πρόσβασης (access point). 2) Παράμετροι Προσομοίωσης Αρχικά, Εισάγουμε τα απαραίτητα αρχεία κεφαλίδας (header files), καθορίζουμε το namespace που θα χρησιμοποιήσουμε, τις παραμέτρους που μπορούμε να περάσουμε μέσω του τερματικού και το επίπεδο καταγραφής των μηνυμάτων. #include "ns3/core-module.h" #include "ns3/network-module.h" #include "ns3/applications-module.h" #include "ns3/wifi-module.h" #include "ns3/mobility-module.h" #include "ns3/csma-module.h" #include "ns3/internet-module.h" #include "ns3/netanim-module.h" using namespace ns3; NS_LOG_COMPONENT_DEFINE ("lab3"); int main (int argc, char *argv[]) { uint32_t nwifi = 3; double xdist = 50.0; CommandLine cmd; cmd.addvalue ("xdist", "Distance between two nodes along axis x", xdist); cmd.parse (argc,argv); LogComponentEnable("UdpClient", LOG_LEVEL_INFO); LogComponentEnable("UdpServer", LOG_LEVEL_INFO); Στη συνέχεια, δημιουργούμε τους κόμβους του ασύρματου δικτύου κι ορίζουμε έναν από αυτούς ως «σημείο πρόσβασης» (Access Point). 1
NodeContainer wifistanodes, wifiapnode; wifistanodes.create (nwifi); wifiapnode = wifistanodes.get (0); Δημιουργούμε το φυσικό επίπεδο και το κανάλι και τα συσχετίζουμε, εφαρμόζοντας τις προεπιλεγμένες ρυθμίσεις. YansWifiChannelHelper channel = YansWifiChannelHelper::Default (); YansWifiPhyHelper phy = YansWifiPhyHelper::Default (); phy.setchannel (channel.create ()); Θέτουμε τον τύπο του αλγορίθμου για τον έλεγχο του ρυθμού και υλοποιούμε το επίπεδο MAC για το οποίο ορίζουμε ότι δεν θα παρέχει κάποιο μηχανισμό για Ποιότητα της Υπηρεσίας. WifiHelper wifi = WifiHelper::Default (); wifi.setremotestationmanager ("ns3::aarfwifimanager"); NqosWifiMacHelper mac = NqosWifiMacHelper::Default (); Ορίζουμε ένα SSID για το δίκτυο, καθώς επίσης δηλώνουμε ότι δε θα χρησιμοποιείται ο μηχανισμός Active Probing για την ανίχνευση του Access Point από τους κόμβους του δικτύου. Έτσι, θα χρησιμοποιούνται beacon frames όπως θα δούμε παρακάτω. Ssid ssid = Ssid ("ns-3-ssid"); mac.settype ("ns3::stawifimac", "Ssid", SsidValue (ssid), "ActiveProbing", BooleanValue (false)); Καθορίζουμε τις παραμέτρους φυσικού και επιπέδου MAC των κόμβων μας. Έτσι, δημιουργούμε τις συσκευές WiFi. NetDeviceContainer stadevices; stadevices = wifi.install (phy, mac, wifistanodes.get (1)); Ορίζουμε ένα SSID για το Access Point και το ρυθμίζουμε να στέλνει ένα beacon frame κάθε 5 δευτερόλεπτα. Με αυτό το beacon frame, το Access Point γνωστοποιεί την ύπαρξή του στους χρήστες που βρίσκονται εντός της περιοχής κάλυψής του (μηχανισμός Passive Scanning). mac.settype ("ns3::apwifimac", "Ssid", SsidValue (ssid), "BeaconGeneration", BooleanValue (true), "BeaconInterval", TimeValue (Seconds (5))); Δημιουργούμε τη συσκευή WiFi για το σημείο πρόσβασης καθορίζοντας τις παραμέτρους του Φυσικού και του MAC επιπέδου της. NetDeviceContainer apdevice; apdevice = wifi.install (phy, mac, wifiapnode); 2
Ορίζουμε τη θέση των κόμβων στο δίκτυό μας. MobilityHelper mobility; mobility.setpositionallocator ("ns3::gridpositionallocator", "MinX", DoubleValue (0.0), "MinY", DoubleValue (0.0), "DeltaX", DoubleValue (xdist), "DeltaY", DoubleValue (25.0), "GridWidth", UintegerValue (3), "LayoutType", StringValue ("RowFirst")); mobility.setmobilitymodel ("ns3::constantpositionmobilitymodel"); mobility.install (wifistanodes); Εγκαθιστούμε τη στοίβα πρωτοκόλλων TCP κι ορίζουμε τις IP διευθύνσεις των κόμβων. InternetStackHelper stack; stack.install (wifistanodes); Ipv4AddressHelper address; Ipv4InterfaceContainer wifiinterfaces, wifiapinterface; address.setbase ("10.1.5.0", "255.255.255.0"); wifiapinterface = address.assign (apdevice); wifiinterfaces = address.assign (stadevices); Δημιουργούμε ένα κόμβο που θα λαμβάνει πακέτα (server), θέτουμε την πόρτα που θα στην οποία θα ακούει και καθορίζουμε τις χρονικές στιγμές έναρξης και λήξης της κίνησης. UdpServerHelper server (22000); ApplicationContainer serverapps = server.install (wifiapnode.get(0)); serverapps.start (Seconds (1.0)); serverapps.stop (Seconds (15.0)); Αντίστοιχα, δημιουργούμε τον κόμβο που θα στέλνει την κίνηση στο δίκτυο (client) και θέτουμε κάποιες παραμέτρους, όπως το χρονικό διάστημα μεταξύ δύο διαδοχικών πακέτων που θα στέλνονται, το μέγιστο αριθμό πακέτων που μπορεί να στείλει ο client και το μέγεθος του πακέτου. UdpClientHelper client (wifiapinterface.getaddress (0), 22000); client.setattribute ("Interval", TimeValue (Seconds (0.5))); client.setattribute ("PacketSize", UintegerValue (768)); ApplicationContainer clientapps = client.install (wifistanodes.get(1)); clientapps.start (Seconds (2.0)); clientapps.stop (Seconds (14.0)); 3
Ακολούθως, συμπληρώνουμε τους πίνακες δρομολόγησης. Ipv4GlobalRoutingHelper::PopulateRoutingTables (); Τέλος, Ρυθμίζουμε τη διάρκεια της προσομοίωσης και δημιουργούμε το αρχείο για το Network Animator. Simulator::Stop (Seconds (18.0)); AnimationInterface anim ("lab3.xml"); Simulator::Run (); Simulator::Destroy (); return 0; } Αποθηκεύουμε τον παραπάνω κώδικα σε ένα αρχείο με όνομα lab3.cc στην τοποθεσία nsallinone-3.**/ns-3.**/examples/tutorial. Η τοποθεσία ns-3.**/examples περιέχει μία σειρά από παραδείγματα για ένα ευρύ φάσμα τεχνολογιών και σεναρίων που υποστηρίζει ο NS3. Μας επιτρέπει να οργανώνουμε τα scripts μας σε φακέλους, κάτι το οποίο μπορούμε να το κάνουμε και στην τοποθεσία scratch. Η διαφορά στην περίπτωση της τοποθεσίας ns-3.**/examples εντοπίζεται στην ύπαρξη των αρχείων wscript που περιγράφουν τα περιεχόμενα του κάθε φακέλου. Τα wscripts είναι από τα βασικά συστατικά του NS3, με αποτέλεσμα να κρίνεται χρήσιμη η γνωριμία με αυτά στα πλαίσια του εργαστηρίου. Η μορφή των περιεχομένων ενός αρχείου wscript είναι η παρακάτω. def build(bld): obj = bld.create_ns3_program('hello-simulator', ['core']) obj.source = 'hello-simulator.cc' obj = bld.create_ns3_program('first', ['core', 'point-to-point', 'internet', 'applications']) obj.source = 'first.cc' obj = bld.create_ns3_program('second', ['core', 'point-to-point', 'csma', 'internet', 'applications']) obj.source = 'second.cc' obj = bld.create_ns3_program('third', ['core', 'point-to-point', 'csma', 'wifi', 'internet']) obj.source = 'third.cc' obj = bld.create_ns3_program('fourth', ['core']) obj.source = 'fourth.cc' obj = bld.create_ns3_program('fifth', ['core', 'point-to-point', 'internet', 'applications']) obj.source = 'fifth.cc' 4
obj = bld.create_ns3_program('sixth', ['core', 'point-to-point', 'internet', 'applications']) obj.source = 'sixth.cc' Με τις εντολές της μορφής: obj = bld.create_ns3_program('first', ['core', 'point-to-point', 'internet', 'applications']) obj.source = 'first.cc' Καθορίζουμε το όνομα μίας προσομοίωσης που υπάρχει στην ίδια τοποθεσία με το wscript (πχ first), τις εξαρτήσεις (dependencies) που έχει η εν λόγω προσομοίωση (πχ obj = bld.create_ns3_program(['core', 'point-to-point', 'internet', 'applications']), καθώς επίσης και το αρχείο που περιέχει την προσομοίωσή μας. Έτσι, για να μπορούμε να εκτελέσουμε το αρχείο lab3.cc μέσα από το examples/template, προσθέτουμε τις παρακάτω γραμμές στο αρχείο wscript. obj = bld.create_ns3_program(lab3, ['core', 'wifi', 'csma', 'netanim', 'internet', 'applications']) obj.source = 'lab3.cc' Για να εκτελέσουμε την προσομοίωσή μας μεταφερόμαστε με την κατάλληλη εντολή cd στην τοποθεσία ns-allinone-3.**/ns-3.** κι εκτελούμε την εντολή:./waf --run examples/tutorial/lab3 Με το NetAnim, ανοίγουμε το αρχείο lab3.xml που δημιουργήθηκε στην τοποθεσία nsallinone-3.**/ns-3.**. Παρακάτω βλέπουμε την τοπολογία του δικτύου της προσομοίωσής μας, όπως αυτή απεικονίζεται στο NetAnim: Μπορούμε να αποθηκεύσουμε τα αποτελέσματα της προσομοίωσης σε ένα αρχείο με την παρακάτω εντολή:./waf --run examples/tutorial/lab3 &> out3 5
Το αρχείο out3 βρίσκεται στην τοποθεσία ns-allinone-3.**/ns-3.**. Για ευκολότερη επεξεργασία των δεδομένων που περιέχει το αρχείο out3 θα χρησιμοποιήσουμε ένα script που είναι γραμμένο σε γλώσσα awk (βλέπε lab2). Αφού έχετε εκτελέσει το αρχείο lab3 και έχετε εξάγει τα αποτελέσματά του στο αρχείο out3, εκτελέστε στο τερματικό την παρακάτω εντολή: awk -f myawk.awk < out3 Με αυτό τον τρόπο, το myawk.awk αρχείο θα επεξεργαστεί τα δεδομένα του αρχείου out3 και θα τυπώσει στο τερματικό τα αποτελέσματα. Παράρτημα Κώδικα #include "ns3/core-module.h" #include "ns3/network-module.h" #include "ns3/applications-module.h" #include "ns3/wifi-module.h" #include "ns3/mobility-module.h" #include "ns3/csma-module.h" #include "ns3/internet-module.h" #include "ns3/netanim-module.h" using namespace ns3; NS_LOG_COMPONENT_DEFINE ("lab3"); int main (int argc, char *argv[]) { uint32_t nwifi = 3; double xdist = 50.0; CommandLine cmd; cmd.addvalue ("xdist", "Distance between two nodes along axis x", xdist); cmd.parse (argc,argv); LogComponentEnable("UdpClient", LOG_LEVEL_INFO); LogComponentEnable("UdpServer", LOG_LEVEL_INFO); NodeContainer wifistanodes, wifiapnode; wifistanodes.create (nwifi); wifiapnode = wifistanodes.get (0); YansWifiChannelHelper channel = YansWifiChannelHelper::Default (); 6
YansWifiPhyHelper phy = YansWifiPhyHelper::Default (); phy.setchannel (channel.create ()); WifiHelper wifi = WifiHelper::Default (); wifi.setremotestationmanager ("ns3::aarfwifimanager"); NqosWifiMacHelper mac = NqosWifiMacHelper::Default (); Ssid ssid = Ssid ("ns-3-ssid"); mac.settype ("ns3::stawifimac", "Ssid", SsidValue (ssid), "ActiveProbing", BooleanValue (false)); NetDeviceContainer stadevices; stadevices = wifi.install (phy, mac, wifistanodes.get (1)); mac.settype ("ns3::apwifimac", "Ssid", SsidValue (ssid), "BeaconGeneration", BooleanValue (true), "BeaconInterval", TimeValue (Seconds (5))); NetDeviceContainer apdevice; apdevice = wifi.install (phy, mac, wifiapnode); MobilityHelper mobility; mobility.setpositionallocator ("ns3::gridpositionallocator", "MinX", DoubleValue (0.0), "MinY", DoubleValue (0.0), "DeltaX", DoubleValue (xdist), "DeltaY", DoubleValue (25.0), "GridWidth", UintegerValue (3), "LayoutType", StringValue ("RowFirst")); mobility.setmobilitymodel ("ns3::constantpositionmobilitymodel"); mobility.install (wifistanodes); InternetStackHelper stack; stack.install (wifistanodes); Ipv4AddressHelper address; Ipv4InterfaceContainer wifiinterfaces, wifiapinterface; address.setbase ("10.1.5.0", "255.255.255.0"); wifiapinterface = address.assign (apdevice); wifiinterfaces = address.assign (stadevices); UdpServerHelper server (22000); 7
ApplicationContainer serverapps = server.install (wifiapnode.get(0)); serverapps.start (Seconds (1.0)); serverapps.stop (Seconds (15.0)); UdpClientHelper client (wifiapinterface.getaddress (0), 22000); client.setattribute ("Interval", TimeValue (Seconds (0.5))); client.setattribute ("PacketSize", UintegerValue (768)); ApplicationContainer clientapps = client.install (wifistanodes.get(1)); clientapps.start (Seconds (2.0)); clientapps.stop (Seconds (14.0)); Ipv4GlobalRoutingHelper::PopulateRoutingTables (); } Simulator::Stop (Seconds (18.0)); AnimationInterface anim ("lab3.xml"); Simulator::Run (); Simulator::Destroy (); return 0; 8
Άσκηση 1) Σκοπός της άσκησης Σε αυτή την άσκηση εξετάζουμε την επίδοση του μηχανισμού RTS/CTS σε ένα δίκτυο IEEE 802.11. Επίσης, πραγματοποιείται εξάσκηση στον εναλλακτικό τρόπο εκτέλεσης των προσομοιώσεων μέσα από κάποια τοποθεσία όπως η examples/tutorial, που επεξηγήθηκε παραπάνω. 2) Σενάριο Προσομοίωσης Το δίκτυο IEEE 802.11 που θα προσομοιωθεί αποτελείται από 9 κόμβους τοποθετημένους σε πλέγμα, χωρίς να μετακινούνται στο χώρο. 3) Παράμετροι Προσομοίωσης Δίνεται το παρακάτω τμήμα κώδικα: #include "ns3/core-module.h" #include "ns3/network-module.h" #include "ns3/applications-module.h" #include "ns3/wifi-module.h" #include "ns3/mobility-module.h" #include "ns3/csma-module.h" #include "ns3/internet-module.h" #include "ns3/netanim-module.h" using namespace ns3; NS_LOG_COMPONENT_DEFINE ("Lab3b"); int main (int argc, char *argv[]) { LogComponentEnable ("UdpClient", LOG_LEVEL_INFO); LogComponentEnable ("UdpServer", LOG_LEVEL_INFO); /* Τοποθετίστε εδώ τον κώδικα που θα σας ζητηθεί παρακάτω*/ phy.enablepcap ("lab3b", stadevices.get (0)); Simulator::Run (); Simulator::Destroy (); return 0; } 9
Μέσα στη συνάρτηση main: 1) Δημιουργήστε ένα δίκτυο IEEE 802.11 με 9 κόμβους. 2) Δημιουργήστε το φυσικό επίπεδο του δικτύου. 3) Εισάγετε το παρακάτω κομμάτι κώδικα για την ενεργοποίηση του μηχανισμού RTS/CTS: WifiHelper wifi = WifiHelper::Default (); wifi.setremotestationmanager ("ns3::aarfwifimanager"); Config::SetDefault ("ns3::wifiremotestationmanager::rtsctsthreshold", UintegerValue (0)); NqosWifiMacHelper mac = NqosWifiMacHelper::Default (); 4) Δημιουργήστε τις συσκευές WiFi. 5) Δημιουργήστε το πλέγμα όπου θα είναι τοποθετημένοι οι κόμβοι και ρυθμίστε τους κόμβους ώστε να μην κινούνται στο χώρο. Σημειώνουμε ότι στην κάθε σειρά του πλέγματος θα πρέπει να είναι τοποθετημένοι 3 κόμβοι. 6) Εισάγετε τη στοίβα του internet. 7) Ορίστε τις διευθύνσεις IP. 8) Δημιουργήστε 2 servers (κόμβος 0 και 2) και 2 clients (κόμβος 6 και 8). Ο κόμβος 6 να στέλνει κίνηση στον κόμβο 0 και ο κόμβος 8 να στέλνει κίνηση στον κόμβο 2 (6->0 και 8->2). Οι servers να ξεκινούν τις χρονική στιγμή 2 και να σταματούν τη χρονική στιγμή 10. Οι clients να ξεκινούν τις χρονικές στιγμές 3 και 3.15 αντίστοιχα, και να σταματούν τη χρονική στιγμή 9. Ορίστε το μέγεθος των πακέτων που θα στέλνουν οι clients να είναι ίσο με 1024 Bytes και το χρονικό διάστημα μεταξύ δύο διαδοχικών πακέτων (interval) να είναι ίσο με 0.01. Επιπλέον, ορίστε ως μέγιστο αριθμό πακέτων (MaxPackets) να είναι ίσο με 1000. 9) Ορίστε το συνολικό διάστημα της προσομοίωσης σε 12 secs. 10) Εκτελέστε τον κώδικα κι εξάγεται τα αποτελέσματα σε ένα αρχείο με όνομα homework. 11) Αναλύστε τα αποτελέσματα χρησιμοποιώντας το αρχείο myawk.awk. Πόσα πακέτα εστάλησαν και πόσα ελήφθησαν; Ποιες είναι οι τιμές για την απόλυα πακέτων, τη χρονική καθυστέρηση και τη ρυθμαπόδοση; 12) Αλλάξτε την τιμή του RtsCtsThreshold από 0 σε 1200 και κάντε πάλι τα δύο προηγούμενα ερωτήματα. Δώστε μία σύντομη εξήγηση. 10