2011-01-17 22 views
1

Greetings!Webサーバー:ストリームからHTTP要求を読み取る

私はC#(もう一度)で騙されていましたが、今は単純なHTTP Webサーバーの実装に苦しんでいます。正直なところ、私はHTTPの仕様に慣れたくないです - ちょうど小文字をシンプルと読む)と書く必要があります。そして私はこの問題を奨励しました。クライアントはサーバーに要求を送信し、サーバーはそれを解析し、いくつかのアクションを実行し、応答を作成してクライアントに返します。それは明らかです(私にとっては少なくとも)。

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(); 
     } 
    } 
} 

をしかし、私は「水中の石」会った:ときにクライアントに近い私は、入力ストリームを経由して要求を読んでいるので、入力データフローが終了する。ここ

は私がこれまで持っているものです彼のブラウザのページ(curl、w3、およびその他の「geek-stuff」を除いて、最も明白なアクションについて話しましょう)。

質問:リクエストの終了を判断する方法は?例えば。リクエストデータの読み取りを停止してレスポンスを送信する必要がありますか?

+0

なぜ 'HttpListener'を使用しないのですか? – SLaks

+0

'Windowsのバージョンによってはサポートされていないものがあります – shybovycha

答えて

1

This Wikipedia articleは、リクエストメッセージの形式についてかなり簡潔に説明しています。

リクエスト行とヘッダーは、すべての(すなわち、ラインフィードに続くキャリッジリターンである)<CR> <LF>で終わらなければなりません。空行は、<CR> <LF>のみで構成され、他の空白は含まれていない必要があります。 HTTP/1.1プロトコルでは、ホストを除くすべてのヘッダーはオプションです。

基本的には、ヘッダーや潜在的なメッセージ本文の後に空白行がないかどうかを確認してください。

HTTP specification

によると、メッセージ本体が存在するかどうかを決定するために特定のヘッダを使用することができるが:

要求内のメッセージボディの存在はコンテンツ長を含めることによって合図またはさ要求のメッセージヘッダーのTransfer-Encodingヘッダーフィールド。

+0

うーん...ええ、私は今、 '\ r \ n'を探しています。しかし、私はどのようにメッセージ本文を扱うことができますか? – shybovycha

+0

私はもう少し説明するために私の答えを更新しました。 –

2

なぜHttpListenerを使用しないのですか?単純なHTTPサーバーを5行のコードにまとめることができます。

+0

いくつかの場所では良いアイデアかもしれませんが、私たちはいくつかのプラットフォームに集中していませんか? =) – shybovycha

+0

Windows XP SP2以前のプラットフォームをサポートする必要があるとお考えですか?あなたが本当にクロスプラットフォームを望むなら、おそらくカヤックサーバーは良い選択肢になるでしょう。 http://kayakhttp.com/ –

0

別のオプションは、このいずれかになります。 http://webserver.codeplex.com/ あなたがそれを使用しない場合でも、あなたがアイデアを盗んだことができ、それは完全な要求のライフサイクルを実装しているため。

関連する問題