zoukankan      html  css  js  c++  java
  • 编写一个简单的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

     代码下载

  • 相关阅读:
    WCF中的序列化[下篇]
    WCF中的序列化[上篇]
    SET TRANSACTION ISOLATION LEVEL 详解
    深入探讨数据仓库建模与ETL的实践技巧
    用SQL语句添加删除修改字段等操作
    WCF数据契约与序列化
    在SQL Server中使用检查约束来验证数据
    C#线程同步的几种方法[转]
    Linq的Join用法
    测试wlm代码高亮插件
  • 原文地址:https://www.cnblogs.com/lilunjia/p/7001686.html
Copyright © 2011-2022 走看看