Zur Übertragung von Dateien werden zwei Transportprotokolle verwendet: TCP und UDP. UDP ist ein unzuverlässiges Protokoll, während TCP Zuverlässigkeit, Flusskontrolle und Überlastungskontrolle bietet, aber über eine explizite Verbindungsaufbauphase verfügt, die für manche Anwendungen möglicherweise nicht wünschenswert ist. Das Ziel dieses Projekts besteht darin, eine Dateiübertragungsanwendung zu entwerfen und zu implementieren, die alle guten Funktionen von TCP ohne die Phase des Verbindungsaufbaus bietet.
Der UDP-Server und -Client verwendet das folgende Header-Format:
Der Server empfängt eine Dateianforderung vom Client. Es extrahiert den Dateinamen aus der Anfrage und ruft den Inhalt der Datei in einem Puffer ab. Anschließend segmentiert es die Datei in Blöcke mit einer Größe von 1450 Byte, wie vom Header unterstützt.
Es sind zwei Fenstergrößen zu berücksichtigen:
Der Server beginnt mit dem Senden von Dateisegmenten bis zur Mindestgröße des Überlastungsfensters und der angekündigten Fenstergröße. Nachdem alle Segmente in einem Fenster gesendet wurden, wartet es auf den Empfang einer Bestätigung. Wenn eine Bestätigung für eine Sequenznummer empfangen wird, die kleiner als die nächste zu sendende Sequenznummer ist, bedeutet dies, dass ein vorheriges Segment nicht korrekt empfangen wurde und der Server die drei doppelten Bestätigungen vom Client akzeptiert. Anschließend wird die nächste Sequenznummer basierend auf der empfangenen Bestätigung festgelegt. Nach Erhalt der kumulativen Bestätigung wird im nächsten Fenster mit dem Senden der Segmente fortgefahren. Wenn doppelte Bestätigungen empfangen werden, beginnt der Server mit dem Senden von Segmenten aus dem Paket, das nicht korrekt empfangen wurde.
Implementierung des Jacobson/Karel-Algorithmus zur Schätzung der Roundtrip-Zeit (RTT) für die vom Client zu empfangenden Pakete und die vom Server empfangene Bestätigung. Wenn der Server innerhalb von RTT keine Bestätigung erhält, überträgt er diese Pakete erneut.
Pseudocode:
Estimated_RTT = (1-α) Estimated RTT + (α) Sample_RTT
In the original TCP Specification, α=.0125
Jacobson/Karels included a variation component to the calculation for the Estimated_RTT
Estimated_RTT = Estimated_RTT + δ (Sample_RTT-Estimated_RTT)
Deviation = Deviation + δ (|Sample_RTT- Estimated_RTT|- Deviation)
Timeout = μ * Estimated_RTT + φ * Deviation
Typically φ=4, μ = 1, δ is between 0 and 1
Der Server beginnt mit dem Senden eines Segments. Dann folgen zwei Phasen der Staukontrolle:
Langsamer Start: Die Segmentgröße wird exponentiell erhöht, bis sie vom Empfänger innerhalb des Timeouts korrekt bestätigt wird und die Größe des Überlastungsfensters kleiner als der ssthresh ist, der auf 64.000 Bytes eingestellt ist.
Überlastungsvermeidung: Wenn die Größe des Überlastungsfensters größer oder gleich ssthresh wird, wird die Größe des Überlastungsfensters linear um 1 Segmentgröße erhöht.
Timeout: Wird mit dem oben angegebenen Jacobson/Karel-Algorithmus berechnet. Wenn eine Zeitüberschreitung auftritt, wird ssthresh auf die Hälfte des Werts des Überlastungsfensters gesetzt und das Überlastungsfenster wird auf die Größe eines Segments zurückgesetzt.
vagrant up
Dadurch werden sowohl der Server als auch die Client-Rechner gestartet
vagrant ssh reliableUDPServer
vagrant ssh reliableUDPClient
make
./Server port advertised_window
Der Server akzeptiert die folgenden Befehlszeilenargumente:
Port: Portnummer, die für die Kommunikation verwendet werden soll
beworbenes_Fenster: Die Anzahl der Bytes, die der Server senden darf, bevor er auf eine Bestätigung wartet
./Client server_host_name port file_name advertised_window
Der Client akzeptiert die folgenden Befehlszeilenargumente:
Port und Advertised_Window: identisch mit denen des Servers
server_host_name: Hostname des Servers
Dateiname: der Name der vom Client angeforderten Datei
Sobald der Code erfolgreich ausgeführt wurde, finden Sie die vom Client angeforderte Datei im Ordner ReliableUDPClient.
Computernetzwerk-Top-Down-Ansatz