Spreker: Laten we nu duik in de verdeelsleutel en neem een ​​kijkje op de context waarin de code die u schrijft zal opereren. Aan het einde van de dag, je gaat implementeren het geheel van de webserver. Maar we hebben verstrekt u met het skelet code dat sommige functies hebben, in het bijzonder met betrekking tot netwerken. Laten we eens een kijkje nemen. Dus hier naar de top van het bestand is een bos van functie te testen macro-eisen. Nu is dit slechts een kenmerk van c, waarbij volgens een bos van man pagina's moet je een aantal van definiëren Deze constanten om waar te of zelfs specifieke nummers, zodat zijn heeft u toegang tot bepaalde functies. Anders zullen ze worden zwartwerk en je zal geen toegang hebben. Dus ik heb dit gedaan door middel van het lezen van de man pagina's. Nu beneden, in lijnen 15 tot 17, we hebben een hele hoop beperkingen verklaard. En we hebben deze van een geleende populaire webserver genaamd Apache. En dit zijn slechts nummers die gaan het totale aantal cap bytes die zijn toegestaan in verschillende contexten voor de HTTP verzoek dat een browser is toegestaan ​​om mij te sturen. Vervolgens definiëren we octetten. Nu een octet is gewoon een mooie manier zeggen een byte, of acht bits. Blijkt dat in vervlogen tijden een byte niet noodzakelijk acht bits, dus octet is altijd acht bits. Dus in dit geval hebben we aangenomen wat is gebruikelijk in de netwerken wereld van het aanroepen van acht bytes een octet. Hier heb ik aangegeven dat achttallen zal 512, zo veel als in forensisch als we lezen een heleboel bytes tegelijk ook hier we gaan naar een gelezen tros octetten tegelijk. Naast een hele hoop van header-bestanden. Hoe wist ik dat deze op te nemen? Nou ik lees gewoon de man pagina's voor een aantal functies dat we zullen gebruiken in deze distributie code en omvatten in degenen Ik kreeg de opdracht om. En nu hebben we een soort data. We hebben een octet verklaard om een ​​char zijn. En we zullen later zien dat dat is gebruikt in de code. En we hebben verklaard hele hoop van prototypes, en we zullen snel lopen door elk van deze functies. Ten slotte, en misschien wel het meest belangrijk te houden let op dit punt in het verhaal, dat er in feite geheel bos van globale variabelen het begin van het bestand, wortel, CFD, SFD, verzoek, file en lichaam. Nu algemeen gebruik zoveel globale variabelen, of globale variabelen helemaal, is niet de rug praktijk. Maar het blijkt dat we ook met behulp van een techniek genaamd signaalverwerking later in de code, die ons in staat stelt om detecteren wanneer de gebruiker er iets raakt zoals CTRL C en af ​​te sluiten de server sierlijk. En om sierlijk doen en eigenlijk vrij geheugen, we nodig hebben om toegang te hebben deze globale variabelen. En laten we nu eens een kijkje nemen op de belangrijkste, die drijft het geheel van dit programma. Eerst op hier boven we heb een fout nummer variabele dat lijkt niet te een type, maar dat is want het is eigenlijk gedefinieerd in een bestand genaamd error errno.h die inbegrepen hoger. Als je dat doet de mens errno om daadwerkelijk zie de definitie van dit ding, je zult zien dat dit een speciale globale variabele dat wordt door een hele hoop te stellen van functies niet geschreven door ons, maar door de auteurs van Linux en andere systemen daadwerkelijk vastgesteld een nummer om die variabele wanneer er iets mis gaat, zodat u kunt wereldwijd erachter te komen wat deed fout gaan. Nu beneden zie je een nieuwe techniek wellicht met behulp van getopt, een functie die parse commando helpt line argumenten, zodat we niet hoeft te storen verspillen tijd uitzoeken hoe om iets te ontleden, zoals 8080, of dash p, of dash h om hulp te krijgen. getopt doet in wezen dat voor ons. Zie de man pagina voor meer. Vervolgens een beetje fout doen wij controleren om ervoor te zorgen dat het poortnummer is binnen het opgegeven bereik in de spec. Vervolgens zien we een aanroep van de functie start, waarvan de definitie zullen we kijken in een moment, en zoals de naam suggereert, dit begint de webserver. Hier hebben we een oproep naar een functie genoemd signaal dat zegt, als en wanneer je hoort Controle C uit toetsenbord van de gebruiker, ga je gang en bel een functie genaamd handler dat gaat om uiteindelijk schone dingen en stoppen de server. Onder dat is wat lijkt op een te zijn oneindige lus, de eerste regel van die effectief is een oproep een functie genaamd reset, die onszelf implementeren later in orde vrij te maken wat van onze wereldwijde staten. Daarna is een lijn van code die voorwaardelijk controleert het rendement waarde van de aangesloten. Nu verbonden ziet eruit als een predikaat, iets dat waar of onwaar terugkeert. En het doet, maar er is iets speciaals in de aangesloten doordat het een blokkeringsoproep. Het zal daar te zitten en te wachten totdat de browser van een gebruiker probeert te maken met deze web server en alleen dan zal het return true of false zodat we doorgaan aan de binnenkant van deze if-statement. Eenmaal daar, merkt deze functie om een functie genaamd parse, die we schreven, die alle octetten ontleedt, alle van de bytes vanuit een browser naar de server, zodat we kunnen overhandigen je terug uiteindelijk een waarde op één van de globale variabelen die slaat alle bytes in slechts de headers van die verzoek niet het lichaam als er echter een orgaan aan. Nu beneden beginnen we te ontleden die headers te extraheren een subset van de informatie dat we de zorg over. Specifiek, volgens de specificatie, hebben we eerst wilde vragen lijn, dat is gewoon die eerste lijn die hopelijk zegt iets als get slash of een pad en vervolgens HTTP 1.1. We gebruiken deze metafoor van een naald in een hooiberg om te zoeken naar bepaalde chars of adressen. En inderdaad, er is een aantal functies in onze distributie-code dat je ook kan nuttig vinden bij het zoeken naar bepaalde waarden. Uiteindelijk, kopiëren we deze bytes in een variabele genaamd lijn, die opmerken, ook, we hebben op de stapel toegewezen door middel van een dynamisch formaat array. En we bewust proberen om te voorkomen dat bellen malloc omdat opnieuw, omdat of Control C zijn een potentiële Deze activiteit, we niet willen deze code plotseling onderbroken door de gebruiker hitting Controle C, waarvan het resultaat is dat ik geen kans zou kunnen hebben gratis iets wat ik heb malloced. Dus ik ben op zoek naar zo veel gebruiken van de stapel is ik kan hier. Next up, een hele hoop te dos. De specificatie zal uiteenzetten Op precies wat hier verwacht, maar de opmerkingen geven u een hint van wat ons te wachten. Je moet eerst valideert het verzoek lijn en zorg ervoor dat het lijkt alsof de specificaties grammatica, zogezegd, zegt het zou moeten. Vervolgens moet er iets te halen riep de query, het spul uit na een vraagteken, zoals we zagen met onze Google voorbeeld terloops in een HD parameter. Vervolgens hebben we samenvoegen samen de root van de webserver met het pad dat is in dat het verzoek van de eerste lijn en vormen het volledige pad van het bestand willen we op zoek naar. Daarna gaan we ervoor zorgen dat dat het bestand bestaat en leesbaar. En dan gaan we halen haar bestandsextensie, de .html of .php, of een dergelijke uitbreiding is dat bij de einde van de gevraagde string. Next up is een hele stelletje code schreven we om daadwerkelijk te genereren PHP generated content voor je. In een notendop, dit code neemt in de naam van het bestand dat u wilt PHP te interpreteren. We doorgeven via het zogeheten een buis in PHP interpreter. Ga terug het antwoord alsof de reactie waren bestand zelf. En dan herhalen we over die file's bytes, ze allemaal in een buffer te trekken zodat we uiteindelijk print ze uit. Inderdaad, al deze vraagt ​​hier om dprintf stelt ons in staat om iets af te drukken zogenaamde file descriptor, die is gewoon een integer dat is een bestand. Zeer vergelijkbaar in de geest, maar fundamenteel verschillend van een bestand ster pointer. Merk op hoe je syntax kunt gebruiken als printf hier zodat ik kan dynamisch Steek iets als de lengte de waarde van een HTTP header genaamd Content-Length. En uiteindelijk heb ik de functie recht om daadwerkelijk te schrijven het lichaam om het verzoek. Helaas, wij slechts geïmplementeerd ondersteuning voor dynamisch gegenereerde PHP-bestanden. We hadden geen ondersteuning voor de uitvoering van statische bestanden zoals gifs, en JPEG, en CSS en HTML-bestanden. Dat, helaas, wordt overgelaten aan u om te reageren op de klant doel dit te doen. Dus daar zul je merken dat er niet veel inspiratie binnen dat blok, maar als je een beetje hoger op hoe we gingen over het interpreteren van PHP-code, de functies die u zult gebruiken zijn een beetje anders. In feite kan je lenen Sommige functies misschien van het forensisch onderzoek probleem set, omdat aan het eind van de dag alles wat je nodig hebt om hier doen is als je eenmaal weet wat het bestand geopend en als je eenmaal weet dat het zogenaamde MIME-type of content type, je nodig hebt om te lezen in die bytes en hoe dan spugen ze weer naar buiten. En nu een rondleiding van deze andere functies bestand. Up voor het eerst wordt aangesloten, die gewoon geeft true toen het eindelijk hoort een verbinding van een gebruiker. Next up is fout. Error ondertussen als functie we schreef aan alle van de verschillende 400 behandelen en 500 HTTP-status codes die je zou willen terug te sturen naar de gebruiker, samen met een standaard bericht. Next up is de belasting, een bijzonder vlezige functie, waarvan het doel in het leven is te lezen uit een bestand ster pointer de inhoud van een bestand in een globale buffer dat hebben wij verklaard wereldwijd boven [? belangrijkste. ?] Dit is een beetje ingewikkeld, omdat we moet de bytes gelezen uit het bestand maar controleren op elke iteratie of we hebben al raakte het einde van het bestand of de iets anders is misgegaan. En we gebruiken realloc om ervoor te zorgen dat wat de buffer we gebruiken groeit en groeit en groeit en altijd voorblijven van het aantal bytes die we nodig hebben om te passen in daar. Handler, ondertussen, is de functie die wordt genoemd bij wijze van het hebben geregistreerd Controle C als een signaal dat we willen onderscheppen. Merk hier in handler dat het uiteindelijk oproepen te stoppen, wat natuurlijk stopt de webserver. En helaas, lookup is niet geïmplementeerd. In de geest, dit is een vrij eenvoudig functie. Gegeven een extensie, moet om terug zogenaamde MIME type of content type. En we geven in de specificatie Wat dat mapping moet zijn. Maar je moet vertalen het uiteindelijk om C-code. Next up is onze evenzo vlezige functie riep parse, waarvan het doel in het leven te lezen, niet uit een bestand, maar van een netwerkverbinding. Specifiek, lezen en ontleden van de HTTP-verzoek dat is gekomen vanuit een browser de server zodat Uiteindelijk kunnen we ontleden bij enkel de headers in het verzoek lijn en terug te keren die aan u door middel van een globale buffer die we hierboven [verklaard? belangrijkste. ?] Reset, ondertussen, is een functie definiëren we dat wordt iteratief binnen genoemd van de belangrijkste elke keer dat je over klaar om te beginnen met luisteren een nieuwe verbinding zodat we weten altijd de toestand van onze variabelen en zo dat we hebben ook bevrijd elke geheugen dat misschien zijn toegewezen voor een eerdere netwerkverbinding. Next up wil beginnen, de functie die we schreven dat geheel bevat Veel netwerken code die uiteindelijk begint de webserver. Laatste up is de functie genoemd stop, die doet precies dat, het stopt de webserver. Maar eerst is het bevrijdt elke geheugen dat nog steeds is toegewezen. Maar het uiteindelijk noemt exit zonder zelfs terugkerende controle om onze functie. Uiteindelijk een van de belangrijkste technieken bij de uitvoering van deze web-server is ga een beetje trial and error, het hebben van een browservenster geopend aan de rechterkant en een terminal venster op links, de servers console venster, zodat u kan de berichten die te zien op het scherm wordt weergegeven. Maar nog beter zou een derde zijn raam, een tweede terminal venster, waarin u Telnet, het gebruik gebruiken voor die is voorgeschreven in de spec. En Telnet is gewoon een zeer eenvoudig programma voor het netwerk dat kun je doen alsof zijn een browser in één venster terwijl het spreken aan het andere venster. Op deze manier kunt u zien precies de tekstuele commando's die terug komen van server naar client zonder te porren rond ontwikkelaar chroom's gereedschappen in een anders clunkier interface.