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.