.NET TIPS

簡易Webサーバを実装するには?[2.0のみ、C#、VB]

デジタルアドバンテージ 遠藤 孝信
2008/01/17

 .NET Framework 2.0のクラス・ライブラリには、HTTPリクエストに応答可能なHttpListenerクラス(System.Net名前空間)が用意されており、このクラスを使えば簡単にアプリケーションにWebサーバの機能を実装できる。

 本稿では非常に簡易なWebサーバを作成して、HttpListenerクラスの基本的な利用方法を示す。

簡易Webサーバを実装したサンプル・プログラム

 ここではまず、HttpListenerクラスを使って実装した簡易Webサーバのサンプル・プログラムのソース・コードを示す。

 このサンプル・プログラムを使用するには、あらかじめc:\wwwrootディレクトリ配下にHTMLファイルを配置しておく必要がある。例えばindex.htmlを配置した場合には、「http://localhost/index.html」あるいは「http://<マシン名>/index.html」*としてブラウザからアクセスできる。

* 別のPCからアクセスする場合にはWindowsファイアウォールで80番ポートを開いておく必要がある。

// webserver.cs

using System;
using System.IO;
using System.Net;

class SimpleWebServer
{
  static void Main()
  {
    string root = @"c:\wwwroot\"; // ドキュメント・ルート
    string prefix = "http://*/"; // 受け付けるURL

    HttpListener listener = new HttpListener();
    listener.Prefixes.Add(prefix); // プレフィックスの登録
    listener.Start();

    while (true) {
      HttpListenerContext context = listener.GetContext();
      HttpListenerRequest req = context.Request;
      HttpListenerResponse res = context.Response;

      Console.WriteLine(req.RawUrl);

      // リクエストされたURLからファイルのパスを求める
      string path = root + req.RawUrl.Replace("/", "\\");

      // ファイルが存在すればレスポンス・ストリームに書き出す
      if (File.Exists(path)) {
        byte[] content = File.ReadAllBytes(path);
        res.OutputStream.Write(content, 0, content.Length);
      }
      res.Close();
    }
  }
}

// コンパイル方法:csc webserver.cs
簡易Webサーバを実装したC#のサンプル・プログラム(webserver.cs)

' webserver.vb

Imports System
Imports System.IO
Imports System.Net

Class SimpleWebServer
  Shared Sub Main()
    Dim root As String = "c:\wwwroot\" ' ドキュメント・ルート
    Dim prefix As String = "http://*/" ' 受け付けるURL

    Dim listener As New HttpListener()
    listener.Prefixes.Add(prefix) ' プレフィックスの登録
    listener.Start()

    While (True)
      Dim context As HttpListenerContext = listener.GetContext()
      Dim req As HttpListenerRequest = context.Request
      Dim res As HttpListenerResponse = context.Response

      Console.WriteLine(req.RawUrl)

      ' リクエストされたURLからファイルのパスを求める
      Dim path As String = root & req.RawUrl.Replace("/", "\\")

      ' ファイルが存在すればレスポンス・ストリームに書き出す
      If File.Exists(path) Then
        Dim content() As Byte = File.ReadAllBytes(path)
        res.OutputStream.Write(content, 0, content.Length)
      End If

      res.Close()
    End While
  End Sub
End Class

' コンパイル方法:vbc webserver.vb
簡易Webサーバを実装したVBのサンプル・プログラム(webserver.vb)

 HttpListenerクラスを使用してWebサーバを実装する場合の基本的な流れは次のようになる。

  1. HttpListenerクラスをインスタンス化する
  2. 応答するプレフィックスの登録する
  3. Startメソッドを呼び出して処理を開始する
  4. GetContextメソッドを呼び出してリクエストを待つ
  5. リクエストが来たら、そのURLに応じたファイルを出力する

 2のプレフィックスとは、リクエストを受け入れるURLのパターンであり、すべてのリクエストを受け入れるには「http://*/」としておけばよい。ポート番号を80番以外にする場合には、「http://*:8080/」(8080番の場合)といった具合に指定する。

 Startメソッドの呼び出し後、実際にリクエストを受け取るにはGetContextメソッドを呼び出す。上記のサンプル・プログラムでは無限ループを行っているが、GetContextメソッドはリクエストが来るまで(=ブラウザによりアクセスされるまで)待つので、見かけ上、プログラムはそこで停止することになる。

 リクエストが来るとGetContextメソッドは、その内容をHttpListenerContextクラス(System.Net名前空間)のオブジェクトとして返す。このHttpListenerContextオブジェクトからは、ブラウザからのリクエストを表すHttpListenerRequestクラスと、ブラウザに返すレスポンスを表すHttpListenerResponseクラスのオブジェクトにアクセスできる(どちらもSystem.Net名前空間)。

 そして、HttpListenerRequestオブジェクトのRawUrlプロパティからは、リクエストされたURLからドメイン名を除いた部分が取得できる(例えば「/images/title.gif」など)。サンプル・プログラムでは、この文字列内の「/」を「\」に置き換えて、レスポンスとして返すファイルのパス名を求めている。

 レスポンスとしてブラウザに対して出力する内容は、いま求めたパス名のファイルの内容を、HttpListenerResponseオブジェクトのOutputStreamプロパティから得られるストリーム(System.IO名前空間のStreamオブジェクト)に書き込めばよい。

 ちなみに、上記のサンプル・プログラムではループ内でリクエストを1つ1つ処理しているが、一般的なWebサーバではリクエストが到着したら別スレッドにその処理を振り分けることにより、多くのリクエストを並列に処理して応答性を高めていることが多い。

 なお、HttpListenerクラスはWindows XP SP2あるいはWindows Server 2003でしか使用できない(筆者が試した限りではWindows Vistaでも使用可能)。現在の環境で使用できるかどうかは、HttpListenerクラスの静的プロパティであるIsSupportedプロパティでチェックできる。End of Article

利用可能バージョン:.NET Framework 2.0のみ
カテゴリ:クラス・ライブラリ 処理対象:ネットワーク
使用ライブラリ:HttpListenerクラス(System.Net名前空間)
使用ライブラリ:HttpListenerContextクラス(System.Net名前空間)
使用ライブラリ:HttpListenerRequestクラス(System.Net名前空間)

この記事と関連性の高い別の.NET TIPS
WebRequest/WebResponseクラスでWebページを取得するには?
[ASP.NET]任意の画像を出力してブラウザで表示するには?
HTTPステータス・コードを取得しWebページの存在を確認するには?
WebClientクラスでWebページを取得するには?
このリストは、(株)デジタルアドバンテージが開発した
自動関連記事探索システム Jigsaw(ジグソー) により自動抽出したものです。
generated by

「.NET TIPS」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間