zoukankan      html  css  js  c++  java
  • 自己实现简单Web服务器,支持GET POST请求

    最近项目上遇到一个需求,最后想到的解决方案是自己实现一个web服务器去处理请求,然后再将信息发送到另外一个程序。然后返回处理之后的结果呈现出来。

    现在我就来分享一下如何实现的。

    通过.NET 为我们提供的HttpListener类实现对Http协议的处理,实现简单的web服务器。

    注意:此类在 .NET Framework 2.0 版中是新增的。所以支持.NET Framework 2.0以上版本。该类仅在运行 Windows XP SP2 或 Windows Server 2003 操作系统的计算机上可用。

    引用命名空间:using System.Net;

    使用Http服务一般步骤如下:

    1. 创建一个HTTP侦听器对象并初始化
    2. 开始侦听来自客户端的请求
    3. 处理客户端的Http请求
    4. 关闭HTTP侦听器

    创建一个HTTP侦听器对象

    创建HTTP侦听器对象只需要新建一个HttpListener对象即可。

    1
    HttpListener listener = new HttpListener();

      

    初始化需要经过如下两步

      1. 添加需要监听的URL范围至listener.Prefixes中,可以通过如下函数实现:
        1
        listener.Prefixes.Add("http://127.0.0.1:8080/")    //必须以'/'结尾
        多个的话可以采用循环添加。
      2. 调用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 就可以访问了。

  • 相关阅读:
    TSQL笔记4:表
    C#笔记26: 与非托管代码交互操作
    C#笔记22:多线程之停止或取消线程
    C#笔记25:比较和排序(IComparable和IComparer以及它们的泛型实现)
    TSQL笔记7:临时表和表变量
    TSQL笔记6:GO
    WPF快速指导9:WPF中的属性(依赖项属性)
    TSQL笔记2:INSERT、UPDATE和DELETE
    C#笔记23:多线程之Task(并行编程)
    云计算读书笔记(一)
  • 原文地址:https://www.cnblogs.com/armyfai/p/3862379.html
Copyright © 2011-2022 走看看