2011-01-17 13 views
1

lesen Grüße!Web-Server: http-Anfrage aus dem Stream

Ich habe mit C# (wieder) herumalbern und jetzt bin ich mit einfachen HTTP-Webserver-Implementierung stecken geblieben. Ehrlich gesagt, möchte ich nicht mit HTTP-Spezifikation auskommen - ich muss nur eine sehr kleine winzige (lesen Sie als einfache) HTTP-Webserver. Und ich habe dieses Problem gefördert: Client sendet Anfrage an den Server und dann Server analysiert es, führt einige Aktionen, baut Antwort und sendet es zurück an den Client. Das scheint (zumindest für mich) offensichtlich zu sein.

Hier ist, was ich bisher habe:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Net; 
using System.Net.Sockets; 
using System.IO; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      TcpListener listener = new TcpListener(IPAddress.Any, 80); 
      listener.Start(); 

      Socket sock = listener.AcceptSocket(); 

      try 
      { 
       Stream s = new NetworkStream(sock); 
       s.ReadTimeout = 300; 

       StreamReader reader = new StreamReader(s); 
       StreamWriter writer = new StreamWriter(s); 
       writer.AutoFlush = true; 

       Console.WriteLine("Client stream read:\r\n"); 

       string str = "none"; 

       while (sock.Connected && !reader.EndOfStream && str.Length > 0) // here's where i'm stuck 
       { 
        str = reader.ReadLine(); 
        Console.WriteLine("{0} ({1})", str, str.Length); 
       } 

       Console.WriteLine("Sending response...\r\n"); 

       { 
        string response = "<h1>404: Page Not Found</h1>"; 
        writer.WriteLine("HTTP/1.1 404 Not Found"); 
        writer.WriteLine("Content-Type: text/html; charset=utf-8"); 
        writer.WriteLine("Content-Length: {0}", response.Length); 
        writer.WriteLine("\r\n{0}", response); 
       } 

       Console.WriteLine("Client: over\r\n"); 

       s.Close(); 
       sock.Close(); 
      } 
      catch (Exception e) 
      { 
       Console.WriteLine("Exception: {0}\r\nTrace: \r\n{1}", e.Message, e.StackTrace); 
      } 

      Console.ReadKey(); 
     } 
    } 
} 

Aber ich habe einen „Unterwasser-Stein“ erfüllt werden: i Anfrage über den Eingangsstrom gerade lese, so Eingangsdatenfluss, wenn Client schließt beendet werden Seite in seinem Browser (lassen Sie uns über die offensichtlichsten Aktionen sprechen, ausgenommen Curl, W3 und andere "Geek-Zeug").

So ist die Frage: wie Anfrage 'Ende zu bestimmen? Z.B. Wann sollte ich aufhören, Anforderungsdaten zu lesen und die Antwort zu senden?

+0

Warum verwenden Sie nicht 'HttpListener'? – SLaks

+0

, weil es in einigen Windows-Versionen nicht unterstützt wurde. – shybovycha

Antwort

1

This Wikipedia article erklärt ziemlich prägnant über das Format der Anfrage Nachricht.

Die Anforderungsleitung und Header müssen alle mit <CR> < LF Ende > (das heißt, ein Wagenrücklauf durch einen Zeilenvorschub). Die Leerzeile darf nur aus <CR> > LF > bestehen. Im HTTP/1.1-Protokoll sind alle Header außer Host optional.

Grundsätzlich achten Sie auf eine leere Zeile nach den Headern und/oder einem potenziellen Nachrichtentext.

Nach dem HTTP specification, können Sie bestimmte Header verwenden, um zu bestimmen, ob es einen Nachrichtentext ist:

Das Vorhandensein einer Nachricht Körper in einer Anforderung durch die Aufnahme eines Content-Length signalisiert wird, oder Transfer-Encoding-Header-Feld in den Message-Headern der Anfrage.

+0

Hmm ... Ja, ich suche jetzt nach '\ r \ n'. Aber wie könnte ich mit dem Nachrichtentext umgehen? – shybovycha

+0

Ich habe meine Antwort aktualisiert, um das ein bisschen mehr zu erklären. –

2

Warum nicht HttpListener verwenden? Sie können einen einfachen HTTP-Server in 5 Zeilen Code haben.

+0

Kann an einigen Stellen eine gute Idee sein, aber wir konzentrieren uns nicht nur auf ein paar Plattformen, oder? =) – shybovycha

+0

Versuchen Sie zu sagen, dass Sie Plattformen vor Windows XP SP2 unterstützen müssen? Wenn Sie wirklich Cross-Plattform wollen, dann wäre vielleicht Kajak-Server eine gute Option. http://kayakhttp.com/ –

0

Eine weitere Möglichkeit ist diese: http://webserver.codeplex.com/ auch wenn Sie es nicht verwenden möchten, können Sie Ideen gestohlen hat, weil es die komplette Anfrage Lifecycle implementiert.

Verwandte Themen