1 00:00:00,000 --> 00:00:09,647 2 00:00:09,647 --> 00:00:11,730 SPEAKER: Lad os nu dykke i fordelingen kode 3 00:00:11,730 --> 00:00:14,470 og tage et kig på den kontekst hvor den kode, du skriver 4 00:00:14,470 --> 00:00:15,780 vil være i drift. 5 00:00:15,780 --> 00:00:17,350 Ved slutningen af ​​dagen, du kommer til at gennemføre 6 00:00:17,350 --> 00:00:18,710 helheden af ​​webserveren. 7 00:00:18,710 --> 00:00:20,460 Men vi har givet du med skelettet 8 00:00:20,460 --> 00:00:24,090 kode, der har en vis funktionalitet, især relateret til netværk. 9 00:00:24,090 --> 00:00:25,390 Lad os tage et kig. 10 00:00:25,390 --> 00:00:27,560 >> Så heroppe mod toppen af filen er en flok 11 00:00:27,560 --> 00:00:30,020 af funktionen teste makro krav. 12 00:00:30,020 --> 00:00:33,570 Nu dette er blot en funktion i C, hvorved ifølge en flok man-sider 13 00:00:33,570 --> 00:00:36,410 du nødt til at definere nogle af disse konstanter til at være sandt 14 00:00:36,410 --> 00:00:39,920 eller at være endnu specifikke numre, således at du har adgang til bestemte funktioner. 15 00:00:39,920 --> 00:00:42,470 Ellers vil de blive sort og du vil ikke have adgang til. 16 00:00:42,470 --> 00:00:45,340 Så jeg har gjort dette ved hjælp læse man-siderne. 17 00:00:45,340 --> 00:00:48,410 Nu dernede, i linier 15 til 17, vi 18 00:00:48,410 --> 00:00:50,550 har en hel masse begrænsninger erklæret. 19 00:00:50,550 --> 00:00:53,370 >> Og vi har lånt dem fra en populære web-server kaldet Apache. 20 00:00:53,370 --> 00:00:54,650 Og disse er blot numre, der går 21 00:00:54,650 --> 00:00:56,810 at lægge loft over det samlede antal af bytes, der er tilladt 22 00:00:56,810 --> 00:01:01,930 i forskellige sammenhænge til HTTP-anmodning at en browser er tilladt at sende mig. 23 00:01:01,930 --> 00:01:04,310 Dernæst definerer vi oktetter. 24 00:01:04,310 --> 00:01:07,790 Nu en oktet er bare en fancy måde at sige en byte eller otte bits. 25 00:01:07,790 --> 00:01:10,720 Viser sig i gårsdagens en byte ikke nødvendigvis var otte bits, 26 00:01:10,720 --> 00:01:12,339 så oktet er altid otte bits. 27 00:01:12,339 --> 00:01:14,880 Så i dette tilfælde, vi har vedtaget hvad der er almindelig i netværk 28 00:01:14,880 --> 00:01:17,410 verden kalde otte bytes en oktet. 29 00:01:17,410 --> 00:01:21,840 >> Her har jeg angivet, at oktetter vil være 512, så meget som i retsvidenskab 30 00:01:21,840 --> 00:01:24,170 når vi læser en flok bytes ad gangen, også her, 31 00:01:24,170 --> 00:01:27,390 vi kommer til at læse en bundt af oktetter ad gangen. 32 00:01:27,390 --> 00:01:28,922 Næste en hel bunke af header-filer. 33 00:01:28,922 --> 00:01:30,255 Hvordan vidste jeg at inkludere disse? 34 00:01:30,255 --> 00:01:32,730 Jamen jeg blot læse manden sider til en række funktioner 35 00:01:32,730 --> 00:01:35,620 at vi vil bruge i denne fordeling kode og omfatter i dem 36 00:01:35,620 --> 00:01:37,390 Jeg fik besked på at. 37 00:01:37,390 --> 00:01:39,090 >> Og nu har vi en datatype. 38 00:01:39,090 --> 00:01:41,470 Vi har erklæret en oktet til at være en char. 39 00:01:41,470 --> 00:01:44,040 Og vi vil se senere, at det er anvendes i koden. 40 00:01:44,040 --> 00:01:45,670 Og vi har erklæret en hel masse prototyper, 41 00:01:45,670 --> 00:01:47,961 og vi vil gå hurtigt gennem hver af disse funktioner. 42 00:01:47,961 --> 00:01:50,400 Endelig, og måske mest vigtigt at holde i 43 00:01:50,400 --> 00:01:52,520 huske på dette tidspunkt i historien, er, at der 44 00:01:52,520 --> 00:01:54,520 er faktisk en hel bundt af globale variabler 45 00:01:54,520 --> 00:02:00,430 på toppen af ​​filen, rod, CFD, SFD, anmodning fil og krop. 46 00:02:00,430 --> 00:02:03,960 >> Nu generelt under anvendelse af så mange global variabler eller globale variabler på alle, 47 00:02:03,960 --> 00:02:05,280 er ikke tilbage praksis. 48 00:02:05,280 --> 00:02:09,090 Men det viser sig, vi også bruger en teknik kaldet signal håndtering senere 49 00:02:09,090 --> 00:02:11,930 i koden, som tillader os at registrere, når brugeren rammer noget 50 00:02:11,930 --> 00:02:15,080 Ligesom CTRL C og lukke ned serveren elegant. 51 00:02:15,080 --> 00:02:18,240 Og for at gøre det yndefuldt og faktisk frigøre hukommelse, 52 00:02:18,240 --> 00:02:20,800 vi har brug for at have adgang til disse globale variabler. 53 00:02:20,800 --> 00:02:24,510 >> Og lad os nu tage et kig på main, som driver hele dette program. 54 00:02:24,510 --> 00:02:27,720 Først på toppen her vi har en fejl nummer variabel 55 00:02:27,720 --> 00:02:29,570 der synes ikke at har en type, men det er 56 00:02:29,570 --> 00:02:31,500 fordi det er faktisk defineret i en fil kaldet 57 00:02:31,500 --> 00:02:34,800 fejl errno.h som indgår højere oppe. 58 00:02:34,800 --> 00:02:38,780 Hvis du gør mennesket errno til rent faktisk se definitionen for denne ting, 59 00:02:38,780 --> 00:02:41,230 vil du se, at dette er en særlig global variabel, 60 00:02:41,230 --> 00:02:43,350 indstilles ved en hel masse funktioner ikke skrevet 61 00:02:43,350 --> 00:02:48,730 af os, men af ​​forfatterne til Linux og andre systemer til faktisk indstillet 62 00:02:48,730 --> 00:02:52,400 et nummer til den pågældende variabel, når noget går galt, så du kan globalt 63 00:02:52,400 --> 00:02:54,830 regne ud, hvad gik galt. 64 00:02:54,830 --> 00:02:58,540 >> Nu ned under kan du se et nyt teknik måske ved hjælp getopt, 65 00:02:58,540 --> 00:03:01,790 en funktion, der hjælper parse kommando line argumenter, så vi ikke 66 00:03:01,790 --> 00:03:05,540 har gider spilde tid på at regne ud af at analysere noget som 8080, 67 00:03:05,540 --> 00:03:08,350 eller bindestreg p eller bindestreg h for at få hjælp. 68 00:03:08,350 --> 00:03:10,300 getopt væsentlige gør det for os. 69 00:03:10,300 --> 00:03:11,750 Se man-siden for mere. 70 00:03:11,750 --> 00:03:13,960 >> Dernæst gør vi lidt af fejl kontrol for at sikre 71 00:03:13,960 --> 00:03:17,420 at portnummer er inden det angivne interval i spec. 72 00:03:17,420 --> 00:03:20,240 Dernæst ser vi et kald til funktionen starte, hvis definition vi 73 00:03:20,240 --> 00:03:24,040 se på et øjeblik, og som navnet antyder, er dette starter webserveren. 74 00:03:24,040 --> 00:03:26,960 Her har vi et kald til en funktion kaldet signal, som siger, 75 00:03:26,960 --> 00:03:30,750 hvis og når du hører Kontrol C fra brugerens tastatur, gå videre og kalde 76 00:03:30,750 --> 00:03:34,650 en funktion kaldet handler, der sker til i sidste ende rent tingene op og stoppe 77 00:03:34,650 --> 00:03:35,500 serveren. 78 00:03:35,500 --> 00:03:39,470 >> Nedenfor det er det, der synes at være en uendelig løkke, den første linje, som 79 00:03:39,470 --> 00:03:41,660 effektivt er en opfordring til en funktion kaldet 80 00:03:41,660 --> 00:03:45,110 reset, som vi selv gennemføre senere i rækkefølge 81 00:03:45,110 --> 00:03:47,470 at frigøre nogle af vores globale stater. 82 00:03:47,470 --> 00:03:50,480 Derefter er en linje af kode, der konditionelt 83 00:03:50,480 --> 00:03:52,576 kontrollerer tilbagevenden værdi af tilsluttet. 84 00:03:52,576 --> 00:03:55,700 Nu forbundet ligner et prædikat, noget, som returnerer sandt eller falsk. 85 00:03:55,700 --> 00:03:58,040 Og det gør, men der er noget særligt i tilsluttet 86 00:03:58,040 --> 00:03:59,960 i, at det er et blokerende opkald. 87 00:03:59,960 --> 00:04:03,180 Den vil sidde der og vente indtil en brugers browser 88 00:04:03,180 --> 00:04:05,860 forsøger at oprette forbindelse til denne web server og først derefter vil det 89 00:04:05,860 --> 00:04:10,160 returnere sandt eller falsk, så vi fortsætter til indersiden af ​​dette, hvis erklæring. 90 00:04:10,160 --> 00:04:13,870 >> Når der, bemærker denne funktion til en funktion kaldet parse, som vi skrev, 91 00:04:13,870 --> 00:04:17,230 der analyserer alle oktetter, alle af bytes, der kommer fra en browser 92 00:04:17,230 --> 00:04:21,010 til serveren, så vi kan aflevere dig tilbage i sidste ende en værdi til en 93 00:04:21,010 --> 00:04:24,420 af de globale variable, gemmer alle de bytes i bare 94 00:04:24,420 --> 00:04:26,630 overskrifterne i denne anmodning ikke kroppen 95 00:04:26,630 --> 00:04:28,920 hvis der var faktisk et organ til det. 96 00:04:28,920 --> 00:04:32,980 >> Nu dernede vi begynder at parse disse overskrifter til at udtrække 97 00:04:32,980 --> 00:04:35,490 en delmængde af den information at vi holder af. 98 00:04:35,490 --> 00:04:37,740 Specifikt pr specifikation, vi først 99 00:04:37,740 --> 00:04:40,580 ville anmode linje, der er netop allerførste linje, 100 00:04:40,580 --> 00:04:45,710 Forhåbentlig siger noget get skråstreg eller nogle sti og derefter HTTP 1.1. 101 00:04:45,710 --> 00:04:48,150 Vi bruger denne metafor af en nål i en høstak 102 00:04:48,150 --> 00:04:50,370 at kigge efter særlig chars eller adresser. 103 00:04:50,370 --> 00:04:53,120 Og ja, der er en række funktioner i vores fordeling kode 104 00:04:53,120 --> 00:04:56,930 at du også kan finde nyttige når de søger for bestemte værdier. 105 00:04:56,930 --> 00:05:00,630 >> I sidste ende vi kopiere disse bytes i en variabel kaldet linje, 106 00:05:00,630 --> 00:05:03,510 der bemærker også vi har allokeret på stakken 107 00:05:03,510 --> 00:05:05,890 ved hjælp af en dynamisk størrelse array. 108 00:05:05,890 --> 00:05:08,350 Og vi er bevidst forsøger for at undgå at kalde malloc 109 00:05:08,350 --> 00:05:11,100 fordi igen, fordi of Control C er 110 00:05:11,100 --> 00:05:14,630 en potentiel træk ved dette program, er ønsker ikke at have denne kode pludselig 111 00:05:14,630 --> 00:05:17,479 afbrudt af brugeren hitting Kontrol C, og resultatet heraf 112 00:05:17,479 --> 00:05:20,270 er, at jeg ikke kunne have en chance gratis noget, jeg har malloced. 113 00:05:20,270 --> 00:05:23,660 Så jeg forsøger at bruge så meget af stakken er jeg kan her. 114 00:05:23,660 --> 00:05:26,040 >> Næste op, en hel masse til DOS. 115 00:05:26,040 --> 00:05:28,930 Specifikationen vil udlægge på præcis, hvad der forventes her, 116 00:05:28,930 --> 00:05:31,800 men kommentarerne giver dig en antydning af, hvad der ligger forude. 117 00:05:31,800 --> 00:05:33,830 Du skal først validere anmodningen linje 118 00:05:33,830 --> 00:05:37,760 og sørg for, at det ser ud som det specifikationer grammatik, så at sige, 119 00:05:37,760 --> 00:05:38,541 siger det skal. 120 00:05:38,541 --> 00:05:41,290 Du skal herefter udtrække noget kaldet forespørgslen, den ting ud 121 00:05:41,290 --> 00:05:44,200 efter et spørgsmålstegn, ligesom vi så med vores Google eksempel 122 00:05:44,200 --> 00:05:46,320 i forbifarten i en HD parameter. 123 00:05:46,320 --> 00:05:49,050 Vi derefter sammenkæde sammen roden af ​​webserveren 124 00:05:49,050 --> 00:05:52,520 med den sti, der er i denne anmodning første linje 125 00:05:52,520 --> 00:05:56,010 og danne den fulde sti den fil, vi ønsker at søge efter. 126 00:05:56,010 --> 00:06:00,300 >> Derefter vil vi sørge for at filen findes og er læsbar. 127 00:06:00,300 --> 00:06:05,100 Og så vil vi udtrække sin filtypenavn, .html eller .php, 128 00:06:05,100 --> 00:06:09,920 eller nogle sådan udvidelse, der er på meget ende af snoren ønskede. 129 00:06:09,920 --> 00:06:11,940 Næste op er en helhed flok kode vi skrev 130 00:06:11,940 --> 00:06:15,800 til rent faktisk at generere PHP genereret indhold for dig. 131 00:06:15,800 --> 00:06:18,010 I en nøddeskal, dette kode tager i navnet 132 00:06:18,010 --> 00:06:20,250 af den fil, PHP at fortolke. 133 00:06:20,250 --> 00:06:24,630 Vi passerer det ved noget, der hedder et rør ind i PHP tolk. 134 00:06:24,630 --> 00:06:28,060 Kom tilbage svaret, som om responset var selve filen. 135 00:06:28,060 --> 00:06:32,110 Og så har vi gentage over at filens bytes, trække dem alle i én buffer 136 00:06:32,110 --> 00:06:34,180 så vi kan i sidste ende printe dem ud. 137 00:06:34,180 --> 00:06:37,230 >> Faktisk alle disse opfordrer her til dprintf 138 00:06:37,230 --> 00:06:40,110 tillader os at udskrive noget kaldes en filbeskrivere, som 139 00:06:40,110 --> 00:06:42,350 er blot et heltal der repræsenterer en fil. 140 00:06:42,350 --> 00:06:45,360 Meget ens i ånd, men fundamentalt forskellig fra en fil 141 00:06:45,360 --> 00:06:46,620 stjernede pointer. 142 00:06:46,620 --> 00:06:50,260 Bemærk, hvordan du kan bruge syntaksen gerne printf her, så jeg kan dynamisk 143 00:06:50,260 --> 00:06:54,000 indsætte noget som længden for værdien af ​​en HTTP header 144 00:06:54,000 --> 00:06:55,270 kaldet Content-Length. 145 00:06:55,270 --> 00:06:57,990 Og i sidste ende jeg brugte funktion ret til rent faktisk at skrive 146 00:06:57,990 --> 00:07:00,040 kroppen til anmodningen. 147 00:07:00,040 --> 00:07:03,750 >> Desværre, vi kun gennemført støtte til dynamisk 148 00:07:03,750 --> 00:07:05,350 genererede PHP filer. 149 00:07:05,350 --> 00:07:08,520 Vi har ikke gennemføre støtte til statiske filer som GIF og JPEG, 150 00:07:08,520 --> 00:07:10,660 og CSS og HTML-filer. 151 00:07:10,660 --> 00:07:14,450 Det vil desværre er overladt til dig at reagere på kundens formål 152 00:07:14,450 --> 00:07:15,090 dette at gøre. 153 00:07:15,090 --> 00:07:20,050 Så i der du opdage, at der er ikke meget inspiration inden for denne blok, 154 00:07:20,050 --> 00:07:23,520 men hvis du lidt højere op på, hvordan vi gik om tolkning PHP-kode, 155 00:07:23,520 --> 00:07:25,520 de funktioner, du vil bruge er lidt anderledes. 156 00:07:25,520 --> 00:07:27,561 >> Faktisk kan du låne nogle af de funktioner 157 00:07:27,561 --> 00:07:29,620 måske fra retsvidenskab problem sæt, fordi 158 00:07:29,620 --> 00:07:32,860 ved slutningen af ​​dagen alt du behøver at gøre her er, når du ved, hvad fil åben 159 00:07:32,860 --> 00:07:35,690 og når du ved, det er såkaldt MIME-type eller indholdstype, 160 00:07:35,690 --> 00:07:39,040 du nødt til at læse i disse bytes og på en måde spytte dem ud igen. 161 00:07:39,040 --> 00:07:41,190 >> Og nu en tour på fils andre funktioner. 162 00:07:41,190 --> 00:07:43,820 Op først er tilsluttet, der blot returnerer true 163 00:07:43,820 --> 00:07:47,350 når det endelig hører en forbindelse fra en bruger. 164 00:07:47,350 --> 00:07:48,786 Næste op er fejl. 165 00:07:48,786 --> 00:07:52,296 Fejl, i mellemtiden, som en funktion, vi skrev til at håndtere alle de forskellige 400 166 00:07:52,296 --> 00:07:55,360 og 500 HTTP status koder, som du måske ønsker 167 00:07:55,360 --> 00:07:58,500 at sende tilbage til brugeren, sammen med en standard besked. 168 00:07:58,500 --> 00:08:01,950 >> Næste op er belastning, en særlig kødfuld funktion, hvis formål i livet 169 00:08:01,950 --> 00:08:06,920 er at læse fra en fil stjerne pointer den indholdet af en fil til en global buffer 170 00:08:06,920 --> 00:08:09,000 at vi erklæret globalt ovenfor [? main. ?] 171 00:08:09,000 --> 00:08:12,649 Dette er en smule kompliceret, fordi vi nødt til at læse byte fra filen 172 00:08:12,649 --> 00:08:14,690 men tjek på hver iteration om vi har allerede 173 00:08:14,690 --> 00:08:17,600 ramte slutningen af ​​filen eller noget andet er gået galt. 174 00:08:17,600 --> 00:08:21,210 Og vi bruger realloc at sikre, at uanset buffer vi bruger vokser 175 00:08:21,210 --> 00:08:24,440 og vokser og vokser og altid opholder forud for antallet af bytes 176 00:08:24,440 --> 00:08:25,675 at vi skal passe på der. 177 00:08:25,675 --> 00:08:27,550 Handler, i mellemtiden, er den funktion, der bliver 178 00:08:27,550 --> 00:08:30,630 kaldes ved at have registreret Kontrol C som et signal 179 00:08:30,630 --> 00:08:32,140 at vi ønsker at opfange. 180 00:08:32,140 --> 00:08:34,070 Bemærk her i handleren at det i sidste ende 181 00:08:34,070 --> 00:08:36,780 opkald stoppe, hvilket naturligvis stopper webserveren. 182 00:08:36,780 --> 00:08:39,750 Og desværre, opslag er ikke implementeret. 183 00:08:39,750 --> 00:08:41,940 I ånd, er dette en forholdsvis simpel funktion. 184 00:08:41,940 --> 00:08:44,900 Givet et filtypenavn, den har brug for at returnere det såkaldte MIME 185 00:08:44,900 --> 00:08:46,320 type eller indhold type. 186 00:08:46,320 --> 00:08:49,260 Og vi angiver i udbudsbetingelserne hvad der kortlægning skal være. 187 00:08:49,260 --> 00:08:52,330 Men du har brug for at oversætte det i sidste ende til C-kode. 188 00:08:52,330 --> 00:08:56,490 >> Næste op er vores på lignende kødfuld funktion kaldet parse, hvis formål i livet 189 00:08:56,490 --> 00:08:59,350 er at læse, ikke fra en fil, men fra en netværksforbindelse. 190 00:08:59,350 --> 00:09:03,510 Specifikt, læsning og parsing den HTTP-anmodning, der er kommet fra en browser 191 00:09:03,510 --> 00:09:05,940 til serveren, således at i sidste ende kan vi parse 192 00:09:05,940 --> 00:09:09,530 på blot overskrifterne i anmodningen line og returnere dem til dig 193 00:09:09,530 --> 00:09:12,720 ved hjælp af en global buffer, vi ovenfor nævnte [? main. ?] 194 00:09:12,720 --> 00:09:14,880 >> Reset, i mellemtiden, er en funktion, at vi definerer 195 00:09:14,880 --> 00:09:18,730 der bliver kaldt iterativt inde af vigtigste hver gang du er ved 196 00:09:18,730 --> 00:09:20,799 klar til at begynde at lytte for en ny forbindelse 197 00:09:20,799 --> 00:09:22,840 så vi altid ved tilstanden af ​​vores variabler 198 00:09:22,840 --> 00:09:24,870 og så vi har også frigjort nogen hukommelse, 199 00:09:24,870 --> 00:09:28,070 kunne have været afsat til en tidligere netværksforbindelse. 200 00:09:28,070 --> 00:09:30,060 Næste op er at starte, den funktion, skrev vi 201 00:09:30,060 --> 00:09:31,920 der indeholder en hel masse networking kode 202 00:09:31,920 --> 00:09:34,420 der i sidste ende starter webserveren. 203 00:09:34,420 --> 00:09:36,680 >> Sidste up er den funktion kaldet stop, som 204 00:09:36,680 --> 00:09:38,770 gør præcis det, det stopper webserveren. 205 00:09:38,770 --> 00:09:42,270 Men først det frigør enhver hukommelse der stadig er blevet tildelt. 206 00:09:42,270 --> 00:09:45,850 Men det i sidste ende kræver exit uden selv at returnere kontrol 207 00:09:45,850 --> 00:09:47,480 til vores vigtigste funktion. 208 00:09:47,480 --> 00:09:49,480 I sidste ende, en af ​​de de fleste vigtige teknikker 209 00:09:49,480 --> 00:09:52,680 ved gennemførelsen af ​​dette web-server er kommer til at være lidt af trial and error, 210 00:09:52,680 --> 00:09:55,886 har én browservindue åbent til højre og en terminal vindue på 211 00:09:55,886 --> 00:09:57,760 venstre, serverne konsol vindue, så man 212 00:09:57,760 --> 00:10:00,420 kan se de beskeder, der der vises på skærmen. 213 00:10:00,420 --> 00:10:04,170 >> Men endnu bedre ville være en tredje vindue, en anden terminal vindue, 214 00:10:04,170 --> 00:10:07,135 hvor du bruger Telnet, brugen for hvilke der er foreskrevet i spec. 215 00:10:07,135 --> 00:10:09,640 Og Telnet er bare en meget simpelt netværk program 216 00:10:09,640 --> 00:10:12,660 som lader dig at foregive at være en browser i et vindue 217 00:10:12,660 --> 00:10:14,540 mens du taler til det andet vindue. 218 00:10:14,540 --> 00:10:16,830 Denne måde kan du se præcis de tekstuelle kommandoer 219 00:10:16,830 --> 00:10:18,700 der kommer tilbage fra server til klient 220 00:10:18,700 --> 00:10:20,810 uden at skulle stikke omkring Chromes udvikleren 221 00:10:20,810 --> 00:10:24,010 værktøjer i en ellers clunkier interface. 222 00:10:24,010 --> 00:10:29,099