Der Ablauf als Zustände
Das einfachste zuverlässige Protokoll heißt Stop-and-Wait: Der Sender schickt ein Paket und wartet auf die Quittung, bevor das nächste folgt.
- Sender:Zustände Senden und Warten; passende Quittung → nächstes Paket, Timeout → dasselbe Paket noch einmal.
- Empfänger:Rahmen zerlegen, Nutzdaten speichern, mit
ACKund Nummer antworten. - Timeout:Wartezeit, nach der der Sender einen Verlust annimmt; länger als Hin- und Rückweg zusammen.
- Duplikate:geht nur die Quittung verloren, kommt ein Paket doppelt an — der Empfänger erkennt es an der Nummer.
Starte die Übertragung von HALLO WELT in drei Paketen mit ▶ oder gehe mit „Schritt“ von Ereignis zu Ereignis. Links leuchtet die Zeile des Senders, die gerade läuft. Lass dann ein Paket oder eine Quittung verloren gehen.
- 1def senden(pakete, kanal):
- 2 nr = 0
- 3 while nr < len(pakete):
- 4 rahmen = f"#{nr};{pakete[nr]}$"
- 5 kanal.schicke(rahmen)
- 6 antwort = kanal.warte_auf_ack(3)
- 7 if antwort == f"ACK{nr}":
- 8 nr = nr + 1
- 9 # sonst: Timeout, gleiches Paket erneut
Halte fest: Der Sender schickt erst weiter, wenn die passende Quittung da ist. Bleibt sie aus, sendet er nach dem Timeout erneut — ein doppelt ankommendes Paket erkennt der Empfänger an der Nummer.
Den Empfänger programmieren
Der Rahmen hat das Format #nr;daten$ aus 7.3.2. Der Empfänger schneidet Start- und Endzeichen ab, trennt am Semikolon und prüft die Nummer.
def empfangen(rahmen, erwartet, daten): inhalt = rahmen[1:-1] # '#' und '$' abschneiden nr_text, nutz = inhalt.split(";") nr = int(nr_text) if nr == erwartet: # neues Paket daten.append(nutz) erwartet = erwartet + 1 return f"ACK{nr}", erwartet # auch Duplikate quittieren
- Zerlegen:
rahmen[1:-1]entfernt das erste und das letzte Zeichen;split(";")trennt Nummer und Nutzdaten. - Prüfen:nur ein Paket mit der erwarteten Nummer wird gespeichert.
- Quittieren:immer — sonst wartet der Sender nach einem verlorenen ACK ewig.
- Testen:Fälle durchspielen: alles glatt, Paket verloren, Quittung verloren.
Stop-and-Wait: Senden → auf ACKnr warten → bei passender Quittung nr + 1, bei Timeout dasselbe Paket erneut senden
Allgemeine Hinweise
Doppelte Daten vermeiden
Wer ein Duplikat erneut speichert, erhält HALLO WEO WE. Immer die Nummer mit der erwarteten vergleichen.
Trennzeichen in den Nutzdaten
Enthalten die Daten ein ;, liefert split(";") zu viele Teile. Abhilfe: split(";", 1) oder ein Längenfeld.
Kanal erst simulieren
Eine Klasse Kanal, die zufällig Rahmen verwirft, reicht zum Testen. Echte Netzwerk-Sockets kommen erst danach.
