编写一个简单的Web Server

时间:2024-04-14 23:37:39

编写一个简单的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 != -) { ret = src.Substring(, 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 != -) {
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(, ); 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, , data.Length);
response.ContentEncoding = Encoding.UTF8; response.StatusCode = ; 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>

整个目录结构

编写一个简单的Web Server

运行控制台程序,在浏览器中输入地址:

http://localhost/index.html

  编写一个简单的Web Server

如果浏览器无法访问localhost,编辑C:\Windows\System32\drivers\etc\hosts文件,保证有一条这样的记录

127.0.0.1 localhost

代码下载