Speak: Nu ska vi dyka i distributionskoden
och ta en titt på den kontext där koden du skriver
kommer att vara i drift.
Vid slutet av dagen, du kommer att genomföra
helheten av webbservern.
Men vi har gett dig med skelettet
kod som har en viss funktion, speciellt relaterat till nätverkande.
Låt oss ta en titt.
>> Så här uppe mot toppen i filen är ett gäng
av funktionen testa makro krav.
Nu är detta bara en del av c, varvid Enligt ett gäng man-sidor
du måste definiera några av dessa konstanter för att vara sant
eller att vara ens specifika nummer så att du har tillgång till vissa funktioner.
Annars kommer de att Odeklarerat och du kommer inte att ha tillgång till.
Så jag har gjort detta genom att läsa manualsidorna.
Nu ner nedan, i linjerna 15 till 17, vi
har en hel massa gränser deklarerade.
>> Och vi har lånat dessa från en populära webbserver som heter Apache.
Och dessa är bara siffror som går
att begränsa det totala antalet byte som är tillåtna
i olika sammanhang för HTTP-begäran att en webbläsare får skicka mig.
Därefter definierar vi oktetter.
Nu en oktett är bara ett finare sätt att säga ett byte, eller åtta bitar.
Visar sig i förr en byte var inte nödvändigtvis åtta bitar,
så oktett är alltid åtta bitar.
Så i det här fallet har vi antagit vad är vanligt i nätverk
värld av ringa åtta byte en oktett.
>> Här har jag angett att oktetter kommer vara 512, så att ungefär som i kriminalteknik
när vi läser ett gäng byte i taget, även här,
vi ska läsa en gäng oktetter i taget.
Nästa en hel massa header-filer.
Hur visste jag att inkludera dessa?
Jo jag helt enkelt läsa mannen sidor för ett antal funktioner
att vi kommer att använda i denna distribution kod och inkludera i de
Jag fick i uppdrag att.
>> Och nu har vi en datatyp.
Vi har förklarat en oktett för att vara en röding.
Och vi får se senare att det är används i hela koden.
Och vi har deklarerat en massa prototyper,
och vi ska gå snabbt genom var och en av dessa funktioner.
Slutligen, och kanske mest viktigt att hålla i
tänka på denna punkt i berättelsen, är att det
är i själva verket en hel gäng globala variabler
vid toppen av filen, rot, CFD, SFD, begäran, fil och kropp.
>> Nu allmänhet, med hjälp av så många globala variabler, eller globala variabler alls,
är inte baksidan praktiken.
Men det visar sig att vi också med hjälp av en teknik som kallas signalhantering senare
i koden, vilket ger oss möjlighet att upptäcka när användaren slår något
gillar CTRL C och stänga servern graciöst.
Och för att göra det graciöst och faktiskt frigöra minne,
vi måste ha tillgång till dessa globala variabler.
>> Och nu ska vi ta en titt på huvud, vilket driver helheten av detta program.
Först, på toppen här vi har ett felnummer variabel
som inte tycks har en typ, men det är
eftersom det är faktiskt definieras i en fil som heter
error errno.h som ingår högre upp.
Om du gör människan errno att faktiskt se definitionen av denna sak,
du kommer att se att detta är en speciella global variabel som
ställs in med en hel drös av funktioner inte skrivit
av oss, utan av författarna till Linux och andra system för att faktiskt ställa
ett nummer till den variabeln när något går fel så att du kan globalt
räkna ut vad gick fel.
>> Nu nere ser du en ny Tekniken kanske med hjälp getopt,
en funktion som hjälper parse kommandot line argument så att vi inte gör det
behöver bry slösa tid att räkna ut hur man tolka något liknande 8080,
eller streck p, eller streck h för att få hjälp.
getopt gör i huvudsak att för oss.
Se manualsidan för mer.
>> Därefter gör vi en bit av misstag kontrollera för att se
att portnumret är inom det angivna området i spec.
Därefter ser vi ett anrop till funktionen starta, vars definition vi
titta på i ett ögonblick, och som namnet antyder detta startar webbservern.
Här har vi ett anrop till en funktion kallas signal som säger,
om och när du hör kontroll C från användarens tangentbord, gå vidare och ringa
en funktion som kallas hanterare som händer att slutligen rena saker upp och stoppa
servern.
>> Därunder är vad som verkar vara en oändlig slinga, den första raden i vilka
effektivt är ett samtal till en funktion som kallas
återställning, vilket vi själva genomföra senare i ordning
att frigöra en del av våra globala stater.
Efter det är en linje av kod som villkor
kontrollerar retur Värdet av anslutna.
Nu anslutna ser ut som ett predikat, något som returnerar sant eller falskt.
Och det gör det, men det finns något speciellt i anslutna
i att det är en blockerande samtal.
Det kommer att sitta där och vänta tills en användares webbläsare
försöker ansluta till denna webbsida server och först då kommer det
returnera sant eller falskt, så att vi går vidare på insidan av detta om uttalandet.
>> Väl där, märker denna funktion till en Funktionen kallas parse, som vi skrev,
vilket tolkar alla oktett, alla av de bytes som kommer från en webbläsare
till servern, så att vi kan lämna du tillbaka i slutändan ett värde till en
av dessa globala variabler som lagrar alla av bytes i bara
rubrikerna för att begäran, inte kroppen
om det fanns faktiskt en kropp till det.
>> Nu nere vi börjar tolka dessa rubriker för att extrahera
en delmängd av den information att vi bryr oss om.
Specifikt per den specifikation, vi först
ville begära linje, vilket är just det allra första linje som
förhoppningsvis säger något i stil med get snedstreck eller någon stig och sedan HTTP 1.1.
Vi använder denna metafor av en nål i en höstack
att leta efter speciell tecken eller adresser.
Och faktiskt, det finns ett antal funktioner i vår distributionskoden
att du också kan hitta hjälp när du letar efter specifika värden.
>> Ytterst vi kopiera dessa bytes in i en variabel som heter linje,
som märker också, vi har fördelas på stacken
genom en dynamiskt storlek array.
Och vi är medvetet försöker att undvika att ringa malloc
eftersom igen, eftersom of Control C är
en potentiell inslag i detta program, vi vill inte ha denna kod plötsligt
avbrutits av användaren slå Kontroll C, vars resultat
är att jag inte skulle ha en chans gratis något jag har malloced.
Så jag försöker använda så mycket av stapeln är jag kan här.
>> Nästa upp, en hel massa till dos.
Specifikationen kommer förklara på exakt vad som förväntas här,
men kommentarerna ger dig en antydan om vad som väntar.
Du behöver först validera begäranlinjen
och se till att det ser ut som det specifikationer grammatik, så att säga,
säger att det borde.
Du behöver sedan att extrahera något kallas frågan, grejer ut
efter ett frågetecken, som vi såg med vår Google exempel
i förbigående i en HD parameter.
Vi sammanfoga därefter ihop roten av webbserver
med den väg som är i denna begäran första raden
och bildar den fullständiga sökvägen filen vi vill leta efter.
>> Därefter kommer vi att se till att att filen finns och är läsbar.
Och sedan ska vi utvinna dess filändelse, .html eller .php,
eller någon sådan förlängning som är på Alldeles i slutet av den begärda strängen.
Nästa är en helhet gäng kod vi skrev
att faktiskt skapa PHP genererat innehåll för dig.
I ett nötskal, här kod tar i namnet
av den fil du vill PHP att tolka.
Vi passerar den genom något som kallas ett rör in i PHP: s tolk.
Få tillbaka svaret som om svaret var själva filen.
Och då är vi iterera över att filens bytes, dra dem alla i en buffert
så att vi kan i slutändan skriva ut dem.
>> Faktiskt, alla dessa samtal här för dprintf
tillåter oss att skriva ut något kallas en filbeskrivare, vilket
är bara ett heltal som representerar en fil.
Mycket lik i anden, men fundamentalt annorlunda från en fil
stjärniga pekare.
Lägg märke till hur du kan använda syntax som printf här så att jag kan dynamiskt
sätter något liknande längden för värdet av ett HTTP-huvud
kallas Content-Length.
Och i slutändan jag använde Funktionen rätt att faktiskt skriva
kroppen till begäran.
>> Tyvärr, vi bara genomfört stöd för dynamiskt
genererade PHP-filer.
Vi har inte genomfört stöd för statiska filer som gifs och JPEG,
och CSS och HTML-filer.
Det tyvärr är kvar till dig att svara på klient ändamål
detta att göra.
Så i det du kommer att upptäcka att det finns inte mycket inspiration inom detta block,
men om du lite högre upp på hur Vi gick omkring tolka PHP-kod,
de funktioner du kommer att använda är lite annorlunda.
>> I själva verket kan du låna vissa funktioner
kanske från kriminalteknik Problemet set, eftersom
i slutet av dagen allt du behöver för att göra här är när du vet vad filen öppen
och när du vet att det är så kallade MIME-typ eller innehåll typ,
du behöver läsa i dessa bytes och på något sätt spotta dem tillbaka ut.
>> Och nu en rundtur i denna filens andra funktioner.
Upp först ansluts, som helt enkelt returnerar true
när det äntligen hör en anslutning från en användare.
Nästa upp är fel.
Fel, under tiden, som en funktion som vi skrev att hantera alla de olika 400
och 500 HTTP status koder som du kanske vill
att skicka tillbaka till användaren, tillsammans med ett standardmeddelande.
>> Nästa upp är last, en särskilt köttig funktion, vars syfte i livet
är att läsa från en fil stjärna pekaren innehållet i en fil till en global buffert
att vi förklarade globalt ovan [? viktigaste. ?]
Detta är lite komplicerat eftersom vi måste läsa byte från filen
men kolla på varje iteration oavsett om vi har redan
slog i slutet av filen eller något annat har gått fel.
Och vi använder realloc att se till att oavsett buffert vi använder växer
och växer och växer och alltid vistas före antalet byte
att vi måste passa in där.
Handler, under tiden, är den funktion som får
kallas genom att ha registrerad Kontroll C som en signal
att vi vill avlyssna.
Lägg märke här i handler att det i slutändan
samtal stopp, vilket naturligtvis stoppar webbservern.
Och tyvärr, lookup inte genomförs.
I anden, är detta en ganska enkel funktion.
Givet en fil förlängning, behöver det att returnera det sk MIME
typ eller innehållstypen.
Och vi anger i specifikationen vad det kartläggning måste vara.
Men du behöver översätta det i slutändan till C-kod.
>> Nästa upp är vår likaledes köttig funktion kallas parse, vars syfte i livet
är att läsa, inte från en fil, men från en nätverksanslutning.
Specifikt, läsa och analysera den HTTP-begäran som kommit från en webbläsare
till servern så att i slutändan kan vi tolka
på bara rubrikerna i begäran linjen och tillbaka dem till dig
i form av en global buffert som Vi förklarade ovan [? viktigaste. ?]
>> Återställ, under tiden, är ett funktion som vi definierar
som får kallas iterativt inne av huvud varje gång du är på väg
redo att börja lyssna för en ny anslutning
så att vi alltid vet tillståndet i våra variabler
och så att vi har också befriade något minne som
kanske har avsatts för en tidigare nätverksanslutning.
Nästa upp är att börja, det funktion som vi skrev
som innehåller ett helt massa nätverkskoden
som i slutändan börjar webbservern.
>> Förra upp är funktionen kallas stopp, vilket
gör exakt det, det stoppar webbservern.
Men först det frigör något minne som fortfarande har tilldelats.
Men det i slutändan kallar exit utan även återvänder kontrollen
till vår huvuduppgift.
Ytterst en av de de flesta viktiga tekniker
vid genomförandet av detta webbserver är kommer att vara lite av försök och misstag,
med en webbläsarfönster öppet till höger och ett terminalfönster på
kvar, servrar konsolen fönster, så att man
kan se de meddelanden som som visas på skärmen.
>> Men ännu bättre vore en tredje fönster, en andra terminalfönster,
där du använder Telnet, användningen som är föreskrivet i spec.
Och Telnet är bara en mycket enkel nätverksprogram
som låter dig att låtsas vara en webbläsare i ett fönster
när du pratar med det andra fönstret.
Detta gör att du kan se exakt textkommandon
som kommer tillbaka från servern till klienten
utan att behöva peta runt krom utvecklare
verktygen i en annars clunkier gränssnitt.