ALTAVEU: Ara anem a bussejar en el codi de distribució i fer una ullada al context en què el codi que escriure que es va a operar. Al final del dia, vostè va a posar en pràctica la totalitat del servidor web. Però hem proporcionat que amb l'esquelet codi que té algunes funcions, particularment en relació amb la creació de xarxes. Anem a fer una ullada. Així que aquí cap a la part superior del fitxer és un grapat de la funció de provar els requisits de macro. Ara bé, això és només una característica de c, segons el qual d'acord amb un munt de pàgines de manual vostè ha de definir algunes de aquestes constants per ser veritat o ser fins i tot números específics de manera que vostè té accés a certes funcions. En cas contrari seran no declarada i vostè no tindrà accés. Així que he fet això per mitjà de la lectura de les pàgines de manual. Ara baix, en les línies 15 i 17, que tenen un munt de límits declarats. I hem prestat aquests d'una servidor web popular anomenat Apache. I aquests són només nombres que es va per limitar el nombre total de bytes que es permet en els diversos contextos de la petició HTTP que permet a un navegador d'enviar. A continuació, definim octets. Ara un octet és només una forma elegant de dir un byte, o vuit bits. Resulta que en antany un byte no era necessàriament vuit bits de manera octet és sempre vuit bits. Així que en aquest cas hem adoptat el que és comú a la xarxa món de cridar a vuit bytes d'un octet. Aquí he especificat que octets voluntat ser de 512, de manera que igual que en l'anàlisi forense quan llegim un munt de bytes alhora, també en aquest cas, anem a llegir un manat de octets alhora. Següent un munt d'arxius de capçalera. Com sé que inclogui aquests? Bé, jo simplement vaig llegir l'home pàgines per a un nombre de funcions que utilitzarem en aquesta distribució codi i incloure en els Em va donar instruccions per. I ara tenim un tipus de dades. Hem declarat un octeto per ser un char. I veurem més endavant que això és utilitzat en tot el codi. I hem declarat una manat sencer de prototips, i anem a caminar ràpidament per cadascuna d'aquestes funcions. Finalment, i potser el més important tenir en la ment en aquest moment de la història, és que no són, de fet el seu conjunt munt de variables globals a la part superior de l'arxiu, arrel, CFD, SFD, sol·licitud, arxiu i el cos. Ara generalment, utilitzant tants mundial variables o variables globals en absolut, no és la pràctica de nou. Però resulta que també estem utilitzant un tècnica anomenada maneig de senyals més tard en el codi, el que ens permet detectar quan l'usuari prem una mica com CTRL C i es tancarà el servidor amb gràcia. I per tal de fer això amb gràcia i en realitat alliberar memòria, necessitem tenir accés a aquestes variables globals. I ara anem a fer una ullada a principal, que impulsa la totalitat d'aquest programa. En primer lloc, a la part superior aquí tenir una variable de nombre d'error que sembla no tenir un tipus, però això és perquè en realitat definit en un arxiu anomenat errno.h error que s'inclou més amunt. Si ho fa l'home errno a realitat vegeu la definició d'aquesta cosa, veuràs que es tracta d'un variable global especial que és fixat per un grapat sencer de funcions no escrita per nosaltres, sinó pels autors de Linux i altres sistemes per establir realment un nombre a aquesta variable quan alguna cosa va malament, perquè pugui a nivell mundial esbrinar el que va sortir malament. Ara baix veuràs una nova tècnica potser usant getopt, una funció que ajuda comando d'anàlisi sintàctica arguments de la línia perquè no ens fem s'ha de preocupar de perdre el temps pensant la manera d'analitzar una mena 8080, o un guió p, o un guió h per obtenir ajuda. getopt bàsicament fa que per a nosaltres. Consulteu la pàgina de manual per a més. A continuació, fem una mica d'error comprovació per assegurar- que el nombre de port està dins del rang especificat en l'especificació. A continuació, veiem una crida a la funció iniciar, la definició ens va mira en un moment, i com el seu nom suggereix, aquest s'inicia el servidor web. Aquí tenim una crida a una funció crida senyal que diu: sempre que escolti Control C de teclat de l'usuari, seguiu endavant i truqui un controlador de funció trucada que està passant el que en última instància, netes i deixar de el servidor. A sota d'això és el que sembla ser un bucle infinit, la primera línia dels quals efectivament és una crida a una funció anomenada restablir, que nosaltres mateixos aplicar més endavant per tal per alliberar alguns dels nostres estats globals. Després que és una línia de codi que condicionalment està comprovant el retorn valor de connectat. Mirades Ara connectats com un predicat, cosa que retorna cert o fals. I ho fa, però hi ha alguna cosa especial en connectat en què es tracta d'una trucada de bloqueig. Serà seure allà i esperar fins que el navegador de l'usuari intenta connectar-se a aquest web servidor i només llavors serà return true o false perquè procedim a l'interior d'aquesta sentència if. Un cop allà, observi aquesta funció a un funció anomenada d'anàlisi, el que escrivim, que analitza tots els octets, tot dels bytes procedents d'un navegador per al servidor, de manera que podem lliurar de tornada a última instància, un valor a un d'aquestes variables globals que emmagatzema tots els bytes en només les capçaleres d'aquest sol·licitud, no el cos si no eren en realitat un cos a la mateixa. Ara baix comencem a analitzar les capçaleres per extreure un subconjunt de la informació que ens preocupem. Específicament, per la especificació, nosaltres primer volia demanar línia, que és només que molt primera línia que esperem que diu alguna cosa així com get reduir o algun camí i després HTTP 1.1. Estem utilitzant aquesta metàfora d'una agulla en un paller buscar en particular caràcters o adreces. I de fet, hi ha un nombre de funcions en el nostre codi de distribució que vostè, també, pot ser que trobeu en la recerca de valors particulars. En última instància, copiem aquests bytes en una línia de variable anomenada, que notem, també, tenim assignat a la pila per mitjà d'una matriu de mida dinàmic. I estem tractant deliberadament per evitar cridar a malloc perquè, de nou, perquè de Control C sent una possible opció d'aquest programa, no vull tenir aquest codi de sobte interromput pels cops d'usuari Control C, el resultat dels quals és que jo no podria tenir una oportunitat per a alguna cosa gratis que he malloced. Així que estic tractant d'usar tant de la pila és el que pugui aquí. El següent, un munt de dos. L'especificació exposarà exactament el que s'espera aquí, però els comentaris que donen una pista del que està per venir. Primer ha de validar la línia de petició i assegureu-vos que sembla que el especificacions gramàtica, per així dir-ho, diu que hauria. A continuació, extreure alguna cosa anomenat la consulta, la matèria cap a fora després d'un signe d'interrogació, com vam veure amb el nostre exemple Google de passada en un paràmetre HD. Després es concatena junts l'arrel del servidor web amb la ruta que està en aquesta primera línia de petició i formar la ruta completa l'arxiu que volem cercar. Després d'això, anem a fer que l'arxiu existeix i és llegible. I després anem a extreure el seu extensió d'arxiu, els arxius .html o .php la, o alguna extensió que està en el final de la cadena sol·licitada. El següent és un tot munt de codi que escrivim per generar realment PHP contingut per a vostè generat. En poques paraules, aquesta codi pren al nom del fitxer que voleu PHP interpretar. Nosaltres vam passar per una cosa anomenada un tub en l'intèrpret de PHP. Torna la resposta com si la resposta fos un arxiu en si mateix. I després iterem sobre aquest arxiu de bytes, tirant tots en un memòria intermèdia pel que podem en última instància imprimir-los. De fet, tots aquests demana aquí per dprintf ens permet imprimir alguna cosa anomenat un descriptor d'arxiu, que és simplement un sencer que representa un arxiu. Molt similar en esperit, però fonamentalment diferent d'un arxiu indicador de l'estrella. Observeu com es pot utilitzar la sintaxi com printf aquí perquè jo pugui dinàmicament inserir una mena de longitud pel valor d'una capçalera HTTP anomenat Content-Length. I en última instància, he utilitzat la funció dret a escriure en realitat el cos de la sol·licitud. Per desgràcia, només implementem suport per dinàmicament arxius PHP generats. No ens implementem suport a arxius estàtics com gifs i arxius JPEG, i arxius CSS i HTML. Això, per desgràcia, es deixa a vostè per respondre a la finalitat client això a veure. Així que allà trobareu que hi ha no gaire inspiració dins d'aquest bloc, però si una mica més amunt del que ens vam anar sobre la interpretació de codi PHP, les funcions que es van a utilitzar són una mica diferents. De fet, vostè pot demanar prestat part de la funcionalitat potser de la medicina forense conjunt de problemes, perquè al final del dia tot el que necessita fer aquí és un cop heu escoltat el que obrir el fitxer i una vegada que sap que l'anomenat Tipus MIME o tipus de contingut, vostè necessita llegir en aquests bytes i d'alguna manera ells escopir de tornada. I ara un recorregut per aquest altres funcions d'arxiu. Fins i tot es connecta primer, que simplement retorna true quan per fi se sent un la connexió d'un usuari. El següent és l'error. Error, per la seva banda, com una funció que escriure per manejar les diferents 400 i l'estat HTTP 500 codis que vostè pot ser que vulgueu per enviar de nou a l'usuari, juntament amb un missatge estàndard. El següent pas és la càrrega, un particular funció carnós, el propòsit en la vida està a llegir d'una estrella arxiu punter del contingut d'un arxiu en una memòria intermèdia mundial que declarem a nivell mundial per sobre de [? principal. ?] Això és una mica complexa perquè cal llegir els bytes de l'arxiu però comprovar en cada iteració si ja hem colpejar el final de l'arxiu o alguna cosa ha anat malament. I utilitzem realloc per assegurar-se que qualsevol memòria intermèdia que estem fent servir és cada vegada més gran i creixent i creixent i sempre mantenir-se a l'avantguarda de la quantitat de bytes que hem d'encaixar-hi. Handler, per la seva banda, és la funció que rep cridat per manera de tenir Control C registrada com un senyal de que volem interceptar. Noteu aquí a handler que en última instància trucades detenen, que per descomptat deté el servidor web. I, per desgràcia, de recerca no s'ha implementat. En esperit, aquest és un funció bastant simple. Donada l'extensió d'arxiu, necessita per tornar hi ha l'anomenat MIME tipus o tipus de contingut. I s'especifica en el plec de condicions el que la cartografia ha de ser. Però cal traduir que en última instància al codi c. El següent és la nostra funció similar a carn denominat parse, el propòsit en la vida és llegir, no des d'un arxiu, però a partir d'una connexió de xarxa. En concret, la lectura i anàlisi de la Petició HTTP que ha arribat des d'un navegador al servidor perquè en última instància, podem analitzar a tan sols les capçaleres de la sol·licitud línia i tornar a aquells que per mitjà d'un tampó global que declarem anteriorment [? principal. ?] Canviar, per la seva banda, és un funció que definim que és cridada de forma iterativa l'interior de principal cada vegada que estàs a punt a punt per començar a escoltar per a una nova connexió de manera que sempre sabem l'estat de les nostres variables i pel que hem també alliberat qualsevol memòria que podria haver estat assignat per una connexió de xarxa anterior. El següent pas és començar, la funció que escrivim que conté un conjunt gran quantitat de codi de xarxa que en última instància s'inicia el servidor web. Dura fins és la funció anomenat parada, que fa exactament això, deté el servidor web. Però primer que allibera qualsevol memòria que encara s'ha assignat. Però diu en última instància de sortida sense ni tan sols retornar el control a la nostra funció principal. En última instància, una de les la majoria de les tècniques importants en l'aplicació d'aquest servidor web és serà una mica d'assaig i error, tenir un navegador finestra oberta a la dreta i una finestra de terminal a esquerra, la consola de servidors finestra, de manera que vostè pot veure els missatges que es troben que es mostra a la pantalla. Però millor encara seria tercera finestra, una segona finestra de terminal, en què s'utilitza Telnet, l'ús per als que es prescriu en l'especificació. I Telnet és només una molt programa de xarxa simple que li permet a fingeixes ser un navegador en una finestra mentre parla amb l'altra finestra. D'aquesta manera vostè pot veure exactament les ordres textuals que estan tornant del servidor al client sense haver de ficar al voltant de desenvolupador de Chrome eines en una altra banda interfície clunkier.