编写一个简单的Web Server

编写一个简单的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

 代码下载

原文地址:https://www.cnblogs.com/lilunjia/p/7001686.html