La plongée de Maintenant, nous allons: ENCEINTE dans le code de distribution et jeter un oeil sur le contexte dans lequel le code que vous écrivez va fonctionner. A la fin de la journée, vous allez mettre en œuvre la totalité du serveur web. Mais nous avons fourni vous avec le squelette Code qui ont une certaine fonctionnalité, notamment liés à la mise en réseau. Jetons un coup d'oeil. Donc, ici vers le haut du fichier est un tas des exigences de test de fonctionnalités macro. Maintenant, ce est juste une fonction de c, lequel selon un tas de pages de manuel vous devez définir certains des ces constantes pour être vrai ou encore des numéros spécifiques de sorte que vous avez accès à certaines fonctions. Sinon ils seront non déclarés et vous ne aurez pas accès. Donc, je ai fait cela par de lire les pages de manuel. Maintenant en bas, dans lignes 15 à 17, nous avoir tout un tas de limites déclarées. Et nous avons emprunté ce à partir d'un serveur Web populaire appelé Apache. Et ce ne sont là chiffres qui vont de plafonner le nombre total d'octets qui sont autorisés dans divers contextes de la requête HTTP qu'un navigateur est autorisé à me envoyer. Ensuite, nous définissons octets. Maintenant un octet est juste une façon élégante de dire un octet, ou huit bits. Il se avère que dans un octet antan ne était pas nécessairement huit bits afin octet est toujours huit bits. Donc, dans ce cas, nous avons adopté ce qui est commun dans le réseau monde d'appeler huit octets un octet. Ici, je ai précisé que octets sera être 512, de sorte que tout comme en médecine légale quand nous lisons un tas de octets à la fois, ici aussi, nous allons lire un tas d'octets à la fois. Suivant tout un tas de fichiers d'en-tête. Comment ai-je sais de les inclure? Eh bien je ai simplement lu l'homme pages pour un certain nombre de fonctions que nous allons utiliser dans cette distribution code et inclure dans ceux Je ai été chargé de. Et maintenant nous avons un type de données. Nous avons déclaré un octet d'être un produit de carbonisation. Et nous verrons plus tard que ce est utilisée dans le code. Et nous avons déclaré un tas ensemble de prototypes, et nous allons marcher rapidement à travers chacune de ces fonctions. Enfin, et peut-être plus important de garder à l'esprit à ce moment- l'histoire, ce est qu'il ya sont en fait un ensemble tas de variables globales au début du fichier, racine, CFD, SFD, demande, fichier et le corps. Maintenant, en général, en utilisant tant mondial variables ou variables globales à tous, ne est pas la pratique de retour. Mais il se avère que nous sommes également en utilisant un technique appelée traitement du signal plus tard dans le code, ce qui nous permet de détecter le moment où l'utilisateur appuie sur quelque chose comme CTRL C et se arrêtera le serveur gracieusement. Et pour le faire gracieusement et effectivement libérer de la mémoire, nous avons besoin d'avoir accès à ces variables globales. Et maintenant, nous allons jeter un oeil à principal, qui entraîne l'ensemble de ce programme. Tout d'abord, en haut ici, nous avoir un nombre variable d'erreur qui apparaît pas à avoir un type, mais ce est parce que ce est fait définie dans un fichier appelé erreur qui errno.h est inclus ci-dessus. Si vous faites l'homme errno à fait voir la définition pour cette chose, vous verrez que ce est un variable globale spéciale est fixé par tout un tas des fonctions non écrite par nous, mais par les auteurs de Linux et d'autres systèmes de réellement mis un certain nombre à cette variable lorsque quelque chose qui ne va pas afin que vous puissiez l'échelle mondiale comprendre ce qui fait aller mal. Maintenant en bas vous verrez une nouvelle technique utilisant peut-être getopt, une fonction qui permet de commande parse les arguments de ligne de telle sorte que nous ne avons pas à se soucier de perdre du temps figurer comment analyser quelque chose comme 8080, ou un tiret p, ou un tiret h pour obtenir de l'aide. getopt fait essentiellement que pour nous. Voir la page de manuel pour plus. Ensuite, nous faisons un peu d'erreur vérification pour se assurer que le numéro de port est dans la gamme spécifiée dans la spécification. Ensuite, nous voyons un appel à la fonction commencer, dont la définition nous regarder dans un moment, et comme son nom indique, il démarre le serveur Web. Ici, nous avons un appel à une fonction appelé signal qui dit, si et quand vous entendez le contrôle de C le clavier de l'utilisateur, allez-y et appelez un gestionnaire de fonction appelée ce qui se passe choses à finalement propres et arrêter le serveur. Ci-dessous, ce est ce qui semble être un boucle infinie, la première ligne dont est effectivement un appel à une fonction appelée réinitialiser, qui nous-mêmes nous mettre en œuvre plus tard dans l'ordre afin de libérer certains de nos états globaux. Après ce est une ligne de code qui conditionnellement est de vérifier le retour La valeur de connecté. Maintenant regards connectés comme un prédicat, quelque chose qui renvoie true ou false. Et il le fait, mais il est quelque chose de spécial dans connecté en ce qu'il se agit d'un appel de blocage. Il va rester là et attendre jusqu'à ce que le navigateur d'un utilisateur tente de se connecter à ce site web serveur et alors seulement il retourner true ou false afin que nous procédons à l'intérieur de cette instruction if. Une fois là, vous remarquerez cette fonction à un fonction appelée parse, qui nous avons écrit, qui analyse tous les octets, tous les des octets provenant d'un navigateur sur le serveur, de sorte que nous pouvons remettre vous revenir finalement une valeur à une de ces variables globales stocke tous les octets en seulement les en-têtes de cette demande, pas le corps se il y avait en fait un corps à elle. Maintenant bas nous commençons à analyser ces en-têtes pour extraire un sous-ensemble des informations que nous nous soucions. Plus précisément, par le spécification, nous avons d'abord voulu demander ligne, qui est juste que première ligne dit quelque chose comme je l'espère get slash ou un chemin, puis 1,1 HTTP. Nous utilisons cette métaphore d'une aiguille dans une botte de foin à chercher notamment caractères ou des adresses. Et en effet, il ya un certain nombre de fonctions dans notre code de distribution que vous, aussi, pourraient trouver utile quand on regarde pour des valeurs particulières. En fin de compte, nous copions ces octets en une ligne de variable appelée, qui remarque aussi, nous avons alloué sur la pile par l'intermédiaire d'une matrice de calibrage dynamique. Et nous tente délibérément pour éviter d'appeler malloc car encore une fois, parce Contrôle de C étant une fonction potentiel de ce programme, nous ne voulez pas avoir ce code coup interrompue par l'utilisateur frappe Contrôle de C, dont le résultat ce est que je ne pourrais pas avoir une chance quelque chose de libre, je ai malloced. Je essaie donc d'utiliser autant de la pile est que je peux ici. Ensuite, tout un tas de à dos. La spécification exposera exactement ce qu'on attend ici, mais les commentaires vous donnent un soupçon de ce qui nous attend. Vous devez d'abord valider la ligne de demande et assurez-vous qu'il ressemble à la spécifications grammaire, pour ainsi dire, dit il se doit. Vous devez ensuite extraire quelque chose appelé la requête, l'étoffe après un point d'interrogation, comme nous avons vu notre exemple Google en passant dans un paramètre HD. Nous concaténons puis ensemble la racine du serveur Web avec le chemin qui est en cette demande première ligne et former le chemin complet du le fichier que nous voulons rechercher. Par la suite, nous allons faire en sorte que le fichier existe et est lisible. Et puis nous allons extraire son extension de fichier, le .html ou .php, ou une telle extension qui est au fin de la chaîne demandée. Ensuite, il ya un tout tas de code que nous avons écrit à générer réellement PHP contenu généré pour vous. En un mot, cette Code prend au nom du fichier que vous voulez interpréter PHP. Nous passons par quelque chose appelé un tuyau dans l'interprète de PHP. Retournez la réponse comme si la réponse était un fichier lui-même. Et puis nous parcourons ce fichier de octets, tous tirant dans une mémoire tampon afin que nous puissions finalement les imprimer. En effet, l'ensemble de ceux-ci appelle ici pour dprintf nous permet d'imprimer quelque chose appelé un descripteur de fichier, ce qui est juste un nombre entier qui représente un fichier. Très similaire dans l'esprit, mais fondamentalement différente d'un fichier pointeur étoiles. Remarquez comment vous pouvez utiliser la syntaxe comme printf ici pour que je puisse dynamiquement insérer quelque chose comme la longueur pour la valeur d'un en-tête HTTP appelé Content-Length. Et, finalement, je ai utilisé le droit de réellement écrire fonction le corps de la demande. Malheureusement, nous ne avons mis en place soutien à dynamiquement fichiers PHP générés. Nous ne avons pas implémenter un support pour fichiers statiques comme les gifs, jpeg, et et les fichiers CSS et HTML. Que, malheureusement, est laissé à vous pour répondre à l'objet de client ce qu'il faut faire. Alors là, vous trouverez qu'il ya pas beaucoup d'inspiration au sein de ce bloc, mais si vous un peu plus haut comment nous sommes allés sur l'interprétation du code PHP, les fonctions que vous utiliserez sont un peu différent. En fait, vous pouvez emprunter certaines des fonctionnalités peut-être de la médecine légale jeu de problème, parce que à la fin de la journée tout ce que vous devez faire ici est une fois que vous savez ce fichier ouvert et une fois que vous savez qu'il est soi-disant Le type MIME ou le type de contenu, vous devez lire dans ces octets et en quelque sorte de les recracher. Et maintenant, une visite de cette autres fonctions de fichiers. Jusqu'à la première est reliée, qui retourne simplement vrai quand il entend enfin un connexion d'un utilisateur. Ensuite, il ya erreur. Erreur, quant à lui, en fonction nous écrit pour gérer l'ensemble de la différente 400 et l'état HTTP 500 codes que vous voudrez peut- à renvoyer à l'utilisateur, avec un message standard. Ensuite, il ya la charge, particulièrement fonction viande, dont le but dans la vie est à lire d'une étoile de pointeur de fichier du contenu d'un fichier dans un tampon mondiale que nous avons déclaré au niveau mondial ci-dessus [? principale. ?] Ce est un peu complexe parce que nous avoir à lire les octets du fichier mais il faut vérifier à chaque itération si nous avons déjà frapper la fin du fichier ou autre chose se est mal passé. Et nous utilisons realloc pour se assurer que quel que soit le tampon que nous utilisons est en croissance et de plus en plus et de plus en plus et toujours rester en tête du nombre d'octets que nous devons adapter là. Handler, quant à lui, est la fonction qui obtient appelé par voie d'avoir Contrôle C enregistré comme un signal que nous voulons intercepter. Remarquez ici dans le gestionnaire qu'il finalement appels arrêtent, ce qui bien sûr arrête le serveur Web. Et malheureusement, recherche ne est pas mis en œuvre. Dans l'esprit, ce est un fonction assez simple. Compte tenu de l'extension de fichier, il doit pour revenir ce est ce qu'on appelle MIME type ou le type de contenu. Et nous précisons dans la spécification ce que la cartographie doit être. Mais vous avez besoin de traduire elle a finalement au code c. Ensuite est notre fonction similaire charnu appelée parse, dont le but dans la vie est à lire, pas d'un fichier, mais à partir d'une connexion réseau. Plus précisément, la lecture et l'analyse de la requête HTTP qui est venue à partir d'un navigateur au serveur de telle sorte que finalement, nous pouvons analyser à seulement les en-têtes à la demande ligne et retourner ceux de vous par l'intermédiaire d'un tampon global que nous avons déclaré ci-dessus [? principale. ?] Reset, quant à lui, est un fonction que l'on définit qui est appelé de manière itérative l'intérieur du principal chaque fois que vous êtes sur le prêt à commencer à écouter pour une nouvelle connexion afin que nous sachions toujours l'état de nos variables et que nous avons aussi libérer toute mémoire qui aurait été alloué pour une connexion de réseau précédent. Ensuite, il ya commencer, le fonction que nous écrivions qui contient un ensemble beaucoup de code de réseautage qui commence finalement le serveur Web. Dernière mise est la fonction appelé arrêt, qui fait exactement cela, il arrête le serveur Web. Mais d'abord, il libère toute la mémoire a ce encore été alloué. Mais il appelle finalement sortie sans même rendre le contrôle à notre fonction principale. En fin de compte, l'un des la plupart des techniques importantes la mise en œuvre de ce serveur Web est va être un peu d'essais et d'erreurs, ayant une fenêtre ouverte navigateur à droite et une fenêtre de terminal au à gauche, la console de serveurs fenêtre, de sorte que vous peuvent voir les messages qui sont étant affichée sur l'écran. Mais serait mieux encore un tiers fenêtre, une deuxième fenêtre de terminal, dans lequel vous utilisez Telnet, l'utilisation pour lequel est prescrit dans la spécification. Et Telnet est juste une très programme de réseau simple qui vous permet de faire semblant de un navigateur dans une fenêtre tout en parlant à l'autre fenêtre. De cette façon vous pouvez voir exactement les commandes textuelles qui sont de revenir du serveur au client sans avoir à piquer autour du développeur de Chrome outils dans une autre Interface clunkier.