Rechnernetze Übung 11 Frank Weinhold Professur VSR Fakultät für Informatik TU Chemnitz Juli 2011 Herr Müller (Test GmbH) Sekretärin (Super AG) T-NR. 111 T-NR. 885 Sekretärin (Test GmbH) Herr Meier (Super AG) T-NR. 255 T-NR. 597
Herr Müller (Test GmbH) T-NR. 111 Herr Meier (Super AG) T-NR. 597 IP: 192.168.43.9 MAC: 02-55-4A-89-4F-47 IP: 316.187.69.51 MAC: 08-48-5B-77-56-21 1 2 IP: 192.168.43.15 MAC: 02-00-4C-4F-4F-50 316.187.69.50 MAC: 02-55-4A-89-5D-87 IP: 10.25.6.45 MAC: 08-48-5B-77-89-23 IP: 10.25.6.10 MAC: 1A-45-5B-76-42-11 Vom 1.PC zu Router 1 IP (S) 192.168.43.15 (E) 10.25.6.10 MAC (Z) 02-55-4A-89-4F-47 (S) 02-00-4C-4F-4F-50 Daten Von Router 1 zu Router 2 IP (S) 192.168.43.15 (E) 10.25.6.10 MAC (Z) 08-48-5B-77-56-21 (S) 02-55-4A-89-5D-87 Daten Von Router 2 zu PC 2 IP (S) 192.168.43.15 (E) 10.25.6.10 MAC (Z) 1A-45-5B-76-42-11 (S) 08-48-5B-77-89-23 Daten Die Schicht 2 Adresse (in diesem Fall MAC) ändert sich (wird durch Router angepaßt). Die Schicht 3 Adresse bleibt unverändert in allen Datenframes, da sie eine Ende-zu-Ende-Adresse ist. S- Sender, E Empfänger, Z -Ziel
192.168.43.15 10.25.6.10 1 2 Vermittlungsschicht (Host-zu-Host-Kommunikation) P1 P1 P2 P3 P2 Transportschicht (Prozess-zu-Prozess-Kommunikation) OSI-Referenzmodell 7 Anwendung 6 Darstellung 5 Komm.-steuerung 4 Transport 3 Vermittlung 2 Sicherung 1 Bitübertragung Internet-Referenzmodell Anwendung Transport Internet Rechner- Netzanschluss
Port x Anwendung 1 (Prozess 1) Anwendung 2 (Prozess 2) Port y Transport Internet Rechner- Netzanschluss Sockets: standardisierte Programmierschnittstelle (API) für Anwendungen, um die Netzwerkprotokoll-Implementierung des Betriebssystems zu nutzen.
10.25.6.10:8080 1456 8080 P1 P1 1250 10.25.6.10:1250 P2 P3 P2 14589 192.168.43.15 10.25.6.10 Anwendung 1 (Prozess 1) Anwendung 2 (Prozess 2) Transportschicht Internet
Anwendung 1 (Prozess 1) Anwendung 2 (Prozess 2) Transportschicht Internet UDP TCP Internet Rechner- Netzanschluss Datagram Sockets (verbindungslos) Stream Sockets (verbindungsorientiert)
UDP stellt eine direkte Schnittstelle für IP dar Anwendungen können IP Pakete direkt verschicken, ohne Verbindungsaufbau unzuverlässig, verbindungslos, schnell Demultiplexing der empfangenen Pakete basiert auf der Port-Nummer, die im Datagrammkopf angegeben wird optionale Prüfsumme sehr viele Multimedia-Anwendungen verwenden UDP wegen den Leistungsvorteilen für Multimedia Daten wird teilweise keine zuverlässige Verbindung benötigt Quell-Port gibt die Port-Nummer des sendenden Prozesses an (für Antwort) da UDP verbindungslos, ist Quell-Port optional und kann auf 0 gesetzt werden Ziel-Port gibt an, welcher Prozess das Paket empfangen soll Längenfeld gibt Größe des Paketes, bestehend aus Daten und Header, in Oktetten an (min. 8) Prüfsummenfeld es kann 16 Bit große Prüfsumme mitgesendet werden wird über Pseudo-Header und Daten gebildet optional, wird aber in der Praxis fast immer benutzt, falls nicht, auf 0 gesetzt Daten Max. 65535 Byte Bit 0 16 32 48 64 Quell-Port Ziel-Port Länge Prüfsumme Daten
import socket s = socket.socket(socket.af_inet, socket.sock_dgram) s.bind(("", 1470)) msg,adr = s.recvfrom(1000) print "Empfange von Host %s, port %d: %s" % (adr[0], adr[1], msg) s.sendto("+++ " + msg + " +++", adr) s.close() import socket s = socket.socket(socket.af_inet, socket.sock_dgram) s.sendto("hallo hallo", ( 127.0.0.1, 1470)) msg,adr = s.recvfrom(1000) print "Empfange von Host %s, port %d: %s" % (adr[0], adr[1], msg) s.close()
import socket s = socket.socket(socket.af_inet, socket.sock_dgram) s.sendto("hallo hallo", ( 127.0.0.1, 1470)) msg,adr = s.recvfrom(1000) print "Empfange von Host %s, port %d: %s" % (adr[0], adr[1], msg) s.close() import socket s = socket.socket(socket.af_inet, socket.sock_dgram) s.bind(("", 1470)) msg,adr = s.recvfrom(1000) print "Empfange von Host %s, port %d: %s" % (adr[0], adr[1], msg) s.sendto("+++ " + msg + " +++", adr) s.close()
IP bietet Best Effort Keine Garantie für eine fehlerfreie und vollständige Übertragung UDP stellt eine direkte Schnittstelle für IP dar Protokoll nötig, dass die Probleme von IP behebt Verlust von Datenpaketen Richtige Reihenfolge der Datenpakete TCP - Transmission Control Protocol ermöglicht gesicherte Übertragung eines Bytestromes zwischen zwei Anwendungen über das unzuverlässige IP passt sich dynamisch an die Eigenschaften des Internets an (z.b. heterogene Topologien, schwankende Bandbreiten) Verbindungsverwaltung Verbindungsaufbau zwischen zwei Sockets gesicherter Verbindungsabbau alle übertragenen Daten müssen quittiert sein
Datenübertragung Vollduplex Fehlerkontrolle durch Folgenummern (Sequenznummern) Prüfsumme Quittierung Übertragungswiederholung im Fehlerfall Reihenfolge, Flusskontrolle (durch Fenstermechanismus) und Staukontrolle Unterstützung von Prioritäten Quelle: http://de.wikipedia.org/wiki/transmission_control_protocol (28.06.2009)
Drei-Wege-Handshake Start-Sequenznummer ist beliebige Zahl Generierung ist von TCP-Implementierung abhängig sollte möglichst zufällig sein, um Sicherheitsrisiken zu vermeiden Quelle: http://de.wikipedia.org/wiki/transmission_control_protocol (28.06.2009) kann von beiden Seiten initiiert werden Quelle: http://de.wikipedia.org/wiki/transmission_control_protocol (28.06.2009)
Sendewiederholung wegen verlorener Quittung Sendewiederholung aufeinanderfolgender Dateneinheiten
Kumulative Quittung vermeidet Sendewiederholung Erweiterungen der Quittierung in TCP RFC 2018: Selektive Quittungen import socket s = socket.socket(socket.af_inet, socket.sock_stream) s.bind(("", 8080)) s.listen(1) conn, addr = s.accept() print "Verbindung von Host: %s, port %d" % (addr[0], addr[1]) data = conn.recv(1024) print "empfangen: %s" % data conn.send("+++ " + data + " +++") conn.close() s.close()
import socket s = socket.socket(socket.af_inet, socket.sock_stream) s.connect(( 127.0.0.1, 8080)) s.send('hello, world') data = s.recv(1024) print "empfangen: %s" % data s.close() import socket s = socket.socket(socket.af_inet, socket.sock_stream) s.bind(("", 8080)) s.listen(1) conn, addr = s.accept() print "Verbindung von Host: %s, port %d" % (addr[0], addr[1]) data = conn.recv(1024) print "empfangen: %s" % data conn.send("+++ " + data + " +++") conn.close() s.close()
import socket s = socket.socket(socket.af_inet, socket.sock_stream) s.connect(( 127.0.0.1, 8080)) s.send('hello, world') data = s.recv(1024) print "empfangen: %s" % data s.close() Implementieren Sie einen Server, der verschiedene Rechenoperationen bereitstellt und einen dazugehörigen Klienten. Der Server soll am Port 8080 auf Anfragen von Klienten reagieren. Das Format der Anfrage sieht wie folgt aus: Operation*Zahl1*Zahl2 (Beispiel: ADD*3*2) Das Format des Ergebnisses soll folgendes Format besitzen: RESULTAT*Ergebnis (Beispiel: RESULTAT*5) Die Operationen ADD, SUB, MUL, DIV sollen unterstützt werden, alle Zahlen sind als Integer zu behandeln. Sollte das vom Klienten gesendete Format nicht dem Geforderten entsprechen, ist der Klient darüber zu informieren: Falsches Format! Im Fall, dass eine unbekannte Operation gefordert wird (Bsp: SQRT für Wurzeloperation), soll der Server darauf reagieren: Unbekannte Operation!
Beispiel: Anfrage des Klienten: ADD*4*2 Antwort des Servers: RESULTAT*6 Beispiel 2: Anfrage des Klienten: SQRT*16*2 Antwort des Servers: Unbekannte Operation!