2015-05-26 20:31 GMT+03:00 Adrian Stanciu <[email protected]>:
> 2015-05-26 20:26 GMT+03:00 Adrian Stanciu <[email protected]>: > > 2015-05-26 19:17 GMT+03:00 Georgiana Diana <[email protected]>: > >> Buna, > >> Eu tot am niste nelamuriri legate de citirea asincrona / trimiterea cu > send > >> (inline): > >> > > > > Bună, Georgiana! > > > >> 2015-05-25 20:53 GMT+03:00 Adrian Stanciu via so <[email protected] > >: > >>> > >>> 2015-05-25 20:49 GMT+03:00 Madalina Hristache via so > >>> <[email protected]>: > >>> > Salut, > >>> > >>> Bună, Mădălina! > >>> > >>> > > >>> > Am câteva nelămuriri și am nevoie de clarificarea lor ca să pot > continua > >>> > tema. > >>> > > >>> > 1. Când transmitem un fișier din directorul static, trimitem > header-ul > >>> > HTTP > >>> > cu send (non-blocant, asincron), apoi fișierul cu sendfile. Fără > nicio > >>> > legătură cu libaio.h, da? > >>> > >>> Da, așa este. > >>> > >>> > > >>> > 2. Când transmitem un fișier din directorul dynamic, îl citim de pe > disc > >>> > cu > >>> > apeluri legate de libaio.h, apoi îl punem pe socket. Și cum îl > trimitem? > >>> > Cu > >>> > send? Sendfile? La partea asta sunt în ceață. > >>> > > >>> > >>> Cu send(). > >> > >> > >> In exemplul din laborator [1], precum si in exemplul sugerat in tema [2] > >> (xmailserver), am observat ca se face read pe un file descriptor, > pentru a > >> notifica serverul atunci cand operatia asincrona de citire s-a terminat. > >> > >> 1) Este acest read blocant, sau nu ? > > > > Acel read() pe eventfd este blocant, dar nu se va bloca dacă îl apelâm > > atunci când primim o notificare de la kernel, prin intermediul epoll. > > > >> 2) Care ar trebui sa fie workflow-ul server-ului in cazul trimiterii > unui > >> fisier dinamic ? Ma gandeam ca unul posibil este acesta, dar inca nu > imi dau > >> seama daca este corect: > >> > >> initializare io_context (in main, inainte de logica serverului); > > > > Este mai ușor dacă folosești un context IO per conexiune. > Atunci cred ca ar trebui modificat enuntul, care spune: "Recomandăm folosirea unei variabile globale de tipul io_context_t și a unui descriptor eventfd pentru fiecare conexiune." In rest, mersi mult pentru raspuns ! > > > >> in server, primirea unui request de citire fisier dinamic; > >> trimiterea catre client a unui raspuns: 200/404, in functie de caz, prin > >> send-uri repetate (metoda comuna, atat pentru fisier static, cat si > pentru > >> dinamic); > >> dupa trimiterea header-ului, in cazul unui fisier dinamic, serverul > seteaza > >> un eventfd si submite un request de read pentru contextul aio -- actiune > >> neblocanta; > >> serverul face read pe eventfd-ul anterior -- actiune blocanta ?; > > > > Practic neblocantă dacă citirea se face la semnalizarea pe eventfd din > > partea epoll. > > > >> in urma notificarii de terminare a citirii din fisier a unui buffer in > >> general mai mic decat dimensiunea fisierului, serverul face apeluri send > >> repetate, pentru a trimite buffer-ul proaspat citit; -- in timpul > acesta, se > >> presupune ca serverul initiaza o noua cerere de citire asincrona, sau > >> asteapta trimiterea buffer-ului curent ? ; > > > > E mai ușor dacă nu faci aceste operații simultan; e mai eficient dar > > ar trebui să tratezi în același timp mai multe tipuri de evenimente > > (read din fișier, send pe socket), care ar fi starea conexiunii? iar > > complexitatea implementării ar fi mai mare. > > > >> serverul continua sa citeasca bucati de fisier si sa le trimita catre > >> client. > >> > >> 3) Este corect ca in functia de trimitere fisier, pentru cazul unui > fisier > >> dinamic, si care se tot apeleaza in bucla principala a server-ului > (pentru > >> ca epoll este setat pe out, cat timp trimit un fisier), sa verific si sa > >> schimb starea conexiunilor (de ex, cat timp trimit fisierul, starea sa > fie > >> SENDING_DATA, apoi, cand citirea asincrona se termina, pur si simplu sa > >> schimb starea in DATA_SENT si sa inchid conexiunea) ? > > > > Poți să: > > * activezi EPOLLIN pe eventfd pentru a aștepta finalizarea citirii > > asincrone a unei bucăți din fișier > > * planifici citirea asincronă a unei bucăți din fișier > > * activezi EPOLLOUT pe socket > > Nu am spus complet aici ... activarea EPOLLOUT pe socket se face când > citirea asincronă a fost încheiată. Atunci avem date de trimis. > > > * când ești notificată de epoll că poți să trimiți pe socket, trimiți > > bucata de fișier > > * dacă nu s-a trimis întreaga bucată mai aștepți un nou eveniment de > > EPOLLOUT pe socket din partea epoll și apoi trimiți ce ți-a mai rămas > > și tot așa > > * când ai terminat de trimis acea bucată, dezactivezi EPOLLOUT pe > > socket (căci deocamdată nu mai ai ce trimite) > > * o iei de la capât pentru a citi următoarea bucată din fișier > > * când ai trimis întreg fișierul se poate închide conexiunea > > > > > Adrian > -- *Georgiana Diana Ciocirdel* Polytechnic University of Bucharest, Computer Science
_______________________________________________ http://ocw.cs.pub.ro/courses/so/info/lista-discutii
