[so] [Tema5] [LINUX] Transmitere fisiere static / dynamic

Adrian Stanciu adrian.stanciu.pub at gmail.com
Tue May 26 20:26:22 EEST 2015


2015-05-26 19:17 GMT+03:00 Georgiana Diana <geodiana93 at gmail.com>:
> 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 <so at cursuri.cs.pub.ro>:
>>
>> 2015-05-25 20:49 GMT+03:00 Madalina Hristache via so
>> <so at cursuri.cs.pub.ro>:
>> > 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.

> 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
* 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


More information about the so mailing list