This shows you the differences between two versions of the page.
pc:laboratoare:06 [2022/04/04 00:48] vlad_andrei.badoiu [Sockets] |
pc:laboratoare:06 [2022/04/13 15:06] (current) vlad_andrei.badoiu [Exercitii] |
||
---|---|---|---|
Line 106: | Line 106: | ||
- | In continuare, se vor prezenta principalele functii pentru manipularea socketilor, pe cele din figura de mai jos. | + | In continuare, se vor prezenta principalele functii pentru manipularea socketilor, |
- | {{:pc:laboratoare:sockets-udp.png?400|}} | ||
== Comunicare client-server UNIX == | == Comunicare client-server UNIX == | ||
Line 120: | Line 119: | ||
- //Inchide socket// prin //close()//. | - //Inchide socket// prin //close()//. | ||
- | {{:pc:laboratoare:apeluri.png?300|}} | + | {{:pc:laboratoare:apeluri.png?300|}} {{ :pc:laboratoare:sockets-udp.png?300|}} |
== socket() == | == socket() == | ||
Line 312: | Line 311: | ||
**[Task-ul 1]:** | **[Task-ul 1]:** | ||
- | Plecând de la scheletul de cod oferit, scrieți o pereche de programe (client și server) care să permită transferul unui fișier binar de la server la client. | + | Plecând de la scheletul de cod oferit, scrieți o pereche de programe (client și server) care să permită transferul unui fișier binar de la client la server. |
<note warning> | <note warning> | ||
Line 327: | Line 326: | ||
Specificații: | Specificații: | ||
- Clientul trimite un fisier binar prin UDP, iar serverul il va receptiona datele si le va scrie in fisierul lui. | - Clientul trimite un fisier binar prin UDP, iar serverul il va receptiona datele si le va scrie in fisierul lui. | ||
- | - Fișierul trimis de client se va numi **fisier.bin**, iar fișierul salvat de client se va numi **received_file.bin**. | + | - Fișierul trimis de client se va numi **fisier.bin**, iar fișierul salvat de server se va numi **received_file.bin**. |
- Clientul va transmite fișierul în calupuri de câte 1024 octeți. | - Clientul va transmite fișierul în calupuri de câte 1024 octeți. | ||
+ | |||
+ | La final, vom studia folosind **Wireshark** datagramele trimise de catre client. | ||
+ | |||
+ | Mai mult, daca sunteti in aceasi retea (e.g. pe acelasi WiFi) va puteti **grupa cate doi** pentru a trimite un fisier de la unu 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 un fisierul. Felicitari, ati facut o **aplicatie simpla de transfer de fisiere**. | ||
**[Task-ul 2]:** | **[Task-ul 2]:** | ||
Dacă ați rulat task-ul 1 cu ambele componente pe aceeași mașină, probabil totul a mers bine, însă o soluție naivă (care trimite datagrame doar de la sender la receiver), ascunde 2 probleme: | Dacă ați rulat task-ul 1 cu ambele componente pe aceeași mașină, probabil totul a mers bine, însă o soluție naivă (care trimite datagrame doar de la sender la receiver), ascunde 2 probleme: | ||
- | - Dacă transmițătorul este mai rapid decât receptorul, acesta din urma poate fi inundat și să nu reușească să le proceseze la timp; | + | - Dacă transmițătorul este mai rapid decât receptorul, acesta din urma poate fi inundat și să nu reușească să proceseze la timp datagramele; |
- Două situații foarte posibile în cazul comunicării către mașini diferite (**pierderea unei datagrame** sau **inversarea ordinii datagramelor**) sunt netratate. | - Două situații foarte posibile în cazul comunicării către mașini diferite (**pierderea unei datagrame** sau **inversarea ordinii datagramelor**) sunt netratate. | ||
Line 340: | Line 343: | ||
<note warning> | <note warning> | ||
- | Acest exercitiu va fi rulat doar pe mininet. Lansati-l doar folosind comanda: <code>sudo python3 topology.py</code> | + | Acest exercitiu va fi rulat doar pe mininet. Lansați-l doar folosind comanda: <code>sudo python3 topology.py</code> |
</note> | </note> | ||
Line 398: | Line 401: | ||
<note> | <note> | ||
Observatie: Cateodata, cand se incearca sa se reporneasca un _server_, bind() nu reuseste sa asigneze, iar eroarea este "Address already in use". Asta inseamna ca un socket care a fost conectat pe acel port inca mai este agatat si //utilizeaza portul//. In aceasta situatie, fie se poate astepta deconectarea portului respectiv, fie se specifica programatic reutilizarea portului cu [[https://linux.die.net/man/3/setsockopt|setsockopt()]] | Observatie: Cateodata, cand se incearca sa se reporneasca un _server_, bind() nu reuseste sa asigneze, iar eroarea este "Address already in use". Asta inseamna ca un socket care a fost conectat pe acel port inca mai este agatat si //utilizeaza portul//. In aceasta situatie, fie se poate astepta deconectarea portului respectiv, fie se specifica programatic reutilizarea portului cu [[https://linux.die.net/man/3/setsockopt|setsockopt()]] | ||
+ | |||
+ | <code C> | ||
+ | int enable = 1; | ||
+ | if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) < 0) | ||
+ | perror("setsockopt(SO_REUSEADDR) failed"); | ||
+ | </code> | ||
+ | |||
+ | </note> | ||
+ | |||
+ | <note> | ||
+ | O posibila solutie a laboratorului se gaseste [[https://ocw.cs.pub.ro/courses/_media/pc/laboratoare/lab06-rezolvare.zip|aici]] | ||
</note> | </note> |