最近项目上遇到一个需求,最后想到的解决方案是自己实现一个web服务器去处理请求,然后再将信息发送到另外一个程序。然后返回处理之后的结果呈现出来。
现在我就来分享一下如何实现的。
通过.NET 为我们提供的HttpListener类实现对Http协议的处理,实现简单的web服务器。
注意:此类在 .NET Framework 2.0 版中是新增的。所以支持.NET Framework 2.0以上版本。该类仅在运行 Windows XP SP2 或 Windows Server 2003 操作系统的计算机上可用。
引用命名空间:using System.Net;
使用Http服务一般步骤如下:
-
创建一个HTTP侦听器对象并初始化
-
开始侦听来自客户端的请求
-
处理客户端的Http请求
-
关闭HTTP侦听器
创建一个HTTP侦听器对象
创建HTTP侦听器对象只需要新建一个HttpListener对象即可。
1
|
HttpListener listener = new HttpListener(); |
初始化需要经过如下两步
- 添加需要监听的URL范围至listener.Prefixes中,可以通过如下函数实现:
1 - 调用listener.Start()实现端口的绑定,并开始监听客户端的需求。
侦听来自客户端的请求
这里有2种方式可以侦听HTTP请求,获取HttpListenerContext的最简单方式如下:
1
|
HttpListenerContext context = listener.GetContext(); |
该方法将阻塞调用函数至接收到一个客户端请求为止,如果要提高响应速度,可使用异步方法listener.BeginGetContext()来实现HttpListenerContext对象的获取。
我使用的是异步方式实现对HttpListenerContext对象的获取。
处理客户端的HTTP请求
获取HttpListenerContext后,可通过Request属性获取表示客户端请求的对象,通过Response属性取表示 HttpListener 将要发送到客户端的响应的对象。
1
2
|
HttpListenerRequest request = context.Request; HttpListenerResponse response = context.Response; |
关闭HTTP侦听器
通过调用listener.Stop()函数即可关闭侦听器,并释放相关资源
实现GET POST请求处理
GET请求比较简单,直接通过 request.QueryString["linezero"]; QueryString就可以实现获取参数。
POST请求由于HttpListener 不提供实现,需要自己做处理。在下面相关代码中会贴出方法。
相关代码:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.IO; namespace WebConsole { class Program { static HttpListener sSocket; static void Main(string[] args) { sSocket = new HttpListener(); sSocket.Prefixes.Add("http://127.0.0.1:8080/"); sSocket.Start(); sSocket.BeginGetContext(new AsyncCallback(GetContextCallBack), sSocket); Console.WriteLine("已启动监听,访问http://127.0.0.1:8080/"); Console.ReadKey(); } static void GetContextCallBack(IAsyncResult ar) { try { sSocket = ar.AsyncState as HttpListener; HttpListenerContext context = sSocket.EndGetContext(ar); //再次监听请求 sSocket.BeginGetContext(new AsyncCallback(GetContextCallBack), sSocket); //处理请求 string a = Request(context.Request); //输出请求 Response(context.Response, a); } catch { } } /// <summary> /// 处理输入参数 /// </summary> /// <param name="request"></param> /// <returns></returns> static string Request(HttpListenerRequest request) { string temp = "welcome to linezero!"; if (request.HttpMethod.ToLower().Equals("get")) { //GET请求处理 if (!string.IsNullOrEmpty(request.QueryString["linezero"])) temp = request.QueryString["linezero"]; } else if (request.HttpMethod.ToLower().Equals("post")) { //这是在POST请求时必须传参的判断默认注释掉 //if (!request.HasEntityBody) //{ // temp = "请传入参数"; // return temp; //} //POST请求处理 Stream SourceStream = request.InputStream; byte[] currentChunk = ReadLineAsBytes(SourceStream); //获取数据中有空白符需要去掉,输出的就是post请求的参数字符串 如:username=linezero temp = Encoding.Default.GetString(currentChunk).Replace("", ""); } return temp; } static byte[] ReadLineAsBytes(Stream SourceStream) { var resultStream = new MemoryStream(); while (true) { int data = SourceStream.ReadByte(); resultStream.WriteByte((byte)data); if (data <= 10) break; } resultStream.Position = 0; byte[] dataBytes = new byte[resultStream.Length]; resultStream.Read(dataBytes, 0, dataBytes.Length); return dataBytes; } /// <summary> /// 输出方法 /// </summary> /// <param name="response">response对象</param> /// <param name="responseString">输出值</param> /// <param name="contenttype">输出类型默认为json</param> static void Response(HttpListenerResponse response, string responsestring, string contenttype = "application/json") { response.StatusCode = 200; response.ContentType = contenttype; response.ContentEncoding = Encoding.UTF8; byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responsestring); //对客户端输出相应信息. response.ContentLength64 = buffer.Length; System.IO.Stream output = response.OutputStream; output.Write(buffer, 0, buffer.Length); //关闭输出流,释放相应资源 output.Close(); } } }
最后启动程序,在地址栏里输入http://127.0.0.1:8080 就可以访问了。