Ασύρματες Κινητές Επικοινωνίες Ενότητα 4: Το πρωτόκολλο Transmission Control (TCP) Μιχάλας Άγγελος Τμήμα Μηχανικών Πληροφορικής ΤΕ
Άδειες Χρήσης Το παρόν εκπαιδευτικό υλικό υπόκειται σε άδειες χρήσης Creative Commons. Για εκπαιδευτικό υλικό, όπως εικόνες, που υπόκειται σε άλλου τύπου άδειας χρήσης, η άδεια χρήσης αναφέρεται ρητώς. 2
Χρηματοδότηση Το παρόν εκπαιδευτικό υλικό έχει αναπτυχθεί στα πλαίσια του εκπαιδευτικού έργου του διδάσκοντα. Το έργο «Ανοικτά Ακαδημαϊκά Μαθήματα του ΤΕΙ Δυτικής Μακεδονίας και της Ανώτατης Εκκλησιαστικής Ακαδημίας Θεσσαλονίκης» έχει χρηματοδοτήσει μόνο τη αναδιαμόρφωση του εκπαιδευτικού υλικού. Το έργο υλοποιείται στο πλαίσιο του Επιχειρησιακού Προγράμματος «Εκπαίδευση και Δια Βίου Μάθηση» και συγχρηματοδοτείται από την Ευρωπαϊκή Ένωση (Ευρωπαϊκό Κοινωνικό Ταμείο) και από εθνικούς πόρους. 3
Το πρωτόκολλο TCP
Σκοποί ενότητας Σε αυτή την ενότητα μελετούμε τη συμπεριφορά του παραθύρου συμφόρησης (Congestion Window - CW) του πρωτοκόλλου TCP. Επίσης, σκοπός της ενότητας είναι η εξοικείωση με το εργαλείο gnuplot. Χρησιμοποιείται για παραγωγή γραφικών παραστάσεων. Εκτελείται μέσω της γραμμής εντολών. 5
Περιεχόμενα ενότητας (1/3) Βασικές έννοιες. Αρχεία κεφαλίδας και χώρος ονομάτων. Η κλάση MyApp. Η μέθοδος δημιουργός της κλάσης MyApp. Υλοποίηση συναρτήσεων. Η συνάρτηση main. 6
Περιεχόμενα ενότητας (2/3) Υλοποίηση του Φυσικού επιπέδου του Wireless Fidelity (WiFi). Υλοποίηση του επιπέδου Medium Access Control (MAC) του WiFi. Δημιουργία των συσκευών WiFi. Ορισμός της θέσης των κόμβων. Καθορισμός διευθύνσεων Internet Protocol (IP). PacketSinkHelper. 7
Περιεχόμενα ενότητας (3/3) TCP client. Εντοπισμός απωλειών πακέτων και διάρκεια προσομοίωσης. Το εργαλείο Gnuplot. Δημιουργία γραφικής παράστασης με το Gnuplot. Ασκήσεις. 8
Βασικές έννοιες Το TCP είναι ένα πρωτόκολλο επιπέδου μεταφοράς, προσανατολισμένο στη σύνδεση. Υποστηρίζει έλεγχο ροής κι έλεγχο συμφόρησης. Ένας από τους υποστηριζόμενους μηχανισμούς είναι το CW, το οποίο συμβάλει στην αποφυγή συμφόρησης σε μία από άκρο σε άκρο σύνδεση. Το μέγεθος του CW καθορίζει τον πλήθος των δεδομένων που θα αποστέλλονται. Αυξάνεται κατά ένα Maximum Segment Size (MSS) κάθε φορά που ο δέκτης λαμβάνει ένα Acknowledge (ACK). Το μέγεθος του CW επανέρχεται στην αρχική του τιμή όταν δε ληφθεί ACK. 9
Αρχεία κεφαλίδας και χώρος ονομάτων Εισάγουμε τα απαραίτητα αρχεία κεφαλίδας (header files) και καθορίζουμε το χώρο ονομάτων (namespace). #include <fstream> #include "ns3/core-module.h" #include "ns3/network-module.h" #include "ns3/internet-module.h" #include "ns3/point-to-point-module.h" #include "ns3/applications-module.h" #include "ns3/wifi-module.h" #include "ns3/mobility-module.h" #include "ns3/netanim-module.h" using namespace ns3; NS_LOG_COMPONENT_DEFINE ("Lab4"); 10
Η κλάση MyApp Δημιουργούμε μία κλάση. Δηλώνουμε τη μέθοδο δημιουργό (constructor), καθώς και τις public και private συναρτήσεις και μεταβλητές. class MyApp : public Application { public: MyApp (); void Setup (Ptr<Socket> socket, Address address, uint32_tpacketsize, uint32_t npackets, DataRate datarate); private: virtual void StartApplication (void); virtual void StopApplication (void); void ScheduleTx (void); void SendPacket (void); Ptr<Socket> m_socket; Address m_peer; uint32_t m_packetsize; uint32_t m_npackets; DataRate m_datarate; EventId m_sendevent; bool m_running; uint32_t m_packetssent; }; 11
Η μέθοδος δημιουργός της κλάσης MyApp Δημιουργούμε τη μέθοδο δημιουργό. MyApp::MyApp () : m_socket (0), m_peer (), m_packetsize (0) m_npackets (0), m_datarate (0), m_sendevent (), m_running (false), m_packetssent (0) {} 12
Υλοποίηση συναρτήσεων (1/7) Υλοποιούμε τις συναρτήσεις που ορίσαμε στην κλάση. Η συνάρτηση Setup αρχικοποιεί κάποιες μεταβλητές, για τις οποίες λαμβάνει τιμές από τα ορίσματά της. voidmyapp::setup (Ptr<Socket> socket, Address address, uint32_t packetsize, uint32_t npackets, DataRate datarate){ m_socket = socket; m_peer = address; m_packetsize = packetsize; m_npackets = npackets; m_datarate = datarate; } 13
Υλοποίηση συναρτήσεων (2/7) Η συνάρτηση StartApplication. Ξεκινάει την εφαρμογή MyApp και αποστέλλει πακέτα, καλώντας τη συνάρτηση SendPacket, που περιγράφεται παρακάτω. voidmyapp::startapplication (void){ m_running = true; m_packetssent = 0; m_socket->bind (); m_socket->connect (m_peer); SendPacket (); } 14
Υλοποίηση συναρτήσεων (3/7) Η συνάρτηση StopApplication σταματάει την εφαρμογή MyApp. void MyApp::StopApplication (void){ m_running = false; if (m_sendevent.isrunning ()) { Simulator::Cancel (m_sendevent); } if (m_socket) { m_socket->close (); } } 15
Υλοποίηση συναρτήσεων (4/7) Η συνάρτηση SendPacket αποστέλλει ένα πακέτο. Επιπλέον, καλεί τη συνάρτηση ScheduleTx, η οποία καθορίζει το πότε θα αποσταλεί το επόμενο πακέτο. void MyApp::SendPacket (void){ Ptr<Packet> packet = Create<Packet> (m_packetsize); m_socket->send (packet); if (++m_packetssent < m_npackets) { ScheduleTx (); } } 16
Υλοποίηση συναρτήσεων (5/7) Η συνάρτηση ScheduleTx. void MyApp::ScheduleTx (void){ if (m_running) { Time tnext (Seconds (m_packetsize * 8 / static_cast<double> (m_datarate.getbitrate ()))); m_sendevent = Simulator::Schedule (tnext, &MyApp::SendPacket, this); } } 17
Υλοποίηση συναρτήσεων (6/7) Οι συναρτήσεις CwndChange και RxDrop καταγράφουν τη συμπεριφορά του CW. Η CwndChange καταγράφει τις μεταβολές του μεγέθους CW. static voidcwndchange (uint32_t oldcwnd, uint32_t newcwnd){ std::cout<<simulator::now ().GetSeconds () << "\t" << newcwnd<<std::endl; } 18
Υλοποίηση συναρτήσεων (7/7) Η RxDrop καταγράφει τα συμβάντα απώλειας πακέτων. Οδηγούν σε μείωση του μεγέθους του CW. static voidrxdrop (Ptr<const Packet> p){ std::cout<<"rx drop at: " << Simulator::Now ().GetSeconds ()<<std::endl; } 19
Η συνάρτηση main Ορίζουμε τη συνάρτηση main και δημιουργούμε δύο κόμβους δικτύου. int main (int argc, char *argv[]){ NodeContainer wifistanodes; wifistanodes.create (2); 20
Υλοποίηση του Φυσικού επιπέδου του WiFi Δημιουργούμε το φυσικό επίπεδο και το κανάλι και τα συσχετίζουμε. Εφαρμόζουμε τις προεπιλεγμένες ρυθμίσεις. YansWifiChannelHelper channel = YansWifiChannelHelper::Default (); YansWifiPhyHelper phy = YansWifiPhyHelper::Default (); phy.setchannel (channel.create ()); 21
Υλοποίηση του επιπέδου MAC του WiFi Θέτουμε τον αλγόριθμο για τον έλεγχο του ρυθμού και υλοποιούμε το επίπεδο MAC για το οποίο ορίζουμε ότι δεν θα παρέχει κάποιο μηχανισμό για Ποιότητα της Υπηρεσίας. WifiHelper wifi = WifiHelper::Default (); wifi.setremotestationmanager ("ns3::aarfwifimanager"); Config::SetDefault ("ns3::wifiremotestationmanager::rtsctsthreshold", UintegerValue(0)); NqosWifiMacHelper mac = NqosWifiMacHelper::Default (); 22
Δημιουργία των συσκευών WiFi Καθορίζουμε τις παραμέτρους φυσικού και MAC επιπέδου των κόμβων μας κι έτσι δημιουργούμε τις συσκευές WiFi. NetDeviceContainer stadevices; stadevices = wifi.install (phy, mac, wifistanodes); 23
Ορισμός της θέσης των κόμβων Ορίζουμε τη θέση των κόμβων στο δίκτυό μας. MobilityHelper mobility; mobility.setpositionallocator("ns3::gridpositionallocator", "MinX", DoubleValue (0.0), "MinY", DoubleValue (0.0), "DeltaX", DoubleValue (50.0), "DeltaY", DoubleValue (20.0), "GridWidth", UintegerValue (3), "LayoutType", StringValue ("RowFirst")); mobility.setmobilitymodel ("ns3::constantpositionmobilitymodel"); mobility.install (wifistanodes); 24
Καθορισμός διευθύνσεων IP Εγκαθιστούμε τη στοίβα πρωτοκόλλων TCP κι ορίζουμε τις IP διευθύνσεις των συσκευών. InternetStackHelper stack; stack.install (wifistanodes); Ipv4AddressHelper address; address.setbase ("10.1.5.0", "255.255.255.252"); Ipv4InterfaceContainer interfaces = address.assign (stadevices); 25
PacketSinkHelper Ορίζουμε ένα αντικείμενο PacketSinkHelper. Διαδραματίζει το ρόλο του server λαμβάνοντας δεδομένα. Το συσχετίζουμε με τον κόμβο 0. uint16_t sinkport = 8080; Address sinkaddress (InetSocketAddress (interfaces.getaddress (0), sinkport)); PacketSinkHelper packetsinkhelper ("ns3::tcpsocketfactory", InetSocketAddress (Ipv4Address::GetAny (), sinkport)); ApplicationContainer sinkapps = packetsinkhelper.install wifistanodes.get (0)); sinkapps.start (Seconds (5.0)); sinkapps.stop (Seconds (25.0)); 26
TCP client Ορίζουμε τον κόμβο 1 να είναι ένας TCP client. Θα διατηρεί ένα CW. Θα διαθέτει μία εφαρμογή MyApp, η οποία αποστέλλει δεδομένα με ρυθμό 0.5 Mbps. Ptr<Socket> ns3tcpsocket = Socket::CreateSocket (wifistanodes.get (1), TcpSocketFactory::GetTypeId ()); ns3tcpsocket->traceconnectwithoutcontext ("CongestionWindow", MakeCallback (&CwndChange)); Ptr<MyApp> app = CreateObject<MyApp> (); app->setup (ns3tcpsocket, sinkaddress, 1040, 1000, DataRate("0.5Mbps")); wifistanodes.get (0)->AddApplication (app); app->setstarttime (Seconds (6.0)); app->setstoptime (Seconds (25.0)); 27
Εντοπισμός απωλειών πακέτων και διάρκεια προσομοίωσης Δίνουμε τη δυνατότητα στο TCP client να εντοπίζει απώλειες πακέτων. Ορίζουμε τη διάρκεια της προσομοίωσης. stadevices.get (1)->TraceConnectWithoutContext ("PhyRxDrop", MakeCallback (&RxDrop)); Simulator::Stop (Seconds (25)); AnimationInterface anim ("lab4.xml"); Simulator::Run (); Simulator::Destroy (); return 0; } 28
Απεικόνιση της προσομοίωσης με το NetAnim Ανοίγουμε το αρχείο lab4.xml με το NetAnim. Εικόνα 1. Απεικόνιση της προσομοίωσης από το NetAnim, εμφάνιση μετά την εγκατάσταση του προγράμματος ns-3, ελεύθερο λογισμικό, με άδεια GNU GPLv2 license, διαθέσιμο στο κοινό για έρευνα, ανάπτυξη και χρήση. 29
Το εργαλείο Gnuplot Αποθηκεύουμε τον παραπάνω κώδικα σε ένα αρχείο με όνομα lab4.cc. Μεταβαίνουμε στην τοποθεσία από όπου εκτελούμε τα σενάρια κι εκτελούμε την προσομοίωση με την εντολή:./waf --run lab4 > cwnd.dat 2>&1. Ανοίγουμε το gnuplot στην γραμμή εντολών με την εντολή: gnuplot. 30
Δημιουργία γραφικής παράστασης με το Gnuplot (1/4) Μέσα από το περιβάλλον του gnuplot. Ορίζουμε τον τύπο (png) και μέγεθος της εικόνας που θα περιέχει τη γραφική παράσταση σε 640x480 pixels με την εντολή: set terminal png size 640, 480. Δίνουμε το όνομα cwnd.png στην εικόνα με την εντολή: set output cwnd.png. 31
Δημιουργία γραφικής παράστασης με το Gnuplot (2/4) Καθορίζουμε ως όνομα ετικέτας για τον άξονα x το time με την εντολή: set xlabel time. Καθορίζουμε ως όνομα ετικέτας για τον άξονα y το congestion window size με την εντολή: set ylabel congestion window size. 32
Δημιουργία γραφικής παράστασης με το Gnuplot (3/4) Δημιουργούμε τη γραφική παράσταση. Καθορίζουμε το αρχείο από το ποίο θα λάβει τα δεδομένα (cwnd.dat). Συγκεκριμένα τις στήλες του αρχείου στις οποίες θα βασίζονται οι άξονες x και y (1 και 2, αντίστοιχα). Επίσης καθορίζουμε τον τίτλο της γραφικής παράστασης και τον τύπο αναπαράστασης (Congestion Window και linespoints, αντίστοιχα). plot cwnd.dat using 1:2 title Congestion Window with linespoints 33
Δημιουργία γραφικής παράστασης με το Gnuplot (4/4) Η γραφική παράσταση που δημιουργήσαμε. Εικόνα 2. Γραφική παράσταση, εμφάνιση μετά την εγκατάσταση του προγράμματος ns-3, ελεύθερο λογισμικό, με άδεια GNU GPLv2 license, διαθέσιμο στο κοινό για έρευνα, ανάπτυξη και χρήση. 34
Ασκήσεις (1/18) 1. Δημιουργήστε ένα νέο αρχείο με όνομα lab4b.cc και εισάγετε τον παρακάτω κώδικα. #include "ns3/core-module.h" #include "ns3/point-to-point-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" #include "ns3/olsr-helper.h" using namespace ns3; NS_LOG_COMPONENT_DEFINE ("Lab4b"); 35
Συνέχεια κώδικα. Ασκήσεις (2/18) int main (int argc, char *argv[]){ uint32_t nwifi = 8; double dist = 30; CommandLine cmd; cmd.addvalue ("nwifi", "Number of wifi devices", nwifi); cmd.parse (argc,argv); LogComponentEnable ("UdpClient", LOG_LEVEL_INFO); LogComponentEnable ("UdpServer", LOG_LEVEL_INFO); 36
Ασκήσεις (3/18) Συνέχεια κώδικα NodeContainer wifistanodes; wifistanodes.create (nwifi); YansWifiChannelHelper channel=yanswifichannelhelper::default (); YansWifiPhyHelper phy = YansWifiPhyHelper::Default (); phy.setchannel (channel.create ()); WifiHelper wifi = WifiHelper::Default (); wifi.setremotestationmanager ("ns3::aarfwifimanager"); Config::SetDefault ("ns3::wifiremotestationmanager::rtsctsthreshold", UintegerValue(0)); NqosWifiMacHelper mac = NqosWifiMacHelper::Default (); 37
Ασκήσεις (4/18) Συνέχεια κώδικα. NetDeviceContainer stadevices; stadevices = wifi.install (phy, mac, wifistanodes); MobilityHelper mobility; mobility.setpositionallocator ("ns3::gridpositionallocator", "MinX", DoubleValue (0.0), "MinY", DoubleValue (0.0), "DeltaX", DoubleValue (dist), "DeltaY", DoubleValue (10.0), "GridWidth", UintegerValue (3), "LayoutType", StringValue ("RowFirst")); mobility.setmobilitymodel ("ns3::constantpositionmobilitymodel"); mobility.install (wifistanodes); 38
Ασκήσεις (5/18) Συνέχεια κώδικα. InternetStackHelper stack; stack.install (wifistanodes); Ipv4AddressHelper address; address.setbase ("10.1.7.0", "255.255.255.0"); address.assign (stadevices); Ipv4InterfaceContainer interfaces = address.assign(stadevices); 39
Ασκήσεις (6/18) Συνέχεια κώδικα. UdpServerHelper server (22000); ApplicationContainer serverapps1 = server.install (wifistanodes.get (0)); serverapps1.start (Seconds (1.0)); serverapps1.stop (Seconds (11.0)); UdpServerHelper server2 (23000); ApplicationContainer serverapps2 = server2.install (wifistanodes.get (2)); serverapps2.start (Seconds (1.0)); serverapps2.stop (Seconds (11.0)); 40
Ασκήσεις (7/18) Συνέχεια κώδικα. UdpClientHelper client (interfaces.getaddress (0), 22000); client.setattribute ("Interval", TimeValue (Seconds (0.01))); client.setattribute ("PacketSize", UintegerValue (1024)); client.setattribute ("MaxPackets", UintegerValue (15000)); ApplicationContainer clientapps = client.install (wifistanodes.get (5)); clientapps.start (Seconds (3.0)); clientapps.stop (Seconds (10.0)); 41
Ασκήσεις (8/18) Συνέχεια κώδικα. UdpClientHelper client2 (interfaces.getaddress (2), 23000); client2.setattribute ("Interval", TimeValue (Seconds (0.01))); client2.setattribute ("PacketSize", UintegerValue (1024)); client2.setattribute ("MaxPackets", UintegerValue (15000)); ApplicationContainer clientapps2 = client2.install (wifistanodes.get (6)); clientapps2.start (Seconds (3.05)); clientapps2.stop (Seconds (10.0)); 42
Ασκήσεις (9/18) Συνέχεια κώδικα. Simulator::Stop (Seconds (12.0)); AnimationInterface anim ("lab4b.xml"); Simulator::Run (); Simulator::Destroy (); return 0; } 43
Ασκήσεις (10/18) 2. Εκτελέστε το αρχείο lab4b.cc πέντε φορές χρησιμοποιώντας κάθε φορά διαφορετικό interval (0.01, 0.007, 0.005, 0.0035 και 0.002). Κάθε φορά που θα εκτελείτε το σενάριο, εισάγετε τα αποτελέσματα που προκύπτουν από το αρχείο awk σε ένα αρχείο με όνομα results.dat. Η τελική μορφή του αρχείου results.dat πρέπει να είναι η ακόλουθη: αποτελέσματα 1 ης εκτέλεσης αποτελέσματα 2 ης εκτέλεσης αποτελέσματα 3 ης εκτέλεσης αποτελέσματα 4 ης εκτέλεσης αποτελέσματα 5 ης εκτέλεσης 44
Ασκήσεις (11/18) 3. Ανοίξτε το αρχείο results.dat και εισάγετε στην αρχή κάθε γραμμής την κίνηση (traffic) που αντιστοιχεί στο κάθε interval. Δηλαδή, το αρχείο results.dat τροποποιείται ως εξής. traffic1 αποτελέσματα 1 ης εκτέλεσης traffic2 αποτελέσματα 2 ης εκτέλεσης traffic3 αποτελέσματα 3 ης εκτέλεσης traffic4 αποτελέσματα 4 ης εκτέλεσης traffic5 αποτελέσματα 5 ης εκτέλεσης Σημείωση: Η κίνηση υπολογίζεται από τον τύπο traffic=interval/μέγεθος_πακέτου*8, δηλαδή traffic=interval/1024*8 στην περίπτωσή μας. 45
Ασκήσεις (12/18) 4. Εξάγετε 2 γραφικές παραστάσεις. Μία για το throughput και μία για το delay, αντίστοιχα. Οι παράμετροι των γραφικών παραστάσεων είναι οι εξής. Μέγεθος εικόνας: 640x480. Ονόματα αρχείων: throughput1.png και delay1.png, αντίστοιχα. Όνομα άξονα x: Traffic. 46
Ασκήσεις (13/18) Συνέχεια Άσκησης 4. Ονόματα αξόνων y: Throughput και Delay, αντίστοιχα. Τίτλοι γραφικών παραστάσεων: Throughput και Delay, αντίστοιχα. Τύπος γραφήματος: linespoints. 47
Ασκήσεις (14/18) 5. Ορίστε το interval σε 0.15 κι εκτελέστε την προσομοίωση 4 φορές χρησιμοποιώντας κάθε φορά διαφορετικό μέγεθος πακέτου (256, 512, 768 και 1024). Κάθε φορά που θα εκτελείτε το σενάριο, εισάγετε τα αποτελέσματα που προκύπτουν από το αρχείο awk σε ένα αρχείο με όνομα results.dat. Η τελική μορφή του αρχείου results.dat πρέπει να είναι η ακόλουθη. αποτελέσματα 1 ης εκτέλεσης αποτελέσματα 2 ης εκτέλεσης αποτελέσματα 3 ης εκτέλεσης αποτελέσματα 4 ης εκτέλεσης αποτελέσματα 5 ης εκτέλεσης 48
Ασκήσεις (15/18) 6. Παρόμοια με την άσκηση 3, τροποποιείστε κατάλληλα το αρχείο results.dat (αντί για traffic να έχει το packetsize). 7. Δημιουργήστε 2 γραφικές παραστάσεις, μία για το throughput και μία για το delay, αντίστοιχα. Οι παράμετροι των γραφικών παραστάσεων είναι οι εξής: Μέγεθος εικόνας: 640x480. Ονόματα αρχείων: throughput2.png και delay2.png, αντίστοιχα. 49
Ασκήσεις (16/18) Συνέχεια Άσκησης 7. Όνομα άξονα x: PacketSize. Ονόματα αξόνων y: Throughput και Delay, αντίστοιχα. Τίτλοι γραφικών παραστάσεων: Throughput και Delay, αντίστοιχα. Τύπος γραφήματος: linespoints. 50
Ασκήσεις (17/18) 8. Εξάγετε 2 αντίστοιχες γραφικές παραστάσεις με την άσκηση 7, εφαρμόζοντας τις ακόλουθες παραμέτρους: a. Εύρος τιμών άξονα x από 0 έως 1800, χρησιμοποιώντας την παρακάτω εντολή: set xrange [0:1800]. b. Εύρη τιμών αξόνων y από 1000000 έως 8000000 κι από 0 έως 1, χρησιμοποιώντας τις παρακάτω εντολές, αντίστοιχα: set yrange [1000000:8000000] και set yrange [0:1]. 51
Ασκήσεις (18/18) 9. Δημιουργήστε τη γραφική παράσταση του σεναρίου lab4.cc. Δώστε μία σύντομη εξήγηση για τη γραφική παράσταση. 52
Βιβλιογραφία 1. Βασικές Αρχές Ασύρματης Επικοινωνίας, David Tse, Pramod Viswanath, Εκδόσεις Κλειδάριθμος. 2. ΔΙΚΤΥΑ ΚΙΝΗΤΩΝ & ΠΡΟΣΩΠΙΚΩΝ ΕΠΙΚΟΙΝΩΝΙΩΝ, Θεολόγου Μ., Εκδοτικός Οίκος: ΤΖΙΟΛΑ Έτος έκδοσης: 2007 ISBN: 978-960-418-126-1. 3. Εισαγωγή στα ασύρματα συστήματα, Black, Dipiazza, Ferguson. 4. Συστήματα Κινητών Επικοινωνιών, Κανάτας Αθανάσιος, Κωνσταντίνου Φίλιππος, Πάντος Γεώργιος. 53
Τέλος Ενότητας