schule:webserver_programmieren
Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
Beide Seiten der vorigen RevisionVorhergehende ÜberarbeitungNächste Überarbeitung | Vorhergehende ÜberarbeitungNächste ÜberarbeitungBeide Seiten der Revision | ||
schule:webserver_programmieren [2015-12-20 10:32] – [Version 1: Mit einem HttpListener] marco.bakera | schule:webserver_programmieren [2017-04-19 08:39] – Externe Bearbeitung 127.0.0.1 | ||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
+ | ====== Webserver programmieren ====== | ||
+ | Wie funktioniert eigentlich ein Webserver? Ich habe eine ungefähre Vorstellung davon, was mein Browser macht, wenn ich eine Webseite aufrufe. Aber die genauen Details blieben mir bisher immer verborgen. Ich wollte es daher genauer wissen und habe selbst eine Webserver programmiert. Das ist gar nicht so schwer und jeder kann es selbst ausprobieren. | ||
+ | |||
+ | ===== Version 1: Mit einem HttpListener ===== | ||
+ | |||
+ | In der ersten Version habe ich einen Webserver in C# mit der Klasse '' | ||
+ | |||
+ | <code csharp> | ||
+ | using System; | ||
+ | using System.Net; | ||
+ | using System.IO; | ||
+ | |||
+ | namespace Webserver | ||
+ | { | ||
+ | class MainClass | ||
+ | { | ||
+ | public static void Main(string[] args) | ||
+ | { | ||
+ | HttpListener listener = new HttpListener(); | ||
+ | Console.WriteLine(" | ||
+ | listener.Prefixes.Add(" | ||
+ | |||
+ | listener.Start(); | ||
+ | |||
+ | // Aus dem Context kann der Request und der Response gewonnen werden. | ||
+ | HttpListenerContext ctx = listener.GetContext(); | ||
+ | |||
+ | // Die Antwort wird erstellt und in ein Byte-Array konvertiert. | ||
+ | string sAntwort = "Hallo Client\n"; | ||
+ | byte[] aBytes = System.Text.UTF8Encoding.UTF8.GetBytes(sAntwort); | ||
+ | |||
+ | // Aus dem Context wird der OutputStream verwendet. | ||
+ | Stream sOut = ctx.Response.OutputStream; | ||
+ | // Die Antwort wird über den Outputstream an den Client geschickt. | ||
+ | sOut.Write(aBytes, | ||
+ | sOut.Close(); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | ===== Version 2: Mit Netzwerksockets ===== | ||
+ | |||
+ | Die zweite Version nutzt Netzwerksockets und ist bei der Implementierung näher an der Netzwerkschicht. Es könnten also leicht auch andere Netzwerkdienste außer HTTP damit realisiert werden. Ich habe bewusst nur auf der Netzwerkebene gearbeitet und weitere Abstraktionsebenen sowie schon vorhandene Serverkomponenten, | ||
+ | |||
+ | Nach dem Start des Programms, kann man mit einem Browser auf die Adresse ''< | ||
+ | |||
+ | Das Programm verwendet die folgenden Klassen aus den [[https:// | ||
+ | |||
+ | Wenn du es selbst ausprobieren möchtest, solltest du hier aufhören zu lesen und die [[[[schule: | ||
+ | |||
+ | Das Programm kann nun noch beliebig erweitert werden. Im Moment wird der Typ des verschickten Inhalts noch nicht berücksichtigt und nur Text verwendet. Hier könnten man natürlich auch HTML-Seiten übermitteln und z.B. eine statische HTML-Seite wie '' | ||
+ | |||
+ | <code csharp> | ||
+ | using System; | ||
+ | using System.Net; | ||
+ | using System.Net.Sockets; | ||
+ | |||
+ | namespace WebServer | ||
+ | { | ||
+ | class MainClass | ||
+ | { | ||
+ | public static void Main(string[] args) | ||
+ | { | ||
+ | while (true) | ||
+ | { | ||
+ | // IP-Adresse und Port des Servers | ||
+ | IPAddress ipAdresse = IPAddress.Parse(" | ||
+ | IPEndPoint ipEndpunkt = new IPEndPoint(ipAdresse, | ||
+ | Console.WriteLine(" | ||
+ | |||
+ | // Socket erstellen, mit Endpoint verbinden und auf Verbindung warten | ||
+ | Socket socketServer = | ||
+ | new Socket(ipEndpunkt.AddressFamily, | ||
+ | socketServer.Bind(ipEndpunkt); | ||
+ | socketServer.Listen(1); | ||
+ | |||
+ | // Daten empfangen und in Byte-Array ablegen | ||
+ | byte[] buffer = new byte[512]; | ||
+ | Socket socketClient = socketServer.Accept(); | ||
+ | Console.WriteLine( | ||
+ | " | ||
+ | socketClient.Receive(buffer); | ||
+ | |||
+ | // Empfangene Daten ausgeben | ||
+ | Console.WriteLine(" | ||
+ | string sDaten = ""; | ||
+ | for (int i = 0; i < buffer.Length && buffer[i] != 0; i++) | ||
+ | { | ||
+ | sDaten += (char)buffer [i]; | ||
+ | } | ||
+ | Console.WriteLine(sDaten); | ||
+ | |||
+ | // Daten auswerten und Anwort erstellen | ||
+ | string sAntwort = ""; | ||
+ | if (sDaten.Contains(" | ||
+ | { | ||
+ | sAntwort = "Deine IP lautet " + socketClient.RemoteEndPoint; | ||
+ | } | ||
+ | else if(sDaten.Contains(" | ||
+ | { | ||
+ | sAntwort = "Das heutige Datum ist " + DateTime.Now; | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | sAntwort = "Was willst du machen?"; | ||
+ | } | ||
+ | |||
+ | // Antwort in Byte-Array konvertieren und senden | ||
+ | buffer = new byte[sAntwort.Length]; | ||
+ | for (int i = 0; i < sAntwort.Length; | ||
+ | { | ||
+ | buffer [i] = (byte) sAntwort[i]; | ||
+ | } | ||
+ | socketClient.Send(buffer); | ||
+ | |||
+ | // Sockets schließen | ||
+ | socketClient.Close(); | ||
+ | socketServer.Close(); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ===== Version 3: Mit Python ===== | ||
+ | |||
+ | In dem Buch //Raspberry Pi -- programmieren mit Python// von Michael Wiegand wird in Kapitel "11: Webserver" | ||
+ | |||
+ | Als Grundlage dient ein TCP-Server, der im folgenden Quelltext dargestellt ist. Er kann Anfragen entgegennehmen und entsprechend reagieren. | ||
+ | |||
+ | <code python> | ||
+ | import socket | ||
+ | import threading | ||
+ | |||
+ | bind_ip = " | ||
+ | bind_port = 8081 | ||
+ | |||
+ | server = socket.socket(socket.AF_INET, | ||
+ | server.bind((bind_ip, | ||
+ | server.listen(5) | ||
+ | print(" | ||
+ | |||
+ | # Methode, die Anfragen von Clients behandelt | ||
+ | def handle_client(client_socket): | ||
+ | # Anfrage des Client ausgeben | ||
+ | request = client_socket.recv(1024) | ||
+ | print(" | ||
+ | # Einen String zurücksenden | ||
+ | client_socket.send(bytes(" | ||
+ | client_socket.close() | ||
+ | |||
+ | while True: | ||
+ | client,addr = server.accept() | ||
+ | print(" | ||
+ | handle_client(client) | ||
+ | |||
+ | # Optional: Anfrage in einem separaten Thread behandeln | ||
+ | # client_handler = threading.Thread(target=handle_client, | ||
+ | # client_handler.start() | ||
+ | |||
+ | </ |
schule/webserver_programmieren.txt · Zuletzt geändert: 2019-12-12 20:39 von marco.bakera