本身實現簡單Web服務器,支持GET POST請求

最近項目上遇到一個需求,最後想到的解決方案是本身實現一個web服務器去處理請求,而後再將信息發送到另一個程序。而後返回處理以後的結果呈現出來。web

如今我就來分享一下如何實現的。json

 

經過.NET 爲咱們提供的HttpListener類實現對Http協議的處理,實現簡單的web服務器。服務器

注意:此類在 .NET Framework 2.0 版中是新增的。因此支持.NET Framework 2.0以上版本。該類僅在運行 Windows XP SP2 或 Windows Server 2003 操做系統的計算機上可用。app

引用命名空間:using System.Net;異步

使用Http服務通常步驟以下:ide

  1. 建立一個HTTP偵聽器對象並初始化
  2. 開始偵聽來自客戶端的請求
  3. 處理客戶端的Http請求
  4. 關閉HTTP偵聽器

建立一個HTTP偵聽器對象函數

建立HTTP偵聽器對象只須要新建一個HttpListener對象便可。post

HttpListener listener = new HttpListener();

  

初始化須要通過以下兩步spa

    1. 添加須要監聽的URL範圍至listener.Prefixes中,能夠經過以下函數實現:
      listener.Prefixes.Add("http://127.0.0.1:8080/")    //必須以'/'結尾
      多個的話能夠採用循環添加。
    2. 調用listener.Start()實現端口的綁定,並開始監聽客戶端的需求。

 

偵聽來自客戶端的請求操作系統

 這裏有2種方式能夠偵聽HTTP請求,獲取HttpListenerContext的最簡單方式以下:

HttpListenerContext context = listener.GetContext();

該方法將阻塞調用函數至接收到一個客戶端請求爲止,若是要提升響應速度,可以使用異步方法listener.BeginGetContext()來實現HttpListenerContext對象的獲取。

我使用的是異步方式實現對HttpListenerContext對象的獲取。

 

處理客戶端的HTTP請求

獲取HttpListenerContext後,可經過Request屬性獲取表示客戶端請求的對象,經過Response屬性取表示 HttpListener 將要發送到客戶端的響應的對象。

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();
        }
    }
}
View Code

 

 

 

最後啓動程序,在地址欄裏輸入http://127.0.0.1:8080 就能夠訪問了。

 

若是你以爲本文對你有幫助,請點擊「推薦」,謝謝。

相關文章
相關標籤/搜索