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.