SPEAKER: Lad os nu dykke i fordelingen kode
og tage et kig på den kontekst hvor den kode, du skriver
vil være i drift.
Ved slutningen af ​​dagen, du kommer til at gennemføre
helheden af ​​webserveren.
Men vi har givet du med skelettet
kode, der har en vis funktionalitet, især relateret til netværk.
Lad os tage et kig.
>> Så heroppe mod toppen af filen er en flok
af funktionen teste makro krav.
Nu dette er blot en funktion i C, hvorved ifølge en flok man-sider
du nødt til at definere nogle af disse konstanter til at være sandt
eller at være endnu specifikke numre, således at du har adgang til bestemte funktioner.
Ellers vil de blive sort og du vil ikke have adgang til.
Så jeg har gjort dette ved hjælp læse man-siderne.
Nu dernede, i linier 15 til 17, vi
har en hel masse begrænsninger erklæret.
>> Og vi har lånt dem fra en populære web-server kaldet Apache.
Og disse er blot numre, der går
at lægge loft over det samlede antal af bytes, der er tilladt
i forskellige sammenhænge til HTTP-anmodning at en browser er tilladt at sende mig.
Dernæst definerer vi oktetter.
Nu en oktet er bare en fancy måde at sige en byte eller otte bits.
Viser sig i gårsdagens en byte ikke nødvendigvis var otte bits,
så oktet er altid otte bits.
Så i dette tilfælde, vi har vedtaget hvad der er almindelig i netværk
verden kalde otte bytes en oktet.
>> Her har jeg angivet, at oktetter vil være 512, så meget som i retsvidenskab
når vi læser en flok bytes ad gangen, også her,
vi kommer til at læse en bundt af oktetter ad gangen.
Næste en hel bunke af header-filer.
Hvordan vidste jeg at inkludere disse?
Jamen jeg blot læse manden sider til en række funktioner
at vi vil bruge i denne fordeling kode og omfatter i dem
Jeg fik besked på at.
>> Og nu har vi en datatype.
Vi har erklæret en oktet til at være en char.
Og vi vil se senere, at det er anvendes i koden.
Og vi har erklæret en hel masse prototyper,
og vi vil gå hurtigt gennem hver af disse funktioner.
Endelig, og måske mest vigtigt at holde i
huske på dette tidspunkt i historien, er, at der
er faktisk en hel bundt af globale variabler
på toppen af ​​filen, rod, CFD, SFD, anmodning fil og krop.
>> Nu generelt under anvendelse af så mange global variabler eller globale variabler på alle,
er ikke tilbage praksis.
Men det viser sig, vi også bruger en teknik kaldet signal håndtering senere
i koden, som tillader os at registrere, når brugeren rammer noget
Ligesom CTRL C og lukke ned serveren elegant.
Og for at gøre det yndefuldt og faktisk frigøre hukommelse,
vi har brug for at have adgang til disse globale variabler.
>> Og lad os nu tage et kig på main, som driver hele dette program.
Først på toppen her vi har en fejl nummer variabel
der synes ikke at har en type, men det er
fordi det er faktisk defineret i en fil kaldet
fejl errno.h som indgår højere oppe.
Hvis du gør mennesket errno til rent faktisk se definitionen for denne ting,
vil du se, at dette er en særlig global variabel,
indstilles ved en hel masse funktioner ikke skrevet
af os, men af ​​forfatterne til Linux og andre systemer til faktisk indstillet
et nummer til den pågældende variabel, når noget går galt, så du kan globalt
regne ud, hvad gik galt.
>> Nu ned under kan du se et nyt teknik måske ved hjælp getopt,
en funktion, der hjælper parse kommando line argumenter, så vi ikke
har gider spilde tid på at regne ud af at analysere noget som 8080,
eller bindestreg p eller bindestreg h for at få hjælp.
getopt væsentlige gør det for os.
Se man-siden for mere.
>> Dernæst gør vi lidt af fejl kontrol for at sikre
at portnummer er inden det angivne interval i spec.
Dernæst ser vi et kald til funktionen starte, hvis definition vi
se på et øjeblik, og som navnet antyder, er dette starter webserveren.
Her har vi et kald til en funktion kaldet signal, som siger,
hvis og når du hører Kontrol C fra brugerens tastatur, gå videre og kalde
en funktion kaldet handler, der sker til i sidste ende rent tingene op og stoppe
serveren.
>> Nedenfor det er det, der synes at være en uendelig løkke, den første linje, som
effektivt er en opfordring til en funktion kaldet
reset, som vi selv gennemføre senere i rækkefølge
at frigøre nogle af vores globale stater.
Derefter er en linje af kode, der konditionelt
kontrollerer tilbagevenden værdi af tilsluttet.
Nu forbundet ligner et prædikat, noget, som returnerer sandt eller falsk.
Og det gør, men der er noget særligt i tilsluttet
i, at det er et blokerende opkald.
Den vil sidde der og vente indtil en brugers browser
forsøger at oprette forbindelse til denne web server og først derefter vil det
returnere sandt eller falsk, så vi fortsætter til indersiden af ​​dette, hvis erklæring.
>> Når der, bemærker denne funktion til en funktion kaldet parse, som vi skrev,
der analyserer alle oktetter, alle af bytes, der kommer fra en browser
til serveren, så vi kan aflevere dig tilbage i sidste ende en værdi til en
af de globale variable, gemmer alle de bytes i bare
overskrifterne i denne anmodning ikke kroppen
hvis der var faktisk et organ til det.
>> Nu dernede vi begynder at parse disse overskrifter til at udtrække
en delmængde af den information at vi holder af.
Specifikt pr specifikation, vi først
ville anmode linje, der er netop allerførste linje,
Forhåbentlig siger noget get skråstreg eller nogle sti og derefter HTTP 1.1.
Vi bruger denne metafor af en nål i en høstak
at kigge efter særlig chars eller adresser.
Og ja, der er en række funktioner i vores fordeling kode
at du også kan finde nyttige når de søger for bestemte værdier.
>> I sidste ende vi kopiere disse bytes i en variabel kaldet linje,
der bemærker også vi har allokeret på stakken
ved hjælp af en dynamisk størrelse array.
Og vi er bevidst forsøger for at undgå at kalde malloc
fordi igen, fordi of Control C er
en potentiel træk ved dette program, er ønsker ikke at have denne kode pludselig
afbrudt af brugeren hitting Kontrol C, og resultatet heraf
er, at jeg ikke kunne have en chance gratis noget, jeg har malloced.
Så jeg forsøger at bruge så meget af stakken er jeg kan her.
>> Næste op, en hel masse til DOS.
Specifikationen vil udlægge på præcis, hvad der forventes her,
men kommentarerne giver dig en antydning af, hvad der ligger forude.
Du skal først validere anmodningen linje
og sørg for, at det ser ud som det specifikationer grammatik, så at sige,
siger det skal.
Du skal herefter udtrække noget kaldet forespørgslen, den ting ud
efter et spørgsmålstegn, ligesom vi så med vores Google eksempel
i forbifarten i en HD parameter.
Vi derefter sammenkæde sammen roden af ​​webserveren
med den sti, der er i denne anmodning første linje
og danne den fulde sti den fil, vi ønsker at søge efter.
>> Derefter vil vi sørge for at filen findes og er læsbar.
Og så vil vi udtrække sin filtypenavn, .html eller .php,
eller nogle sådan udvidelse, der er på meget ende af snoren ønskede.
Næste op er en helhed flok kode vi skrev
til rent faktisk at generere PHP genereret indhold for dig.
I en nøddeskal, dette kode tager i navnet
af den fil, PHP at fortolke.
Vi passerer det ved noget, der hedder et rør ind i PHP tolk.
Kom tilbage svaret, som om responset var selve filen.
Og så har vi gentage over at filens bytes, trække dem alle i én buffer
så vi kan i sidste ende printe dem ud.
>> Faktisk alle disse opfordrer her til dprintf
tillader os at udskrive noget kaldes en filbeskrivere, som
er blot et heltal der repræsenterer en fil.
Meget ens i ånd, men fundamentalt forskellig fra en fil
stjernede pointer.
Bemærk, hvordan du kan bruge syntaksen gerne printf her, så jeg kan dynamisk
indsætte noget som længden for værdien af ​​en HTTP header
kaldet Content-Length.
Og i sidste ende jeg brugte funktion ret til rent faktisk at skrive
kroppen til anmodningen.
>> Desværre, vi kun gennemført støtte til dynamisk
genererede PHP filer.
Vi har ikke gennemføre støtte til statiske filer som GIF og JPEG,
og CSS og HTML-filer.
Det vil desværre er overladt til dig at reagere på kundens formål
dette at gøre.
Så i der du opdage, at der er ikke meget inspiration inden for denne blok,
men hvis du lidt højere op på, hvordan vi gik om tolkning PHP-kode,
de funktioner, du vil bruge er lidt anderledes.
>> Faktisk kan du låne nogle af de funktioner
måske fra retsvidenskab problem sæt, fordi
ved slutningen af ​​dagen alt du behøver at gøre her er, når du ved, hvad fil åben
og når du ved, det er såkaldt MIME-type eller indholdstype,
du nødt til at læse i disse bytes og på en måde spytte dem ud igen.
>> Og nu en tour på fils andre funktioner.
Op først er tilsluttet, der blot returnerer true
når det endelig hører en forbindelse fra en bruger.
Næste op er fejl.
Fejl, i mellemtiden, som en funktion, vi skrev til at håndtere alle de forskellige 400
og 500 HTTP status koder, som du måske ønsker
at sende tilbage til brugeren, sammen med en standard besked.
>> Næste op er belastning, en særlig kødfuld funktion, hvis formål i livet
er at læse fra en fil stjerne pointer den indholdet af en fil til en global buffer
at vi erklæret globalt ovenfor [? main. ?]
Dette er en smule kompliceret, fordi vi nødt til at læse byte fra filen
men tjek på hver iteration om vi har allerede
ramte slutningen af ​​filen eller noget andet er gået galt.
Og vi bruger realloc at sikre, at uanset buffer vi bruger vokser
og vokser og vokser og altid opholder forud for antallet af bytes
at vi skal passe på der.
Handler, i mellemtiden, er den funktion, der bliver
kaldes ved at have registreret Kontrol C som et signal
at vi ønsker at opfange.
Bemærk her i handleren at det i sidste ende
opkald stoppe, hvilket naturligvis stopper webserveren.
Og desværre, opslag er ikke implementeret.
I ånd, er dette en forholdsvis simpel funktion.
Givet et filtypenavn, den har brug for at returnere det såkaldte MIME
type eller indhold type.
Og vi angiver i udbudsbetingelserne hvad der kortlægning skal være.
Men du har brug for at oversætte det i sidste ende til C-kode.
>> Næste op er vores på lignende kødfuld funktion kaldet parse, hvis formål i livet
er at læse, ikke fra en fil, men fra en netværksforbindelse.
Specifikt, læsning og parsing den HTTP-anmodning, der er kommet fra en browser
til serveren, således at i sidste ende kan vi parse
på blot overskrifterne i anmodningen line og returnere dem til dig
ved hjælp af en global buffer, vi ovenfor nævnte [? main. ?]
>> Reset, i mellemtiden, er en funktion, at vi definerer
der bliver kaldt iterativt inde af vigtigste hver gang du er ved
klar til at begynde at lytte for en ny forbindelse
så vi altid ved tilstanden af ​​vores variabler
og så vi har også frigjort nogen hukommelse,
kunne have været afsat til en tidligere netværksforbindelse.
Næste op er at starte, den funktion, skrev vi
der indeholder en hel masse networking kode
der i sidste ende starter webserveren.
>> Sidste up er den funktion kaldet stop, som
gør præcis det, det stopper webserveren.
Men først det frigør enhver hukommelse der stadig er blevet tildelt.
Men det i sidste ende kræver exit uden selv at returnere kontrol
til vores vigtigste funktion.
I sidste ende, en af ​​de de fleste vigtige teknikker
ved gennemførelsen af ​​dette web-server er kommer til at være lidt af trial and error,
har én browservindue åbent til højre og en terminal vindue på
venstre, serverne konsol vindue, så man
kan se de beskeder, der der vises på skærmen.
>> Men endnu bedre ville være en tredje vindue, en anden terminal vindue,
hvor du bruger Telnet, brugen for hvilke der er foreskrevet i spec.
Og Telnet er bare en meget simpelt netværk program
som lader dig at foregive at være en browser i et vindue
mens du taler til det andet vindue.
Denne måde kan du se præcis de tekstuelle kommandoer
der kommer tilbage fra server til klient
uden at skulle stikke omkring Chromes udvikleren
værktøjer i en ellers clunkier interface.