編寫一個簡單的Web Server其實是輕而易舉的。如果我們只是想托管一些HTML頁面,我們可以這么實現:
在VS2013中創建一個C# 控制台程序
編寫一個字符串擴展方法類,主要用於在URL中截取文件名
ExtensionMethods.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace webserver1 { /// <summary> /// 一些有用的字符串擴展方法 /// </summary> public static class ExtensionMethods { /// <summary> /// 返回給定字符串左側的字串或是整個源字符串 /// </summary> /// <param name="src">源字符串</param> /// <param name="s">對比字符串</param> /// <returns></returns> public static string LeftOf(this String src, string s) { string ret = src; int idx = src.IndexOf(s); if (idx != -1) { ret = src.Substring(0, idx); } return ret; } /// <summary> /// 返回給定字符串右側的字串或是整個源字符串 /// </summary> /// <param name="src">源字符串</param> /// <param name="s">對比字符串</param> /// <returns></returns> public static string RightOf(this String src, string s) { string ret = String.Empty; int idx = src.IndexOf(s); if (idx != -1) { ret = src.Substring(idx + s.Length); } return ret; } } }
在入口程序中開啟HTTP監聽
Program.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Threading; using System.Net; using System.IO; namespace webserver1 { class Program { static Semaphore sem; static void Main(string[] args) { //支持模擬20個連接 sem = new Semaphore(20, 20); HttpListener listener = new HttpListener(); string url = "http://localhost/"; listener.Prefixes.Add(url); listener.Start(); Task.Run(() => { while (true) { sem.WaitOne(); StartConnectionListener(listener); } }); Console.WriteLine("點擊任意鍵,退出WebServer"); Console.ReadLine(); } static async void StartConnectionListener(HttpListener listener) { // 等待連接。 HttpListenerContext context = await listener.GetContextAsync(); //釋放信號器,另外一個監聽器可以立刻開啟 sem.Release(); //獲得請求對象 HttpListenerRequest request = context.Request; HttpListenerResponse response = context.Response; // 在URL路徑上截取文件名稱, 介於 "/" 和 "?"之間 string path = request.RawUrl.LeftOf("?").RightOf("/"); Console.WriteLine(path); //輸出一些內容 try { // 加載文件並以UTF-8的編碼返回 string text = File.ReadAllText(path); byte[] data = Encoding.UTF8.GetBytes(text); response.ContentType = "text/html"; response.ContentLength64 = data.Length; response.OutputStream.Write(data, 0, data.Length); response.ContentEncoding = Encoding.UTF8; response.StatusCode = 200; response.OutputStream.Close(); } catch (Exception ex) { Console.WriteLine(ex.Message); } } } }
上面的代碼初始化了20個監聽器。 采用信號器(Semaphore),當一個請求收到后,釋放一個信號器,一個新的監聽器再次被創建。這個服務器可以同時接收20個請求。使用await機制來處理線程是否繼續運行。如果你不熟悉Task、async/await的使用,建議參考一些文檔。
創建一個HTML文件,並把屬性{復制到輸入目錄}設置為 “如果較新則復制”
index.html
<html> <head> <title>Simple WebServer</title> </head> <body> <p>Hello World</p> </body> </html>
整個目錄結構
運行控制台程序,在瀏覽器中輸入地址:
http://localhost/index.html
如果瀏覽器無法訪問localhost,編輯C:\Windows\System32\drivers\etc\hosts文件,保證有一條這樣的記錄
127.0.0.1 localhost