SPEAKER: Acum să se arunca cu capul în codul de distribuție
și să ia o privire la contextul în care codul pe care îl scrie
va fi de operare.
La sfârșitul zilei, ai de gând să pună în aplicare
totalitatea serverul de web.
Dar ne-am asigurat tu cu scheletul
cod care au putea funcționa, în special legate de rețea.
Să aruncăm o privire.
>> Deci, aici spre partea de sus a dosarului este un buchet
de facilitate de testare cerințelor macro.
Acum, aceasta este doar o trăsătură de c, prin care în conformitate cu o grămadă de pagini man
trebuie să definiți unele din aceste constante să fie adevărat
sau să fie chiar anumite numere, astfel încât aveți acces la anumite funcții.
În caz contrar, acestea vor fi nedeclarate și nu veți avea acces.
Așa că am făcut acest lucru prin fel de a citi paginile de manual.
Acum jos, în Liniile 15 și 17, noi
au o grămadă de limite declarate.
>> Și am împrumutat acestea la un server web popular numit Apache.
Și acestea sunt doar Numerele care vor
să limiteze numărul total de bytes care sunt permise
în diverse contexte pentru cererea HTTP că un browser este permis să-mi trimită.
Mai departe, vom defini octeti.
Acum, un octet este doar un mod de lux de a spune un octet, sau opt biți.
Se pare că într-odinioară un octet Nu a fost necesar opt biți,
așa octet este întotdeauna opt biți.
Deci, în acest caz, am adoptat ceea ce este comun în rețea
lume de asteptare opt octeti un octet.
>> Aici am precizat că octeti va fie 512, astfel încât de mult ca în criminalistica
când am citit o grămadă de bytes la un moment dat, aici,
vom citi o buchet de octeti la un moment dat.
Mai departe o grămadă de fișiere antet.
Cum știu să includă astea?
Ei bine, am citit pur și simplu omul pagini pentru un număr de funcții
că vom folosi în această distribuție cod și să includă în cele
Am fost instruit să.
>> Și acum avem un tip de date.
Am declarat un octet a fi un char.
Și vom vedea mai târziu că este utilizate în întreaga codul.
Și am declarat un grămadă de prototipuri,
și vom plimba rapid prin fiecare dintre aceste funcții.
În cele din urmă, și, probabil, cel mai important să se țină
minte în acest moment în povestea, este că nu există
sunt, de fapt, un întreg grămadă de variabile globale
în partea de sus a fișierului, rădăcină, CFD, SFD, cerere, fișier și corp.
>> Acum, în general, folosind atât de multe la nivel mondial variabile, sau variabile globale la toate,
nu este practica spate.
Dar se pare că suntem, de asemenea, cu ajutorul unui Manipularea semnal tehnica numita mai târziu
în codul, ceea ce ne permite să detecta atunci când utilizatorul hit-uri ceva
ca CTRL C și închide serverul grațios.
Și pentru a face asta cu grație și de fapt a elibera memorie,
trebuie să avem acces la aceste variabile globale.
>> Și acum să aruncăm o privire la principal, care conduce ansamblul acestui program.
În primul rând, în partea de sus de aici noi au un număr variabil de eroare
care pare a nu au un tip, dar asta e
pentru că este de fapt definite într-un fișier numit
Eroare errno.h care este inclus în sus mai mare.
Dacă veți face om errno la efectiv a se vedea definiția de acest lucru,
veți vedea că aceasta este o Global variabilă special, care
este stabilit de o grămadă funcțiilor nu scrise
de noi, ci de autorii Linux și alte sisteme pentru a stabili efectiv
un număr de care variabil, atunci când ceva nu merge bine, astfel încât să puteți la nivel global
dau seama ce a făcut merge prost.
>> Acum mai jos veți vedea o nouă Tehnica probabil folosind getopt,
o funcție care ajută comanda analizare argumente în linia de astfel încât să nu
Trebuie să deranjeze timp pierdem imaginind cum pentru a analiza ceva de genul 8080,
sau cratimă p, sau liniuță h pentru a obține ajutor.
getopt face, în esență, că pentru noi.
Consultați pagina de manual pentru mai multe.
>> Mai departe, vom face un pic de eroare de verificare pentru a vă asigura
că numărul de port este în intervalul specificat în spec.
Mai departe, vom vedea o chemare la funcția începe, a cărui definiție vom
uita-te la într-un moment, și ca numele său sugerează, aceasta începe serverul de web.
Aici avem un apel la o funcție numit semnal care spune,
dacă și atunci când auzi de control C de la tastatură utilizatorului, mergeți mai departe și de apel
un handler funcție numită ce se intampla lucruri pentru a curăța în cele din urmă în sus și opri
serverul.
>> Mai jos, care este ceea ce pare a fi o buclă infinită, din care prima linie
eficient este un apel la o funcție numită
reseta, care ne-am punerea în aplicare a mai târziu, în ordine
pentru a elibera o parte din statele noastre globale.
După aceea este o linie de cod care condiționat
verifică revenirea Valoarea de conectat.
Arata acum conectate, cum ar fi un predicat, ceva care returnează adevărat sau fals.
Și o face, dar nu e ceva special în conectat
prin aceea că este un apel de blocare.
Acesta va sta acolo și să aștepte până la browser-ul unui utilizator
încearcă să se conecteze la acest web serverul și numai atunci va
întoarce adevărat sau fals, astfel încât să continuăm în interiorul acestui if.
>> Odată ajunși acolo, observa această funcție într-o funcție numită parse, pe care am scris,
care analizează toate octeti, toate de bytes care provin dintr-un browser
la server, astfel încât să putem preda te-ai întors în cele din urmă o valoare de un
de aceste variabile globale care stochează toate de octeți în doar
anteturile de care cerere, nu corpul
dacă ar exista de fapt un corp de ea.
>> Acum mai jos vom începe să analiza aceste antete pentru a extrage
un subset al informațiilor că ne pasă.
Mai exact, pe caietul de sarcini, noi mai întâi
a vrut să solicite linie, care este doar că prima linie care
sperăm spune ceva de genul get slash sau unele cale și apoi HTTP 1.1.
Suntem folosind acest metaforă de un ac in carul cu fan
să caute special caractere sau adrese.
Și într-adevăr, există un număr de funcții în codul nostru de distributie
pe care le, de asemenea, s-ar putea găsi de ajutor atunci când caută pentru valorile particulare.
>> În cele din urmă, am copia aceste bytes într-o linie variabilă numită,
care observa, de asemenea, ne-am alocate pe stivă
prin intermediul unei matrice de dimensiuni dinamic.
Și suntem în mod deliberat încearcă pentru a evita apelarea malloc
deoarece din nou, deoarece de control C fiind
o caracteristică potențial a acestui program, ne-am nu doresc să aibă acest cod brusc
întreruptă de lovirea utilizator Controlul C, al cărei rezultat
este că s-ar putea să nu aibă o șansă pentru ceva gratuit am malloced.
Așa că am încercat să folosească cât mai mult stivei este pot aici.
>> Următorul, o grămadă de la dos.
Caietul de sarcini va expune pe exact ceea ce se așteaptă aici,
dar comentariile pe care le dau un indiciu a ceea ce se află în fața.
Mai întâi trebuie să valida linia cerere
și asigurați-vă că se pare că caietul de sarcini gramatica, ca să spunem așa,
spune că ar trebui.
Apoi nevoie pentru a extrage ceva numit interogare, chestii afară
după un semn de întrebare, cum ar fi am văzut cu exemplul nostru Google
în treacăt într-un parametru HD.
Apoi înlănțui împreună rădăcina serverului web
cu calea pe care se află într- această cerere primul rând
și formează calea completă a fișierul vrem să căutăm.
>> După aceea, vom să ne asigurăm că fișierul există și este lizibil.
Și apoi vom extrage sale extensie de fișier, .html sau .php,
sau o astfel de prelungire care, la foarte capăt șirului solicitate.
Următorul este un întreg grămadă de cod am scris
pentru a genera fapt PHP generat de conținut pentru tine.
Într-un cuvânt, aceasta cod are în numele
din fișierul pe care doriți PHP să interpreteze.
Am trece prin ceva numit o țeavă în interpret PHP.
Du-te înapoi răspunsul ca și cum răspunsul a fost un fișier în sine.
Și apoi ne repeta peste care fișier bytes, trăgând-le pe toate într-un singur tampon
astfel încât să putem în cele din urmă printeaza-le.
>> Într-adevăr, toate acestea solicită aici pentru a dprintf
ne permite să imprimați ceva numit un descriptor de fisier, care
este doar un număr întreg care reprezintă un fișier.
Foarte asemănător în spirit, dar fundamental diferit de la un fișier
pointer stele.
Observați modul în care puteți utiliza sintaxă ca printf aici așa că pot dinamic
introduce ceva de genul lungimea pentru valoarea afara HTTP
numit Content-Length.
Și în cele din urmă am folosit Funcția dreptul de a scrie de fapt
corpul cererii.
>> Din păcate, ne-am pus în aplicare doar sprijin pentru dinamic
fișierele PHP generate.
Nu am în aplicare de sprijin pentru Fișierele statice, cum ar fi gif-uri, și JPEG,
și CSS și HTML fișiere.
Asta, din păcate, este lăsată la tine a răspunde scopului client
asta face.
Deci, acolo veți găsi că există nu de mult inspirație în acest bloc,
dar dacă un pic mai mare de până la modul în care ne-am dus despre interpretarea cod PHP,
funcțiile veți utiliza sunt un pic diferit.
>> De fapt, puteți împrumuta parte din funcționalitatea
probabil de la criminalistica set problemă, pentru că
la sfârșitul zilei tot ce ai nevoie pentru a face aici este din ce stiti ce fișier deschis
și odată ce știi că e așa-numitele Tip MIME sau tip de conținut,
aveți nevoie pentru a citi în aceste octeți și într-un fel le scuipe înapoi.
>> Și acum un tur al acestui alte funcții fișierului.
Până în primul rând este conectat, care pur și simplu returneaza true
când se aude în cele din urmă o conexiune de la un utilizator.
Următorul este eroare.
Eroare, între timp, așa cum o vom funcție a scris să se ocupe de toate de diferite 400
și statutul 500 HTTP coduri care v-ar dori
pentru a trimite înapoi la utilizator, împreună cu un mesaj standard.
>> Următorul este de sarcină, un deosebit de Funcția miez, al cărui scop în viață
este de a citi dintr-un fișier stea Pointer conținutul unui fișier într-un tampon global
că noi declarat la nivel global de mai sus [? principal. ?]
Acesta este un complex pic pentru că noi Trebuie să citiți octeți din fișierul
dar verifica pe fiecare iterație dacă ne-am deja
lovit la sfârșitul fișierului sau altceva a mers prost.
Și vom folosi realloc pentru a vă asigura că indiferent de tampon folosim este în creștere
și în creștere și în creștere și mereu stau in partea din numărul de octeți
că avem nevoie pentru a se potrivi acolo.
Handler, între timp, este funcția care devine
numit prin cale de a avea înregistrată control C ca un semnal
pe care dorim să intercepteze.
Observați aici în handler că în cele din urmă
solicită opri, care, desigur, oprește serverul de web.
Și, din păcate, căutare nu este pusă în aplicare.
În spirit, aceasta este o Funcția destul de simplu.
Având în vedere o extensie de fișier, are nevoie de pentru a reveni se așa-numitele MIME
tip sau tip de conținut.
Și am să precizeze în caietul de sarcini ceea ce trebuie să fie cea de cartografiere.
Dar trebuie să traduce se în cele din urmă cu codul C.
>> Următorul este funcția noastră la fel de miez numit parse, al cărui scop în viață
este de a citi, nu dintr-un fișier, ci de la o conexiune la rețea.
Mai exact, citind și parsarea Cerere HTTP care a venit dintr-un browser
la server, astfel încât în cele din urmă, putem analiza
la doar antetele din cererea de line și să se întoarcă pe cei la tine
prin intermediul unui tampon globală care am declarat mai sus [? principal. ?]
>> Reset, între timp, este o funcție care definim
că este chemat iterativ interior de principal de fiecare dată când ești pe cale
gata să înceapă de ascultare pentru o nouă conexiune
astfel încât să știm mereu starea de variabilele
și astfel încât ne-am, de asemenea, eliberat orice amintire care
ar fi fost alocate pentru o conexiune la rețea anterior.
Următorul este pornește, funcție care am scris
care conține un întreg mulțime de cod de rețea
care incep in cele din urma serverul de web.
>> Ultima sus este funcția numita oprire, care
face exact acest lucru, oprește serverul de web.
Dar mai întâi se eliberează nici o amintire care încă au fost alocate.
Dar în cele din urmă solicită ieșire chiar și fără returnarea de control
funcției nostru principal.
În cele din urmă, unul dintre majoritatea tehnicilor importante
la punerea în aplicare acest server web este Va fi un pic de studiu și de eroare,
având una browser fereastră deschisă la dreapta și o fereastră terminal la
stânga, consola servere fereastră, astfel încât să
Puteti vedea mesajele care sunt fiind afișate pe ecran.
>> Dar mai bine ar fi un al treilea fereastră, o fereastră terminal al doilea,
în care utilizați Telnet, utilizarea pentru care este prescris în spec.
Și Telnet este doar o foarte Programul rețea simplu
care vă permite să pretinde la fi un browser intr-unul fereastră
în timp ce vorbesc la cealaltă fereastră.
În acest fel puteți vedea exact comenzile textuale
care se întorc de la server la client
fără a fi nevoie să poking în jurul valorii de dezvoltator Chrome
Unelte într-un alt mod interfață clunkier.