Softwareschnittstelle
Motivation
• Erfolg des Internets zurückzuführen auf
• Eine gute/sinnvolle Netzwerkarchitektur
• Großteil der Funktionalität über Software auf gewöhnlichen Rechnern am Rand des Netzes
• Neue Funktionen können mit kleinen Programmieraufwand hinzugefügt werden
• Seit Kommerzialisierung des Internet
• Neue Anwendungen und Dienste in einem unglaublichen Tempo aufgetaucht
• Massive Zunahme der Rechenleistung von gewöhnlichen Rechnersystemen
• Es gibt mittlerweile viele Software‐Umgebungen, Tools und Infrastruktur mit denen
• nicht nur einige wenige Spezialisten vernetzte Anwendungen schreiben können
• die Arbeit und die Erschließung neuer Märkte wie Anwendungen für Smartphones erleichtert wird
• Implementierung von Netzwerksoftware hilft dem Verständnisses von Computernetzwerken
• Unwahrscheinlich dass man ein Low‐Level‐Protokoll wie IP angeht
• Aber denkbar ein Protokoll auf Anwendungsebene zu implementieren (die nächste „Killer‐App“ kommt vielleicht von Euch!!!)
• Hier betrachten wir eine low‐level und weit verbreitete Programmierschnittstelle auf der Anwendungsebene sockets (API zur Interprozesskommunikation (IPC))
Socket‐Schnittstelle
• Die meisten Netzwerkprotokolle sind in Software realisiert
• Netzwerkprotokolle sind typischerweise als Teil des Betriebssystems implementiert
• Betriebssystem stellt in der Regel eine Network API (Application Programming Interface) zur Verfügung
• Netzwerk‐API kann beliebig definiert sein
• Z.B. die Socket‐Schnittstelle der Berkeley Software Distribution (BSD) von Unix [Usprung im ARPANET in 1971; API im BSD Unix seit 1983 (Berkeley sockets)]
• Diese ist auf praktisch alle gängigen Betriebssysteme portiert
• Unabhängig dazu gibt es auch programmiersprachenspezifische Schnittstellen die auf den System‐Calls (in C) direkt aufbauen
• Betrachten hier z.B. die Python‐Socket‐Bibliothek
[Für eine gute Guideline siehe z.B. https://realpython.com/python‐sockets/]
• Socket‐Schnittstelle
• Wesentliche Abstraktion: der Socket als Punkt, an dem ein lokaler Anwendungsprozess mit dem Netzwerk verbunden wird
• Die Schnittstelle definiert Vorgänge zum Erstellen eines Sockets, zum Anschließen des Sockets an das Netzwerk, zum Senden / Empfangen von Nachrichten über den Socket
Wesentliche Socket‐API‐Funktionen (hier in C)
Erzeugen eines Sockets
int socket(int domain, int type, int protocol) domain : PF_INET, PF_UNIX, PF_PACKET, ...
type : SOCK_STREAM, SOCK_DGRAM, ...
protocol : UNSPEC, ...
Passive‐Open auf der Server‐Seite
int bind(int socket, struct sockaddr *address, int len) int listen(int socket, int backlog)
int accept(int socket, struct sockaddr *address, int *len) address : enthält IP-Adresse und Port
backlog : Anzahl erlaubter Pending-Connections
Active‐Open auf der Client‐Seite
int connect(int socket, struct sockaddr *address, int len)
Senden und Empfangen von Daten
int send(int socket, char *message, int len, int flags)
int recv(int socket, char *buffer, int len, int flags)
Der übliche Protokollablauf
Beispiel: Echo‐Client und Server
Das folgende Python‐Beispiel inklusive Test findet man unter https://realpython.com/python‐sockets/
Echo‐Server Echo‐Client
Request[<Text>]
Reply[<Text>]
Zum Testen nehmen wir das Loopback‐Interface 127.0.0.1
(aka. localhost)
Echo‐Server
Projekt: implementiere einen Echo‐Server auf Port 65432 und einer IP Deiner Wahl
import socket
HOST = '127.0.0.1' # Standard loopback interface address (localhost)
PORT = 65432 # Port to listen on (non-privileged ports are > 1023) with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((HOST, PORT)) s.listen()
conn, addr = s.accept() with conn:
print('Connected by', addr) while True:
data = conn.recv(1024) if not data:
break
conn.sendall(data)
Projekt: implementiere einen Echo‐Client, der auf Deinen Server zugreift
Echo‐Client
import socket
HOST = '127.0.0.1' # The server's hostname or IP address PORT = 65432 # The port used by the server
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, PORT)) s.sendall(b'Hello, world') data = s.recv(1024)
print('Received', repr(data))
Testen der Software
Erreichbarkeit von Hosts
Aktuelle Verbindungen
Inspektion von Nachrichten
ping <IP-Adresse> # z.B. ping 127.0.0.1
netstat # z.B. netstat |grep 65432
sudo wireshark
Performance
Zwei wesentliche Kenngrößen: Bandbreite und Latenz
Bandbreite
1 s
1 Sekunde
0 1 1 0 0 1 1 …
Bandbreite b in obigem Beispiel:
Bps und bps
Kenngröße Größenordnung Wert
KBps 2
10Byte/s 1.024
MBps 2
20Byte/s 1.048.576
GBps 2
30Byte/s 1.073.741.824
TBps 2
40Byte/s 1.099.511.627.776
Kbps 10
3Bits/s 1.000
Mbps 10
6Bits/s 1.000.000
Gbps 10
9Bits/s 1.000.000.000
Tbps 10
12Bits/s 1.000.000.000.000
Vereinfachung für Überschlagsrechnungen:
Ergänzung zur Diskussion Bps und bps
• Vorige Tabelle ist konform mit standard Rechnernetze‐Literatur
(z.B. Tanenbaum)
• Dummerweise gilt je nach Kontext mal
– KB = 210Byte, MB = 220Byte, GB = 230Byte, … oder
– KB = 103Byte, MB = 106Byte, GB = 109Byte, …
• D.h. einmal Verwendung als Binärpräfix (wie z.B. hier) oder Verwendung als sogenannte SI‐Einheit
• Aus diesem Grund hat die International
Electrotechnical Commission (IEC) schon vor vielen Jahren die weiteren Einheiten KiB, MiB, GiB, … eingeführt
Bezeichnung Größenordnung KiB (kibibyte) 2
10Byte MiB (mebibyte) 2
20Byte GiB (gibibyte) 2
30Byte TiB (tebibyte) 2
40Byte
…
Sobald man diese speziellen
Binärpräfixe verwendet, macht es
natürlich Sinn die Größen KB, MB, GB,
TB, … als SI‐Einheiten zu verwenden,
d.h. in der Form 10
nmit n=3,6,9, 12 …
Zeit x zur Übertragung eines Bits bei Distanz d und Signalausbrei‐
tungsgeschwindigkeit l
Propagation‐Delay
H2 H1
d
Zeit x zur Übertragung von n Bits bei Distanz d Signalausbreitungs‐
geschwindigkeit l und Bandbreite b:
Delay einer Single‐Hop‐Übertragung
H2 H1
d
Zeit x zur Übertragung von n Bits bei Distanz d, Signalausbreitungs‐
geschwindigkeit l, Bandbreite b und Queuing‐Zeit q:
Delay einer Multi‐Hop‐Übertragung
H2 H1
d
Delay‐Bandbreiten‐Produkt
Bandbreite
Delay
Beispiel: Anzahl Bits n die ein Kanal mit 100ms Latenz und 50Mbps
Bandbreite speichert
Transferzeit und Effektiver Durchsatz
H2 H1
Beispiel: Überschlagsrechnung zu Transferzeit z und effektivem Durchsatz d und bei Abrufen einer 1MB Datei über einen Kanal mit 1Gbps Bandbreite und 92ms RTT:
Round‐Trip‐Zeit (RTT) =
Zeit von A nach B und zurück Transferzeit = 𝑅𝑇𝑇 öß Effektiver Durchsatz = öß
Eine weitere Größe: Jitter
• Ist ein Problem, wenn eine konstante Datenrate benötigt wird
• Sofern Latenz akzeptierbar ist Buffering die Lösung
• Diskussion: braucht z.B. ein Video eine konstante Daten‐Rate?
– Ja im Sinne von konstanter Rate von Bildern pro Sekunde
– Aber Kompression und Inhalt führt zu variabler Bitrate
Bitfehlerrate und Paketverlustrate
010100010111100010011101110010110001101
Bitfehler
Paketfehler
Paket 1 Paket 2 Paket 3 Paket 4
Einfacher Zusammenhang zwischen BER und PER, für n Bit
Nachrichten ohne Fehlerkorrektur und unabhängigen Bitfehlern
Additive und Bottleneck‐Kosten
H1 H2
R1
R2
R3
10ms 5ms 10ms
20ms
1Mbps 1Gbps 1Gbps
1Mbps
Beispiel: Delay d und Bandbreite b zwischen zwischen H1 und H2
e
1e
2e
3e
4Multiplikative Kosten
Beispiel: Gesamtpaketerfolgsrate bei gegebenen Paketverlustraten pro Link
H1 H2
R1
R2
R3 p
1=2/3 p
2=1/3 p
3=1/2
p
4=1/2
e
1e
2e
3e
4Performance
Beispiel: Effektiver Durchsatz von Packet‐Switching
Delay‐Einsparungen
H1 H2
Circuit‐Switching
R1 R2 H1 H2
Message‐Switching
R1 R2 H1 H2
Packet‐Switching
R1 R2
Einfluss der Paketgröße
H1
H2
R1 R2