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.