編寫一個簡單的Web Server實際上是垂手可得的。若是咱們只是想託管一些HTML頁面,咱們能夠這麼實現:html
在VS2013中建立一個C# 控制檯程序web
編寫一個字符串擴展方法類,主要用於在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監聽async
Program.csthis
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文件,並把屬性{複製到輸入目錄}設置爲 「若是較新則複製」url
index.htmlspa
<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