2014年10月19日 星期日

自定一個 web server 來理解 HttpListener

建立一個 console 應用程式

namespace SampleWebServerApplication
{
    class Program
    {
        public static HttpListener listener = new HttpListener();
        // 把放這個應用程式所存放的路徑當成網站的根目錄 (Path using "System.IO")
        public static string startUpPath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
        static void Main(string[] args)
        {
            try
            {
                // 要監聽的URL範圍, 使用本機IP位置監聽
                listener.Prefixes.Add("http://localhost:8080/");
                // 開始監聽端口,接收客户端請求
                listener.Start();
                Console.WriteLine("Web Server Listening..");
 
                while (true)
                {
                    // 獲取一個客户端請求為止
                    HttpListenerContext context = listener.GetContext();
                    // 從執行緒池開一個新的執行緒去出處理客户端請求
                    System.Threading.ThreadPool.QueueUserWorkItem(ProcessRequest, context);
                }
            }
            catch (Exception e)
            {
 
                Console.WriteLine(e.Message);
            }
            finally
            {
                listener.Stop(); //關閉 HttpListener
                Console.WriteLine("Web Server Stop!");
            }
 
        }
        /// <summary>
        /// 客户請求處理
        /// </summary>
        /// <param name="listenerContext"></param>
        public static void ProcessRequest(object listenerContext)
        {
            try
            {
                var context = listenerContext as HttpListenerContext;
                string fileName = context.Request.RawUrl.Remove(01);
                string path = Path.Combine(startUpPath, fileName);
                byte[] msg;
                if (File.Exists(path)) // 目錄下有該檔案 (File using "System.IO")
                {
                    context.Response.StatusCode = (int)HttpStatusCode.OK;
                    // 開啟二進位檔案, 將檔案內容讀入位元組陣列, 然後關閉檔案
                    msg = File.ReadAllBytes(path);
                }
                else
                {
                    Console.WriteLine("找不到檔案! {0}", path);
                    context.Response.StatusCode = (int)HttpStatusCode.NotFound;
                    msg = File.ReadAllBytes(startUpPath + "\\error.html");
                }
                context.Response.ContentLength64 = msg.Length;
                using (Stream outputStream = context.Response.OutputStream)
                {
                    // 將檔案寫入到 response
                    outputStream.Write(msg, 0, msg.Length);
                    // outputStream.Close(); // 在 using 裡會自動 close 釋放資源
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }
    }
}

沒有留言: