• C#实现一个简单的HTTP服务器


    用到的类主要有HttpListener、StreamWriter.

    HttpListener:使用HttpListener可创建响应 HTTP
    请求的简单 HTTP
    协议侦听器。实际上HttpListener只是实现了服务器端Socket上面的一个简单封装类。通过设置Prefixes属性来进行侦听,如,侦听器绑定到http或https端点的URL(如下代码).侦听器默认是绑定到运行在http的80端口和https的443的端口,并允许匿名和无身份验证的客户端访问。可以使用HttpListener类的属性Prefixes来制定自定义url和端口,并通过设置属性AuthenticationSchemes属性来配置身份验证。

     建立HttpListener后,执行Start(执行是Start实际上是引发底层的Bind和Listener),就开始处理客服端输入请求。HttpListener中GetContext和套接字的Accept类似,它在没有请求准备好处理的时候处于被阻塞状态。GetContext返回一个对象HttpListenerContext。HttpListenerContext对象的属性Request属性提供了许多关于客户机的一些请求信息.Response则返回一个HttpListerResponse对象,该对象可以用来响应客户机的请求。

     

    代码如下:

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Text;
     4 
     5 using System.Net;
     6 using System.Net.Sockets;
     7 using System.IO;
     8 
     9 namespace ConsoleHttpEchoServer
    10 {
    11   class Program
    12   {
    13   static void Main(string[] args)
    14   {
    15   using (HttpListener listerner = new HttpListener())
    16   {
    17   listerner.AuthenticationSchemes = AuthenticationSchemes.Anonymous;//指定身份验证 Anonymous匿名访问
    18   listerner.Prefixes.Add("http://localhost:8080/web/");
    19 
    20   // listerner.Prefixes.Add("http://localhost/web/");
    21   listerner.Start();
    22   Console.WriteLine("WebServer Start Successed.......");
    23   while (true)
    24   {
    25   //等待请求连接
    26   //没有请求则GetContext处于阻塞状态
    27   HttpListenerContext ctx = listerner.GetContext();
    28   ctx.Response.StatusCode = 200;//设置返回给客服端http状态代码
    29   string name = ctx.Request.QueryString["name"];
    30 
    31   if (name != null)
    32   {
    33   Console.WriteLine(name);
    34   }
    35 
    36 
    37   //使用Writer输出http响应代码
    38   using (StreamWriter writer = new StreamWriter(ctx.Response.OutputStream))
    39   {
    40   Console.WriteLine("hello");
    41   writer.WriteLine("<html><head><title>The WebServer Test</title></head><body>");
    42   writer.WriteLine("<div style=\"height:20px;color:blue;text-align:center;\"><p> hello {0}</p></div>", name);
    43   writer.WriteLine("<ul>");
    44 
    45   foreach (string header in ctx.Request.Headers.Keys)
    46   {
    47   writer.WriteLine("<li><b>{0}:</b>{1}</li>", header, ctx.Request.Headers[header]);
    48    
    49   }
    50   writer.WriteLine("</ul>");
    51   writer.WriteLine("</body></html>");
    52 
    53   writer.Close();
    54   ctx.Response.Close();
    55   }
    56 
    57   }
    58   listerner.Stop();
    59   }
    60   }
    61   }
    62 }

    在浏览器 中输入 http://localhost:8080/web/?name=test或
    http://localhost/web/?name=test,在浏览器就会出现Hello test
    和一些Request头部相关信息.


    备注:

    1.URI 前缀字符串由方案(http 或
    https)、主机、可选端口和可选路径组成。完整前缀字符串的示例为“http://www.contoso.com:8080/customerData/”。前缀必须以正斜杠(“/”)结尾。带有与所请求的
    URI 最近似匹配的前缀的 HttpListener 对象响应请求。多个 HttpListener 对象不能添加同一前缀;如果 HttpListener
    添加已经使用的前缀,将引发Win32Exception 异常。

     

    2.如果指定了端口,主机元素可以被替换为“*”,以指示如果请求的
    URI 与任何其他前缀都不匹配,则 HttpListener 接受发送到该端口的请求。例如,当任何 HttpListener 都不处理请求的 URI
    时,若要接收发送到端口 8080 的所有请求,前缀应为“http://*:8080/”。同样,若要指定 HttpListener
    接受发送到端口的所有请求,请将主机元素替换为“+”字符,即“https://+:8080”。“*”和“+”字符可出现在包含路径的前缀中。




    3.AuthenticationSchemes枚举类有以下值



     
    Anonymous:默认值,允许任意的客户机进行连接,不需要身份验证。

     
    Basic:要求提供纯文本(64位编码)用户名和密码来进行验证。

     
    Digest:类似与基本身份验证,但是用户名和密码使用一个简单密码散列进行传输。

      Ntlm: 指定 NTLM
    身份验证(只有IE支持)。

      IntegratedWindowsAuthentication:指定Windows身份验证。

     
    Negotiate: 和客户端协商以确定身份验证方案。如果客户端和服务器均支持 Kerberos,则使用 Kerberos;否则使用
    Ntlm

    None:不进行身份验证。

  • 相关阅读:
    无声购票弹窗
    C#多线程与异步的区别
    关于adb驱动
    事务日志初探(二)---简单恢复模式
    预写式日志(Write-Ahead Logging (WAL))
    如果正确读取SQL Server中的扩展事件?
    索引初探(三)
    事务日志还原的次意外的操作失误
    索引初探(二)
    索引的初探(一)
  • 原文地址:https://www.cnblogs.com/lyghost/p/2712050.html
Copyright © 2020-2023  润新知