Teme:Server fisiere

Termen de predare: Joi, 4 iunie 2009, ora 23:59 (2009-06-04)

Enunț
Să se implementeze un server de fișiere ce va folosi portul TCP 8192 pentru a răspunde la cereri din rețea. Serverul trebuie să ofere următoarele funcții clienților: listarea fișierelor dintr-un director, citirea dintr-un fișier, scrierea într-un fișier.

Toate operațiile se vor face asincron folosind mecanismele cele mai scalabile oferite de fiecare sistem de operare.

Se va implementa de asemenea și un client, cu următoarea comportare:

Acțiune: citirea, respectiv scrierea în fișierul fisier len octeți începând de la poziția offset. Datele se vor citi de la STDIN și se vor scrie la STDOUT. Acțiune: listarea fișierelor din directorul director la STDOUT. Pentru a ușura testarea, am ales să impunem un format simplu pentru listing: un fişier/director pe fiecare linie precedat de mărimea lui. Directoarele vor fi urmate de caracterul '/'. Mărimea directoarelor este cea întoarsă de ls (0 pe Windows, un multiplu de block size pe Linux).
 * Sintaxa:
 * şi

Precizări generale
Ordinea parametrilor trebuie respectată, întrucât testele fac anumite presupuneri asupra lor.

Serverul trebuie să asculte eventualele cereri pe adresa 127.0.0.1

Clientul va afișa la stdout numai ceea ce primește de la server.

În cazul în care apar erori la server, acestea vor fi trimise clientului care va ieși cu un cod de ieșire != 0.

De asemenea, dacă clientul primește parametri necorespunzători, trebuie sa iasă cu cod de ieșire != 0.

FIXME: Pentru a evita un race în testare, este nevoie sa aşteptaţi în client terminarea operaţiei de scriere în server înainte de a ieşi. Altfel, s-ar putea ca testul să compare fişierul output cu cel corect înainte să termine serverul de scris.

Exemple de funcţionare client:

Testare
Pentru simplificarea procesului de corectare a temelor, dar şi pentru a reduce greşelile temelor trimise, corectarea temelor se va face automat cu ajutorul unor teste publice. (linux, windows).

Formatul afişării, aşa cum a fost descris mai sus, este obligatoriu.

În urma compilării temei trebuie să rezulte două executabile: server</tt> (respectiv server.exe</tt> pentru Windows) şi client</tt> (respectiv client.exe</tt> pentru Windows). Numele acestor executabile trebuie să fie respectat.

Se vor acorda 0.4p pentru fiecare test. Nota rezultată poate fi modificată prin depunctări suplimentare:


 * -0.1 pentru README necorespunzator
 * -0.1 pentru surse prost comentate
 * -0.2 pentru ilizibilitatea codului
 * -0.2 neverificarea conditiilor de eroare/memory leak-uri/etc
 * -0.4 implementare incorectă(protocol incorect, race-uri, potenţiale erori de memorie)

Precizări Windows
Se vor folosi funcţii asincrone de citire/scriere pe sockeţi/fişiere împreună cu mecanismul de completion ports pentru primirea notificarilor. Pool-ul de threaduri va fi egal cu numarul de procesoare din sistem. Numărul de procesoare se află cu ajutorul funcţiei GetSystemInfo. Pentru listarea conţinutului unui director se pot folosi funcţiile FindFirstFile/FindNextFile.

Tema se va rezolva folosind doar funcţii Win32. Se pot folosi de asemenea şi funcţiile de formatare printf, scanf</tt>, funcţiile de alocare de memorie  malloc, free</tt> si funcţiile de manipulare a şirurilor de caractere (strcat</tt>, strdup</tt>, etc.)

Pentru partea de I/O şi procese se vor folosi doar funcţii Win32. De exemplu, funcţiile open</tt>, read</tt>, write</tt>, close</tt> nu trebuie folosite, în locul acestor trebuind să folosiţi CreateFile</tt>, ReadFile</tt>, WriteFile</tt>, CloseHandle</tt>.

Precizari Linux
Pe Linux, se va aştepta unificat încheierea unei operaţii asincrone şi trimiterea/recepţionarea datelor pe sockeţi. Serverul va multiplexa clienţii într-un singur thread folosind epoll şi se va folosi de KAIO pentru citire/scriere din fişiere. Notificarea terminării operaţiilor asincrone se va face folosind eventfd. Pentru listarea continutului unui director se pot folosi funcţiile din dirent.h, opendir/readdir. Pentru aflarea marimii unui director se poate folosi funcţia stat. Tema se va rezolva folosind doar functii POSIX. Se pot folosi de asemenea şi funcţiile de formatare <tt>printf, scanf</tt>, funcţiile de alocare de memorie <tt> malloc, free</tt> şi funcţiile de manipulare a şirurilor de caractere (<tt>strcat</tt>, <tt>strdup</tt>, etc.)

Pentru partea de I/O si procese se vor folosi doar funcţii POSIX. De exemplu, funcţiile <tt>fopen</tt>, <tt>fread</tt>, <tt>fwrite</tt>, <tt>fclose</tt> nu trebuie folosite, în locul acestora trebuind să folosiţi <tt>open</tt>, <tt>read</tt>, <tt>write</tt>, <tt>close</tt>.

FAQ

 * Q: In server, toate operatiile se vor face asincron folosind mecanismele cele mai scalabile oferite de fiecare sistem de operare. Asta inseamna si socketi nonblocanti sau se refera doar la partea de IO?
 * A: Da, folositi socketi neblocanti. Cu socketii blocanti exista riscul blocarii in anumite operatii, cum ar fi write daca bufferul asociat socketului este plin.


 * Q: În cazul în care clientul dă o comanda wr/rd trebuie să trimită/citescă date pe/de pe socket. Trebuie să le trimită/citească cu io asincron?
 * A: Pe partea de client nu are nici un sens să folosiţi altceva decat read/write blocant.


 * Q: Ce se intampla atunci cand se incearca scrierea intr-un fisier care nu exista. Se creeaza fisierul sau se intoarce eroare la client?
 * A: Se crează.

Întrebări
Pentru lamuriri suplimentare asupra temei consultati arhivele listei de discutii sau dati un [mailto:so@cursuri.cs.pub.ro mail] (trebuie sa fiti inregistrati ).