1 00:00:00,000 --> 00:00:09,647 2 00:00:09,647 --> 00:00:11,730 Speak: Nu ska vi dyka i distributionskoden 3 00:00:11,730 --> 00:00:14,470 och ta en titt på den kontext där koden du skriver 4 00:00:14,470 --> 00:00:15,780 kommer att vara i drift. 5 00:00:15,780 --> 00:00:17,350 Vid slutet av dagen, du kommer att genomföra 6 00:00:17,350 --> 00:00:18,710 helheten av webbservern. 7 00:00:18,710 --> 00:00:20,460 Men vi har gett dig med skelettet 8 00:00:20,460 --> 00:00:24,090 kod som har en viss funktion, speciellt relaterat till nätverkande. 9 00:00:24,090 --> 00:00:25,390 Låt oss ta en titt. 10 00:00:25,390 --> 00:00:27,560 >> Så här uppe mot toppen i filen är ett gäng 11 00:00:27,560 --> 00:00:30,020 av funktionen testa makro krav. 12 00:00:30,020 --> 00:00:33,570 Nu är detta bara en del av c, varvid Enligt ett gäng man-sidor 13 00:00:33,570 --> 00:00:36,410 du måste definiera några av dessa konstanter för att vara sant 14 00:00:36,410 --> 00:00:39,920 eller att vara ens specifika nummer så att du har tillgång till vissa funktioner. 15 00:00:39,920 --> 00:00:42,470 Annars kommer de att Odeklarerat och du kommer inte att ha tillgång till. 16 00:00:42,470 --> 00:00:45,340 Så jag har gjort detta genom att läsa manualsidorna. 17 00:00:45,340 --> 00:00:48,410 Nu ner nedan, i linjerna 15 till 17, vi 18 00:00:48,410 --> 00:00:50,550 har en hel massa gränser deklarerade. 19 00:00:50,550 --> 00:00:53,370 >> Och vi har lånat dessa från en populära webbserver som heter Apache. 20 00:00:53,370 --> 00:00:54,650 Och dessa är bara siffror som går 21 00:00:54,650 --> 00:00:56,810 att begränsa det totala antalet byte som är tillåtna 22 00:00:56,810 --> 00:01:01,930 i olika sammanhang för HTTP-begäran att en webbläsare får skicka mig. 23 00:01:01,930 --> 00:01:04,310 Därefter definierar vi oktetter. 24 00:01:04,310 --> 00:01:07,790 Nu en oktett är bara ett finare sätt att säga ett byte, eller åtta bitar. 25 00:01:07,790 --> 00:01:10,720 Visar sig i förr en byte var inte nödvändigtvis åtta bitar, 26 00:01:10,720 --> 00:01:12,339 så oktett är alltid åtta bitar. 27 00:01:12,339 --> 00:01:14,880 Så i det här fallet har vi antagit vad är vanligt i nätverk 28 00:01:14,880 --> 00:01:17,410 värld av ringa åtta byte en oktett. 29 00:01:17,410 --> 00:01:21,840 >> Här har jag angett att oktetter kommer vara 512, så att ungefär som i kriminalteknik 30 00:01:21,840 --> 00:01:24,170 när vi läser ett gäng byte i taget, även här, 31 00:01:24,170 --> 00:01:27,390 vi ska läsa en gäng oktetter i taget. 32 00:01:27,390 --> 00:01:28,922 Nästa en hel massa header-filer. 33 00:01:28,922 --> 00:01:30,255 Hur visste jag att inkludera dessa? 34 00:01:30,255 --> 00:01:32,730 Jo jag helt enkelt läsa mannen sidor för ett antal funktioner 35 00:01:32,730 --> 00:01:35,620 att vi kommer att använda i denna distribution kod och inkludera i de 36 00:01:35,620 --> 00:01:37,390 Jag fick i uppdrag att. 37 00:01:37,390 --> 00:01:39,090 >> Och nu har vi en datatyp. 38 00:01:39,090 --> 00:01:41,470 Vi har förklarat en oktett för att vara en röding. 39 00:01:41,470 --> 00:01:44,040 Och vi får se senare att det är används i hela koden. 40 00:01:44,040 --> 00:01:45,670 Och vi har deklarerat en massa prototyper, 41 00:01:45,670 --> 00:01:47,961 och vi ska gå snabbt genom var och en av dessa funktioner. 42 00:01:47,961 --> 00:01:50,400 Slutligen, och kanske mest viktigt att hålla i 43 00:01:50,400 --> 00:01:52,520 tänka på denna punkt i berättelsen, är att det 44 00:01:52,520 --> 00:01:54,520 är i själva verket en hel gäng globala variabler 45 00:01:54,520 --> 00:02:00,430 vid toppen av filen, rot, CFD, SFD, begäran, fil och kropp. 46 00:02:00,430 --> 00:02:03,960 >> Nu allmänhet, med hjälp av så många globala variabler, eller globala variabler alls, 47 00:02:03,960 --> 00:02:05,280 är inte baksidan praktiken. 48 00:02:05,280 --> 00:02:09,090 Men det visar sig att vi också med hjälp av en teknik som kallas signalhantering senare 49 00:02:09,090 --> 00:02:11,930 i koden, vilket ger oss möjlighet att upptäcka när användaren slår något 50 00:02:11,930 --> 00:02:15,080 gillar CTRL C och stänga servern graciöst. 51 00:02:15,080 --> 00:02:18,240 Och för att göra det graciöst och faktiskt frigöra minne, 52 00:02:18,240 --> 00:02:20,800 vi måste ha tillgång till dessa globala variabler. 53 00:02:20,800 --> 00:02:24,510 >> Och nu ska vi ta en titt på huvud, vilket driver helheten av detta program. 54 00:02:24,510 --> 00:02:27,720 Först, på toppen här vi har ett felnummer variabel 55 00:02:27,720 --> 00:02:29,570 som inte tycks har en typ, men det är 56 00:02:29,570 --> 00:02:31,500 eftersom det är faktiskt definieras i en fil som heter 57 00:02:31,500 --> 00:02:34,800 error errno.h som ingår högre upp. 58 00:02:34,800 --> 00:02:38,780 Om du gör människan errno att faktiskt se definitionen av denna sak, 59 00:02:38,780 --> 00:02:41,230 du kommer att se att detta är en speciella global variabel som 60 00:02:41,230 --> 00:02:43,350 ställs in med en hel drös av funktioner inte skrivit 61 00:02:43,350 --> 00:02:48,730 av oss, utan av författarna till Linux och andra system för att faktiskt ställa 62 00:02:48,730 --> 00:02:52,400 ett nummer till den variabeln när något går fel så att du kan globalt 63 00:02:52,400 --> 00:02:54,830 räkna ut vad gick fel. 64 00:02:54,830 --> 00:02:58,540 >> Nu nere ser du en ny Tekniken kanske med hjälp getopt, 65 00:02:58,540 --> 00:03:01,790 en funktion som hjälper parse kommandot line argument så att vi inte gör det 66 00:03:01,790 --> 00:03:05,540 behöver bry slösa tid att räkna ut hur man tolka något liknande 8080, 67 00:03:05,540 --> 00:03:08,350 eller streck p, eller streck h för att få hjälp. 68 00:03:08,350 --> 00:03:10,300 getopt gör i huvudsak att för oss. 69 00:03:10,300 --> 00:03:11,750 Se manualsidan för mer. 70 00:03:11,750 --> 00:03:13,960 >> Därefter gör vi en bit av misstag kontrollera för att se 71 00:03:13,960 --> 00:03:17,420 att portnumret är inom det angivna området i spec. 72 00:03:17,420 --> 00:03:20,240 Därefter ser vi ett anrop till funktionen starta, vars definition vi 73 00:03:20,240 --> 00:03:24,040 titta på i ett ögonblick, och som namnet antyder detta startar webbservern. 74 00:03:24,040 --> 00:03:26,960 Här har vi ett anrop till en funktion kallas signal som säger, 75 00:03:26,960 --> 00:03:30,750 om och när du hör kontroll C från användarens tangentbord, gå vidare och ringa 76 00:03:30,750 --> 00:03:34,650 en funktion som kallas hanterare som händer att slutligen rena saker upp och stoppa 77 00:03:34,650 --> 00:03:35,500 servern. 78 00:03:35,500 --> 00:03:39,470 >> Därunder är vad som verkar vara en oändlig slinga, den första raden i vilka 79 00:03:39,470 --> 00:03:41,660 effektivt är ett samtal till en funktion som kallas 80 00:03:41,660 --> 00:03:45,110 återställning, vilket vi själva genomföra senare i ordning 81 00:03:45,110 --> 00:03:47,470 att frigöra en del av våra globala stater. 82 00:03:47,470 --> 00:03:50,480 Efter det är en linje av kod som villkor 83 00:03:50,480 --> 00:03:52,576 kontrollerar retur Värdet av anslutna. 84 00:03:52,576 --> 00:03:55,700 Nu anslutna ser ut som ett predikat, något som returnerar sant eller falskt. 85 00:03:55,700 --> 00:03:58,040 Och det gör det, men det finns något speciellt i anslutna 86 00:03:58,040 --> 00:03:59,960 i att det är en blockerande samtal. 87 00:03:59,960 --> 00:04:03,180 Det kommer att sitta där och vänta tills en användares webbläsare 88 00:04:03,180 --> 00:04:05,860 försöker ansluta till denna webbsida server och först då kommer det 89 00:04:05,860 --> 00:04:10,160 returnera sant eller falskt, så att vi går vidare på insidan av detta om uttalandet. 90 00:04:10,160 --> 00:04:13,870 >> Väl där, märker denna funktion till en Funktionen kallas parse, som vi skrev, 91 00:04:13,870 --> 00:04:17,230 vilket tolkar alla oktett, alla av de bytes som kommer från en webbläsare 92 00:04:17,230 --> 00:04:21,010 till servern, så att vi kan lämna du tillbaka i slutändan ett värde till en 93 00:04:21,010 --> 00:04:24,420 av dessa globala variabler som lagrar alla av bytes i bara 94 00:04:24,420 --> 00:04:26,630 rubrikerna för att begäran, inte kroppen 95 00:04:26,630 --> 00:04:28,920 om det fanns faktiskt en kropp till det. 96 00:04:28,920 --> 00:04:32,980 >> Nu nere vi börjar tolka dessa rubriker för att extrahera 97 00:04:32,980 --> 00:04:35,490 en delmängd av den information att vi bryr oss om. 98 00:04:35,490 --> 00:04:37,740 Specifikt per den specifikation, vi först 99 00:04:37,740 --> 00:04:40,580 ville begära linje, vilket är just det allra första linje som 100 00:04:40,580 --> 00:04:45,710 förhoppningsvis säger något i stil med get snedstreck eller någon stig och sedan HTTP 1.1. 101 00:04:45,710 --> 00:04:48,150 Vi använder denna metafor av en nål i en höstack 102 00:04:48,150 --> 00:04:50,370 att leta efter speciell tecken eller adresser. 103 00:04:50,370 --> 00:04:53,120 Och faktiskt, det finns ett antal funktioner i vår distributionskoden 104 00:04:53,120 --> 00:04:56,930 att du också kan hitta hjälp när du letar efter specifika värden. 105 00:04:56,930 --> 00:05:00,630 >> Ytterst vi kopiera dessa bytes in i en variabel som heter linje, 106 00:05:00,630 --> 00:05:03,510 som märker också, vi har fördelas på stacken 107 00:05:03,510 --> 00:05:05,890 genom en dynamiskt storlek array. 108 00:05:05,890 --> 00:05:08,350 Och vi är medvetet försöker att undvika att ringa malloc 109 00:05:08,350 --> 00:05:11,100 eftersom igen, eftersom of Control C är 110 00:05:11,100 --> 00:05:14,630 en potentiell inslag i detta program, vi vill inte ha denna kod plötsligt 111 00:05:14,630 --> 00:05:17,479 avbrutits av användaren slå Kontroll C, vars resultat 112 00:05:17,479 --> 00:05:20,270 är att jag inte skulle ha en chans gratis något jag har malloced. 113 00:05:20,270 --> 00:05:23,660 Så jag försöker använda så mycket av stapeln är jag kan här. 114 00:05:23,660 --> 00:05:26,040 >> Nästa upp, en hel massa till dos. 115 00:05:26,040 --> 00:05:28,930 Specifikationen kommer förklara på exakt vad som förväntas här, 116 00:05:28,930 --> 00:05:31,800 men kommentarerna ger dig en antydan om vad som väntar. 117 00:05:31,800 --> 00:05:33,830 Du behöver först validera begäranlinjen 118 00:05:33,830 --> 00:05:37,760 och se till att det ser ut som det specifikationer grammatik, så att säga, 119 00:05:37,760 --> 00:05:38,541 säger att det borde. 120 00:05:38,541 --> 00:05:41,290 Du behöver sedan att extrahera något kallas frågan, grejer ut 121 00:05:41,290 --> 00:05:44,200 efter ett frågetecken, som vi såg med vår Google exempel 122 00:05:44,200 --> 00:05:46,320 i förbigående i en HD parameter. 123 00:05:46,320 --> 00:05:49,050 Vi sammanfoga därefter ihop roten av webbserver 124 00:05:49,050 --> 00:05:52,520 med den väg som är i denna begäran första raden 125 00:05:52,520 --> 00:05:56,010 och bildar den fullständiga sökvägen filen vi vill leta efter. 126 00:05:56,010 --> 00:06:00,300 >> Därefter kommer vi att se till att att filen finns och är läsbar. 127 00:06:00,300 --> 00:06:05,100 Och sedan ska vi utvinna dess filändelse, .html eller .php, 128 00:06:05,100 --> 00:06:09,920 eller någon sådan förlängning som är på Alldeles i slutet av den begärda strängen. 129 00:06:09,920 --> 00:06:11,940 Nästa är en helhet gäng kod vi skrev 130 00:06:11,940 --> 00:06:15,800 att faktiskt skapa PHP genererat innehåll för dig. 131 00:06:15,800 --> 00:06:18,010 I ett nötskal, här kod tar i namnet 132 00:06:18,010 --> 00:06:20,250 av den fil du vill PHP att tolka. 133 00:06:20,250 --> 00:06:24,630 Vi passerar den genom något som kallas ett rör in i PHP: s tolk. 134 00:06:24,630 --> 00:06:28,060 Få tillbaka svaret som om svaret var själva filen. 135 00:06:28,060 --> 00:06:32,110 Och då är vi iterera över att filens bytes, dra dem alla i en buffert 136 00:06:32,110 --> 00:06:34,180 så att vi kan i slutändan skriva ut dem. 137 00:06:34,180 --> 00:06:37,230 >> Faktiskt, alla dessa samtal här för dprintf 138 00:06:37,230 --> 00:06:40,110 tillåter oss att skriva ut något kallas en filbeskrivare, vilket 139 00:06:40,110 --> 00:06:42,350 är bara ett heltal som representerar en fil. 140 00:06:42,350 --> 00:06:45,360 Mycket lik i anden, men fundamentalt annorlunda från en fil 141 00:06:45,360 --> 00:06:46,620 stjärniga pekare. 142 00:06:46,620 --> 00:06:50,260 Lägg märke till hur du kan använda syntax som printf här så att jag kan dynamiskt 143 00:06:50,260 --> 00:06:54,000 sätter något liknande längden för värdet av ett HTTP-huvud 144 00:06:54,000 --> 00:06:55,270 kallas Content-Length. 145 00:06:55,270 --> 00:06:57,990 Och i slutändan jag använde Funktionen rätt att faktiskt skriva 146 00:06:57,990 --> 00:07:00,040 kroppen till begäran. 147 00:07:00,040 --> 00:07:03,750 >> Tyvärr, vi bara genomfört stöd för dynamiskt 148 00:07:03,750 --> 00:07:05,350 genererade PHP-filer. 149 00:07:05,350 --> 00:07:08,520 Vi har inte genomfört stöd för statiska filer som gifs och JPEG, 150 00:07:08,520 --> 00:07:10,660 och CSS och HTML-filer. 151 00:07:10,660 --> 00:07:14,450 Det tyvärr är kvar till dig att svara på klient ändamål 152 00:07:14,450 --> 00:07:15,090 detta att göra. 153 00:07:15,090 --> 00:07:20,050 Så i det du kommer att upptäcka att det finns inte mycket inspiration inom detta block, 154 00:07:20,050 --> 00:07:23,520 men om du lite högre upp på hur Vi gick omkring tolka PHP-kod, 155 00:07:23,520 --> 00:07:25,520 de funktioner du kommer att använda är lite annorlunda. 156 00:07:25,520 --> 00:07:27,561 >> I själva verket kan du låna vissa funktioner 157 00:07:27,561 --> 00:07:29,620 kanske från kriminalteknik Problemet set, eftersom 158 00:07:29,620 --> 00:07:32,860 i slutet av dagen allt du behöver för att göra här är när du vet vad filen öppen 159 00:07:32,860 --> 00:07:35,690 och när du vet att det är så kallade MIME-typ eller innehåll typ, 160 00:07:35,690 --> 00:07:39,040 du behöver läsa i dessa bytes och på något sätt spotta dem tillbaka ut. 161 00:07:39,040 --> 00:07:41,190 >> Och nu en rundtur i denna filens andra funktioner. 162 00:07:41,190 --> 00:07:43,820 Upp först ansluts, som helt enkelt returnerar true 163 00:07:43,820 --> 00:07:47,350 när det äntligen hör en anslutning från en användare. 164 00:07:47,350 --> 00:07:48,786 Nästa upp är fel. 165 00:07:48,786 --> 00:07:52,296 Fel, under tiden, som en funktion som vi skrev att hantera alla de olika 400 166 00:07:52,296 --> 00:07:55,360 och 500 HTTP status koder som du kanske vill 167 00:07:55,360 --> 00:07:58,500 att skicka tillbaka till användaren, tillsammans med ett standardmeddelande. 168 00:07:58,500 --> 00:08:01,950 >> Nästa upp är last, en särskilt köttig funktion, vars syfte i livet 169 00:08:01,950 --> 00:08:06,920 är att läsa från en fil stjärna pekaren innehållet i en fil till en global buffert 170 00:08:06,920 --> 00:08:09,000 att vi förklarade globalt ovan [? viktigaste. ?] 171 00:08:09,000 --> 00:08:12,649 Detta är lite komplicerat eftersom vi måste läsa byte från filen 172 00:08:12,649 --> 00:08:14,690 men kolla på varje iteration oavsett om vi har redan 173 00:08:14,690 --> 00:08:17,600 slog i slutet av filen eller något annat har gått fel. 174 00:08:17,600 --> 00:08:21,210 Och vi använder realloc att se till att oavsett buffert vi använder växer 175 00:08:21,210 --> 00:08:24,440 och växer och växer och alltid vistas före antalet byte 176 00:08:24,440 --> 00:08:25,675 att vi måste passa in där. 177 00:08:25,675 --> 00:08:27,550 Handler, under tiden, är den funktion som får 178 00:08:27,550 --> 00:08:30,630 kallas genom att ha registrerad Kontroll C som en signal 179 00:08:30,630 --> 00:08:32,140 att vi vill avlyssna. 180 00:08:32,140 --> 00:08:34,070 Lägg märke här i handler att det i slutändan 181 00:08:34,070 --> 00:08:36,780 samtal stopp, vilket naturligtvis stoppar webbservern. 182 00:08:36,780 --> 00:08:39,750 Och tyvärr, lookup inte genomförs. 183 00:08:39,750 --> 00:08:41,940 I anden, är detta en ganska enkel funktion. 184 00:08:41,940 --> 00:08:44,900 Givet en fil förlängning, behöver det att returnera det sk MIME 185 00:08:44,900 --> 00:08:46,320 typ eller innehållstypen. 186 00:08:46,320 --> 00:08:49,260 Och vi anger i specifikationen vad det kartläggning måste vara. 187 00:08:49,260 --> 00:08:52,330 Men du behöver översätta det i slutändan till C-kod. 188 00:08:52,330 --> 00:08:56,490 >> Nästa upp är vår likaledes köttig funktion kallas parse, vars syfte i livet 189 00:08:56,490 --> 00:08:59,350 är att läsa, inte från en fil, men från en nätverksanslutning. 190 00:08:59,350 --> 00:09:03,510 Specifikt, läsa och analysera den HTTP-begäran som kommit från en webbläsare 191 00:09:03,510 --> 00:09:05,940 till servern så att i slutändan kan vi tolka 192 00:09:05,940 --> 00:09:09,530 på bara rubrikerna i begäran linjen och tillbaka dem till dig 193 00:09:09,530 --> 00:09:12,720 i form av en global buffert som Vi förklarade ovan [? viktigaste. ?] 194 00:09:12,720 --> 00:09:14,880 >> Återställ, under tiden, är ett funktion som vi definierar 195 00:09:14,880 --> 00:09:18,730 som får kallas iterativt inne av huvud varje gång du är på väg 196 00:09:18,730 --> 00:09:20,799 redo att börja lyssna för en ny anslutning 197 00:09:20,799 --> 00:09:22,840 så att vi alltid vet tillståndet i våra variabler 198 00:09:22,840 --> 00:09:24,870 och så att vi har också befriade något minne som 199 00:09:24,870 --> 00:09:28,070 kanske har avsatts för en tidigare nätverksanslutning. 200 00:09:28,070 --> 00:09:30,060 Nästa upp är att börja, det funktion som vi skrev 201 00:09:30,060 --> 00:09:31,920 som innehåller ett helt massa nätverkskoden 202 00:09:31,920 --> 00:09:34,420 som i slutändan börjar webbservern. 203 00:09:34,420 --> 00:09:36,680 >> Förra upp är funktionen kallas stopp, vilket 204 00:09:36,680 --> 00:09:38,770 gör exakt det, det stoppar webbservern. 205 00:09:38,770 --> 00:09:42,270 Men först det frigör något minne som fortfarande har tilldelats. 206 00:09:42,270 --> 00:09:45,850 Men det i slutändan kallar exit utan även återvänder kontrollen 207 00:09:45,850 --> 00:09:47,480 till vår huvuduppgift. 208 00:09:47,480 --> 00:09:49,480 Ytterst en av de de flesta viktiga tekniker 209 00:09:49,480 --> 00:09:52,680 vid genomförandet av detta webbserver är kommer att vara lite av försök och misstag, 210 00:09:52,680 --> 00:09:55,886 med en webbläsarfönster öppet till höger och ett terminalfönster på 211 00:09:55,886 --> 00:09:57,760 kvar, servrar konsolen fönster, så att man 212 00:09:57,760 --> 00:10:00,420 kan se de meddelanden som som visas på skärmen. 213 00:10:00,420 --> 00:10:04,170 >> Men ännu bättre vore en tredje fönster, en andra terminalfönster, 214 00:10:04,170 --> 00:10:07,135 där du använder Telnet, användningen som är föreskrivet i spec. 215 00:10:07,135 --> 00:10:09,640 Och Telnet är bara en mycket enkel nätverksprogram 216 00:10:09,640 --> 00:10:12,660 som låter dig att låtsas vara en webbläsare i ett fönster 217 00:10:12,660 --> 00:10:14,540 när du pratar med det andra fönstret. 218 00:10:14,540 --> 00:10:16,830 Detta gör att du kan se exakt textkommandon 219 00:10:16,830 --> 00:10:18,700 som kommer tillbaka från servern till klienten 220 00:10:18,700 --> 00:10:20,810 utan att behöva peta runt krom utvecklare 221 00:10:20,810 --> 00:10:24,010 verktygen i en annars clunkier gränssnitt. 222 00:10:24,010 --> 00:10:29,099