编写一个简单的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:WindowsSystem32driversetchosts文件,保证有一条这样的记录
127.0.0.1 localhost