SPRECHER: Lassen Sie uns nun Tauch in den Verteilercode und werfen Sie einen Blick auf den Kontext , in dem der Code, den Sie schreiben, wird sich in Betrieb sein. Am Ende des Tages, Sie gehen zu implementieren sind die Gesamtheit des Webservers. Aber wir zur Verfügung gestellt haben Sie mit dem Skelett Code, der einige Funktionen haben, besonders in Verbindung mit Vernetzung. Lassen Sie uns einen Blick. Also hier nach oben der Datei ist ein Bündel der Funktion erforderliche Makros. Nun, das ist nur eine Funktion von c, wobei nach einer Reihe von Handbuchseiten müssen Sie einige definieren diese Konstanten wahr zu sein oder sogar bestimmte Zahlen, so dass sein haben Sie Zugriff auf bestimmte Funktionen. Ansonsten werden sie nicht deklariert werden, werden und Sie haben keinen Zugriff. Also habe ich diese im Wege erfolgen lesen die Handbuchseiten. Nun da unten, in Zeilen 15 bis 17, wir haben eine ganze Reihe von Grenzen erklärt. Und wir haben diese von einem geliehenen beliebteste Web-Server Apache genannt. Und das sind nur Zahlen, die gehen, die Gesamtzahl der Kappe von Bytes, die erlaubt sind in verschiedenen Zusammenhängen für die HTTP-Anforderung dass ein Browser erlaubt mir zu schicken. Als nächstes definieren wir Bytes. Jetzt ein Oktett ist nur eine andere Art zu sagen, ein Byte oder acht Bits. Stellt sich heraus, in vergangenen Zeiten ein Byte nicht unbedingt acht Bits, so Oktett ist immer acht Bits. Also in diesem Fall wir angenommen haben was häufig in der Vernetzung Welt der Aufruf acht Byte ein Oktett. Hier habe ich die Oktett wird angegeben 512 sein, so dass ähnlich wie in der Forensik wenn wir ein paar lesen Bytes auf einmal, auch hier, wir werden ein Lese Bündel von Oktetten zu einem Zeitpunkt. Nächstes eine ganze Reihe von Header-Dateien. Wie wusste ich zu ihnen gehören? Nun lese ich einfach den Mann Seiten für eine Anzahl von Funktionen dass wir in dieser Distribution verwenden Code und sind in die, Ich wurde angewiesen. Und jetzt haben wir einen Datentyp. Wir haben ein Oktett erklärt ein Zeichen sein. Und wir werden später sehen, dass das ist, in der gesamten Code. Und wir erklärt haben, eine ganze Reihe von Prototypen, und wir werden schnell durch zu gehen Jede dieser Funktionen. Schließlich und vielleicht am wichtig zu halten dagegen an diesem Punkt in die Geschichte ist, dass es sind in der Tat eine ganze Haufen von globalen Variablen am Anfang der Datei, Wurzel, CFD, SFD, Anfrage, Datei-und Körper. Jetzt in der Regel, mit so vielen globalen Variablen oder globalen Variablen überhaupt, ist nicht die Praxis zurück. Aber es stellt sich heraus, die wir auch mit ein Technik namens Signalverarbeitung später im Code, die es uns erlaubt zu erkennen, wenn der Benutzer etwas trifft wie CTRL C heruntergefahren der Server ordnungsgemäß. Und um das zu tun, anmutig und tatsächlich freie Speicherplatz, wir brauchen, um Zugang zu haben diese globale Variablen. Und nun schauen Sie sich Haupt, lassen die treibt die Gesamtheit des Programms. Zuerst wird in hier oben haben wir eine Fehlernummer variable daß offenbar nicht eine Art, aber das ist denn es ist tatsächlich in der Datei definiert Fehler errno.h die ist höher enthalten. Wenn Sie Menschen errno auf tatsächlich tun siehe Definition für diese Sache, Sie werden sehen, dass dies ein spezielle globale Variable, wird durch eine ganze Reihe gesetzt Funktionsumfang nicht geschrieben von uns, sondern von den Autoren der Linux und andere Systeme, um tatsächlich eingestellt eine Zahl, die die Variable, wenn etwas schief geht, so dass Sie global herauszufinden, was ging schief. Jetzt unten finden Sie eine neue sehen werden Technik vielleicht mit getopt, eine Funktion, die parse Befehl hilft Zeilenargumente, so dass wir es nicht tun müssen Zeitverschwendung Mühe herauszufinden herauszufinden, wie man so etwas wie 8080 zu analysieren, oder Bindestrich p oder Bindestrich h um Hilfe zu holen. getopt Wesentlichen bedeutet das für uns. Siehe Manpage für mehr. Als nächstes wollen wir ein wenig Fehler Überprüfung, um sicherzustellen, , dass die Port-Nummer ist innerhalb der angegebene Bereich in der spec. Weiter sehen wir einen Aufruf der Funktion beginnen, deren Definition wir sehen in einem Moment, und wie der Name schon sagt, dies startet den Web-Server. Ein Aufruf einer Funktion Hier haben wir genannte Signal, das sagt, ob und wann Sie Steuerung C aus hören Tastatur des Benutzers, gehen Sie vor und nennen eine Funktion namens Handler, die gehen letztlich aufräumen und stoppen der Server. Darunter ist das, was scheint, eine sein Endlosschleife, von denen die erste Leitung effektiv ist ein Aufruf auf eine Funktion zurückzusetzen, die uns we Umsetzung später um frei zu einigen unserer globalen Zustände. Danach ist eine Linie von Code, bedingt überprüft die Rück Wert verbunden. Jetzt verbunden sieht aus wie ein Prädikat, etwas, das wahr oder falsch zurückgibt. Und das tut es, aber es gibt etwas Besonderes in angeschlossenen in, dass es ein blockierender Aufruf. Es wird dort zu sitzen und zu warten bis zum Browser des Benutzers versucht, auf diese Web verbinden Server und nur dann wird es Rückkehr wahr oder falsch, so dass wir fortfahren an der Innenseite des if-Anweisung. Dort angekommen, bemerken diese Funktion, um eine Funktion aufgerufen Parse, die wir geschrieben haben, die alle der Bytes analysiert, alle der Bytes, die von einem Browser, an den Server, so dass wir geben kann Sie wieder am Ende ein Wert, der eine dieser globalen Variablen, speichert alle der Bytes in nur die Header daß Anforderung nicht der Körper wenn es eigentlich ein Körper, um es. Jetzt unten wir beginnen, analysieren diese Header zu extrahieren eine Teilmenge der Informationen wir kümmern uns um. Genauer gesagt, die pro Spezifikation wir zunächst wollte Leitung verlangen, das ist, nur, dass erste Zeile, hoffentlich etwas sagt wie get Schrägstrich oder einen Weg und dann HTTP 1.1. Wir nutzen diese Metapher einer Nadel im Heuhaufen nach bestimmten aussehen Zeichen oder Adressen. Und in der Tat, es gibt eine Reihe von Funktionen in unserem Vertriebs Code dass auch Sie hilfreich finden könnte, bei der Suche nach bestimmten Werten. Letztlich diese Bytes kopieren wir in eine Variable namens Linie, welche feststellen, zu, haben wir auf dem Stapel zuge mittels eines dynamisch dimensioniert Array. Und wir bewusst versucht um zu vermeiden, ruft malloc weil wieder, denn Kontroll C wobei eine potentielle Merkmal dieses Programms, die wir will nicht diesen Code plötzlich durch den Benutzer unterbrochen schlag Kontrolle C, wobei das Ergebnis davon ist, dass ich vielleicht eine Chance nicht kostenlos etwas, das ich malloced. So versuche ich, so viel verwenden des Stapels kann ich hier. Weiter oben, eine ganze Reihe von auf dos. Die Spezifikation wird darlegen auf genau das, was Sie hier erwartet, aber die Kommentare geben Ihnen ein Hauch von dem, was vor uns liegt. Als erstes müssen Sie Validierung der Anforderungsleitung und stellen Sie sicher, dass es aussieht wie die Spezifikationen Grammatik, so zu sprechen, sagt es sollte. Sie müssen dann etwas zu extrahieren rief die Abfrage, die Sachen aus nach einem Fragezeichen, wie wir mit unserer Google Beispiel sah im Vorbeigehen in einem HD-Parameter. Wir verketten dann die Wurzel des Webservers mit dem Pfad, der in ist dieser Antrag ersten Zeile und bilden den vollständigen Pfad die Datei wollen wir zu achten ist. Danach werden wir, um sicherzustellen, , dass die Datei existiert und lesbar ist. Und dann werden wir zu extrahieren ihre Dateierweiterung, die .html oder .php, oder so-Erweiterung, die auf die ist Ganz am Ende der angeforderten Zeichenfolge. Als nächstes ist eine ganze Reihe von Code schrieben wir tatsächlich PHP generieren generated Content für Sie. Kurz gesagt, diese Code nimmt im Namen der Datei, die Sie PHP zu interpretieren. Wir fahren durch die so genannte ein Rohr in der PHP-Interpreter. Holen Sie sich zurück, als ob die Antwort die Antwort waren eine Datei selbst. Und dann über die Datei zu durchlaufen wir Bytes, zog sie alle in einen Puffer so dass wir letztlich ausdrucken. Tatsächlich sind alle diese ruft hier, um dprintf ermöglicht es uns, etwas zu drucken genannt Dateideskriptor, die ist nur eine ganze Zahl dass eine Datei. Sehr ähnlich in Geist, sondern grundlegend von einer Datei Sterne-Zeiger. Beachten Sie, wie Sie können, wie Syntax verwenden printf hier, so dass ich dynamisch legen etwas wie die Länge für den Wert von einem HTTP-Header genannte Content-Length. Und schließlich habe ich die Funktion vor, eigentlich schreiben der Körper auf die Anforderung. Leider haben wir nur durchgeführt Unterstützung für dynamisch generierten PHP-Dateien. Wir haben nicht umsetzen Unterstützung statische Dateien wie GIF, JPEG, und CSS und HTML-Dateien. Das ist leider bleibt Ihnen überlassen an den Client Zweck reagieren dies zu tun. Also dort werden Sie feststellen, dass es nicht viel Inspiration innerhalb dieses Blocks, aber wenn man ein wenig weiter oben, wie wir zur Interpretation PHP-Code ging, Funktionen, die Sie verwenden werden sind ein wenig anders. In der Tat, können Sie ausleihen einige der Funktionen vielleicht aus der Forensik Problem Set, weil am Ende des Tages alles, was Sie brauchen hier tun ist, wenn Sie wissen, welche Datei geöffnet und wenn Sie wissen, dass es so genannte MIME-Typ oder einem Inhaltstyp, Sie in diesen Bytes lesen müssen und irgendwie speit sie wieder aus. Und nun eine Tour durch diese andere Funktionen Datei. Bis ersten verbunden ist, die einfach true zurück wenn es endlich hört ein Verbindung von einem Benutzer. Als nächstes ist Fehler. Fehlerdessen als eine Funktion wir schrieb an alle anderen 400 hand und 500 HTTP-Status Codes, die Sie vielleicht an den Benutzer zurückzusenden, zusammen mit einer Standard-Nachricht. Als nächstes ist Last, ein besonders fleischig Funktion, deren Zweck im Leben wird aus einer Datei Sterne Lesezeiger der Inhalt einer Datei in einen globalen Puffer dass wir global deklariert oben [? Haupt. ?] Das ist ein bisschen kompliziert, weil wir müssen die Bytes aus der Datei gelesen aber überprüfen Sie bei jeder Iteration ob wir bereits haben traf das Ende der Datei oder etwas schief gegangen ist. Und wir verwenden realloc um sicherzustellen, dass was auch immer Puffer verwenden wir wächst und wächst und wächst und immer bleiben voran von der Anzahl von Bytes dass wir dort passen. Handler, mittlerweile ist die Funktion, die bekommt haft mit genannt Registrierte Steuerung C als Signal dass wir wollen, abzufangen. Beachten Sie, hier in Handler dass es letztendlich Anrufe zu beenden, was natürlich stoppt den Web-Server. Und leider Lookup ist nicht implementiert. Im Geist, das ist ein ziemlich einfache Funktion. Bei einer Dateierweiterung, muss es Rückkehr ist es so genannte MIME Typ oder einem Inhaltstyp. Und wir in der Spezifikation angeben was das Mapping muss. Aber Sie übersetzen müssen es schließlich zu C-Code. Als nächstes ist unser ähnlich fleischig Funktion genannt Parse, deren Zweck im Leben zu lesen ist, nicht in einer Datei, sondern aus einer Netzwerkverbindung. Genauer gesagt, Lesen und Parsen der HTTP-Anforderung, ist von einem Browser kommen an den Server, so dass letztlich wir analysieren können bei nur die Header in der Anfrage Linie und zurück die zu Ihnen mittels eines globalen Puffer dass wir oben [erklärt? Haupt. ?] Zurücksetzen der Zwischenzeit wird ein Funktion, die wir definieren dass wird iterativ innerhalb genannt Haupt jedes Mal Sie sind bereit zu starten hören für eine neue Verbindung so dass wir immer wissen, der Zustand unserer Variablen und damit haben wir auch befreit jeden Speicher, könnte für zugeteilt worden eine vorherige Netzwerkverbindung. Als nächstes ist zu beginnen, die Funktion, die wir geschrieben haben dass eine ganze enthält Viele Netzwerk-Code das beginnt letztendlich auf den Webserver. Letzte up ist die Funktion genannt Altestelle, die tut genau das, es stoppt den Web-Server. Aber zuerst es entlastet jede Speicher dass noch zugeordnet worden. Aber es letztendlich ruft exit ohne auch nur die Steuerung zurück unsere Hauptaufgabe. Letztlich eine der wichtigsten Techniken Bei der Umsetzung dieser Web-Server werde ein bisschen von Versuch und Irrtum sein, mit einem Browser-Fenster geöffnet auf der rechten Seite und ein Terminal-Fenster an links, die Server-Konsole Fenster, so dass Sie können die Nachrichten, die es zu sehen die auf dem Bildschirm angezeigt. Aber noch besser wäre ein Drittel Fenster, ein zweites Terminalfenster in dem Sie Telnet, die Nutzung für die in der Spezifikation vorgeschrieben. Und Telnet ist nur eine sehr einfache Netzwerkprogramm , mit dem Sie auf so zu tun, ist ein Browser in einem Fenster während er mit der anderen Fenster. Auf diese Weise können Sie sehen, genau die Textbefehle die zurück kommen vom Server zum Client ohne Stossen um Chrome-Entwickler Werkzeuge in einem ansonsten clunkier Schnittstelle.