Exercitii
Scheletul de laborator
Scheletul laboratorului se regaseste la adresa de aici. Funcționalitatea disponibilă este descrisă în README.md. În continuare, vom folosi Mininet pentru a simula o topologie simplă:
sudo python3 topo.py.
Antetul protocolului pe care îl dezvoltăm astăzi este descris mai jos. Protocolul îl vom implementa peste UDP.
|Seq Number|Length|
Exercițiul 1 - Protocolul start-stop
1. Vom dezvolta un protocol simplu de retransmisie, ce reprezintă o extindere a protocolului Start-Stop implementat în laboratorul 5, pentru a avea în vedere segmentele (și ACK-urile) ce se pot pierde.
Pentru fiecare segment, dacă primim ACK trimitem segmentul următor (cu secventa seq + 1), iar în cazul în care nu primim ACK (într-un interval de timp ales pentru timeout) vom retrasmite segmentul curent.
Numărul de secvență va fi folosit de către receiver pentru a identifica transmisiile duplicate realizate pentru segmente care s-au trimis corect, dar pentru care ACK-ul s-a pierdut creând senderului iluzia unui pachet pierdut.
În cele mai multe implementări, dacă primește un segment duplicat receiverul retrimite ACK-ul pentru pachetul anterior (lucru care nu este absolut necesar putând și să se aștepte ca senderul să dea timeout în așteptarea ACK-ului). În acest caz, senderul trebuie să verifice și că ACK-ul primit este pentru pachetul abia trimis, în caz contrar făcându-se tot repetarea trasmiterii mesajului.
Observație
Vom folosi o opțiune specială pe socket pentru a seta un timeout pentru operația de receive. Astfel, dacă recv nu primește date într-un anumit timp, o să expire timer-ul și vom putea trata acest caz.
struct timeval timeout;
timeout.tv_sec = 1;
timeout.tv_usec = 0;
if (setsockopt (sockfd, SOL_SOCKET, SO_RCVTIMEO, &timeout,
sizeof timeout) < 0
error("setsockopt failed\n");
Ulterior, pentru a face un recvfrom și a diferenția timeout de alte excepții ce pot apărea, putem apela la un cod similar celui de mai jos:
int ack;
rc = recvfrom(sockfd, &ack, sizeof(ack), 0, NULL, NULL);
if(rc < 0) {
if(errno == EWOULDBLOCK || errno == EAGAIN) {
// TODO: Trateaza caz de timeout la asteptarea unui ACK
} else {
// Eroare generala, diferita de timeout
DIE(rc < 0, "recv-ack");
}
} else {
// TODO: Trateaza primirea unui ACK (sau a unei datagrame UDP, in general)
}
Exercițiul 2 - Go-Back-N ARQ
2. Vom extinde implementarea precedentă de protocol pentru a folosi tehnică de fereastră glisantă. Vom implementa Go-Back-N. Vom calcula dimensiunea ferestrei de transmisie în funcție de lățimea de bandă și latență.
Exercițiul 3/Bonus - Verificarea funcționării pe computere diferite, fără Mininet
3. Ne vom conecta toți în aceași rețea (e.g. pe acelasi WiFi) pentru
a trimite fișiere către alți colegi din sala. Nu vom mai rula peste Mininet.
Ne vom grupa câte doi pentru a trimite un fișier de la unul la celalalt.
Mai exact, unul dintre voi va porni un server cu bind pe INADDR_ANY
(0.0.0.0), iar clientul va putea trimite catre ip-ul celuilalt fisierul.
Note
Dacă folosiți mașini virtuale și nu aveți rețeaua pe modul Bridge, va
trebui să faceți port forwarding din setarile hypervisorului. Pentru
a verifica dacă sunteți în aceeasi retea, folositi ip address show și confirmați că adresa este din același subnet cu cel al gazdei.