用到的类主要有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:不进行身份验证。