De citit înainte de laborator:
Lectură opțională:
Materiale video opționale:
Laboratoarele de PCom presupun cunoștințe de USO și PC. În cadrul laboratoarelor vom implementa și utiliza protocoalele de comunicație(set de reguli bine definite pe care interlocutorii le urmeaza) discutate la curs. Vom vedea cum funcționează internetul și înțelege cum sunt dezvoltate aplicațiile peste acesta.
Înaintea oricărui laborator va trebui citită lectură recomandată, în cazul de față video-ul Sending digital information over a wire (4 minute) si capitolul The reference models din carte. Prima parte a laboratorului este de tip tutorial și se recomandă trecerea rapidă prin textul laboratorului. În a doua parte a laboratorului se găsesc exerciții. Exercițiile pot fi rezolvate atât în C cât și C++, cu toate aceste recomandăm implementări în versiuni moderne de C++. Recomandăm Visual Studio Code cu extensia de C/C++ pentru laboratoare și teme. Atât temele cât și laboratoarele se vor face pe Linux.
Complexitatea internetului a crescut rapid, dacă la începutul anilor 1970 internetul se rezuma la comunicarea peste un cablu între două dispozitive printr-un protocol simplu, în doar câțiva ani complexitatea a crescut enorm. In figura de mai jos vedem precursorul internetului de astăzi, ARPANET.
Vom vedea cum plecând de la ceva foarte simplu, precum trimiterea unui bit(0 sau 1) folosind un semnal electric care poate lua doar două valori 0V sau 5V, ajungem la a trimite mesaje în partea cealaltă a globului și interconectarea a zeci de miliarde de dispozitive.
Pentru a modela cât mai ușor arhitectură internetului, cercetătorii de la acel timp au propus diferite modele de referință, dintre acestea Open Systems Interconnection (OSI), modelul propus de Huber Zimmemann, a fost cel mai influent. Totuși, în practică, modelul dominant de referință folosit este TCP/IP. În figura de mai jos putem vedea cele două modele de referință și o serie de protocoale la fiecare nivel. La laborator vom avea o abordare bottom-up. Vom porni de la protocoale simple pentru a conecta două calculatoare și vom ajunge la a implementa protocoale de nivel aplicație, precum HTTP, folosit astăzi mai ales de web browsers. Pentru o buna dezvoltare a protocoalelor, acestea sunt descrise in documente numite Request for Comment (RFC), de exemplu RFC 791 descrie protocolul IP.
În cadrul laboratorului de Protocoale vom folosi sisteme de operare bazate pe Linux. În continuare vom reaminti câteva cunoștințe utile pentru următoarele laboratoare și pentru teme.
Următorul video prezintă funcționalitatea acestor comenzi în linia de comanda
1. În orice browser accesați website-ul http://example.com/
2. Vom realiza același lucru de mână:
telnet example.com http
. Această comandă deschide o conexiune (flux de bytes) către un alt calculator (numit example.com) care rulează un serviciu http, protocolul Hyper-Text Transfer Protocol folosit de World Wide Web. Dacă totul a mers corect, veți vedea următoarele:GET / HTTP/1.1
- Path-ul către resursa pe care vrem să o accesămHost: example.com
- Specifică host-ul, partea după httpConnection: close
- Specifică serverului că nu vom mai trimite cereri după această.Am văzut că telnet poate acționa ca un client care se conectează la un server. Vom vedea acuma cum este să fim un server.
netcat -v -l -p 9090
pentru a porni un simplu server ce ascultă pe portul 9090telnet localhost 9090
pentru a ne conecta local, pe calculator, la serverul care rulează pe portul 9090Connection from localhost 53500 received!
Va recomandăm următorul crash course de C pentru a vă reaminti concepte precum structuri, pointeri si alocarea de memorie.
Sistemul de operare Unix/Linux dispune de un compilator pentru compilarea fișierelor scrise în C, numit gcc. Pentru
C++ vom folosi g++
.
Să presupunem că avem un fișier sursă numit hello.c. Compilarea standard a acestui fișier este
gcc hello.c
Ca rezultat se obține un fișier a.out care se poate execută. Dacă însă compilăm folosind
gcc hello.c -o hello
se va obține fișierul executabil hello.
-fsanitize=address
. Mai mult, pentru a evita undefined behavior vom folosi -fsanitize=undefined
. Aceste opțiuni sunt utile pentru a ne asigura că programul scris de noi nu are bug-uri ascunse.
Cum networking-ul, în general, necesită programare low level, va trebui să știm cum să folosim un debugger pentru a depăna probleme într-un mod rapid. Va recomandăm articolul Debugging pentru a va reaminti de cum folosim GDB atât din CLI cât și prin intermediul unui IDE.
Vom folosi următoarele funcții pentru a interacționa cu fișierele pe Linux: open, close, read, write și lseek. API-ul lor este descris în manual man read.2
. Acestea lucrează cu ceea ce numim file descriptors (fd). Simplist, un file descriptor este un integer ce reprezintă un identificator în tabela de fișiere a unui program. De exemplu, dacă creăm deschidem un fișier, identificatorul ar putea fi numărul 4.
Avem un exemplu de folosire a funcțiilor de acces la fișiere în programul de mai jos, care copiază fișierul ”sursă” în fișierul ”destinație”. Urmăriți comentările pentru a înțelege mai bine funcționalitatea.
Packet
in format binar. Realizați un program în C/C++ care să citească array-ul cu elemente de tip Packet
din acest fișier și să afișeze conținutul din payload al fiecărei intrări.struct Packet { char payload[100]; int sum; int size; };
telnet
pentru a ne conecta la următorul server TCP: towel.blinkenlights.nl
. Acest server trimite un șir de biți către noi, iar telnet îl afișează pe ecran (stdout
). Mai multe astfel de exemple le găsiți aicicat
în C/C++. Acesta trebuie să afișeze conținutul unui fișier, linie cu linie la stdout
.