編寫一個簡單的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:\Windows\System32\drivers\etc\hosts文件,保證有一條這樣的記錄

127.0.0.1 localhost

 代碼下載


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM