C#網絡編程入門之HTTP


一、概述

本文目的是通過C#代碼提供一個HTTP服務,正常情況下如果我們需要向外界提供HTTP服務,常規做法就是通過ASP.NET來實現,有時我們的應用程序或Windows服務需要向外提供一些簡單的HTTP服務就可以自己實現,從而避免部署IIS增加系統復雜性。這里必須強調是一些簡單的應用,如果應用比較復雜,涉及到路徑解析HTML解析等,還是用WEB方式實現比較靠譜。

將HTTP和UDP、TCP放在同一個系列實際上有一點不合適,因為UDP、TCP屬於傳輸層協議,HTTP屬於應用層協議,希望讀者首先有一個明確的了解。

 

二、 提供服務

首先啟動HHTP服務:

            if (!HttpListener.IsSupported)
            {
                Console.WriteLine("服務器操作系統不支持建立Http Server,需要更高版本的操作系統!");
                return;
            }

            HttpListener httpListener = new HttpListener();

            try
            {
                Console.WriteLine("正在啟動Http服務");
                int port = 9000;
                httpListener.Prefixes.Add($"http://*:{port}/");
                httpListener.Start();               
                Console.WriteLine("Http服務啟動成功。");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"啟動Http服務出現異常:{ex.Message}");
                return;
            }

進行監聽:

            while (true)
            {
                Console.WriteLine("開始監聽...");
                HttpListenerContext context = httpListener.GetContext();
                HttpListenerRequest request = context.Request;

                string Method = request.HttpMethod.ToUpper();
                Console.WriteLine($"收到請求,URL:{ request.Url} Method:{Method}");               

                Response(context, "hello");
            }

代碼循環進行監聽,GetContext方法會引起阻塞,當收到瀏覽器請求時,服務器立即返回“Hello”。

Response方法實現如下:

        private static void Response(HttpListenerContext context, string responseTxt)
        {
            HttpListenerResponse response = context.Response;
            response.ContentType = "html";
            response.ContentEncoding = Encoding.UTF8;

            using (Stream output = response.OutputStream)
            {
                byte[] buffer2 = Encoding.UTF8.GetBytes(responseTxt);
                output.Write(buffer2, 0, buffer2.Length);
            }
        }

此時打開瀏覽器輸入地址 http://localhosthost:9000/ 看一下能否看到結果。(如果需要通過其他機器訪問,本機要開放防火牆對應端口。)

注意:程序需要以管理員模型運行才能提供服務。

具體辦法:工程新增應用程序清單文件:app.manifest,修改配置信息如下:

  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">

    <security>

      <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">       

        <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />

      </requestedPrivileges>

    </security>

  </trustInfo>

 

三、 響應

通過request.HttpMethod可以取得協議類型,對於GET和POST方法將采取不同的處理方式。

通過request.RawUrl可以取得URL路徑,並進行解析,通過request.QueryString可以用戶輸入的參數值。

             if (Method == "GET")
                {
                    Console.WriteLine($"Get:RawURL:{ request.RawUrl}");

                    if (request.RawUrl.StartsWith("/version"))
                    {
                        Response(context, "Simple Http Server Ver:0.11");
                        continue;
                    }
                    else
                    {
                        string username = request.QueryString["username"];
                        string pwd = request.QueryString["pwd"];

                        Response(context, $"Welcome:{username}");
                        continue;
                    }
                }

以上代碼,如果輸入:http://localhost:9000?username=hahaha

輸出:Welcome:hahaha

在POST方法下,仍然可以通過request.QueryString取得用戶通過URL輸入的參數,但通過Body傳輸的數據需要通過其他方式進行讀取。

                if (Method == "POST")
                {
                    Console.WriteLine($"POST:RawURL:{ request.RawUrl}");
                    string content = GetPostInput(request);
                    Console.WriteLine($"Content:{ content}");
                   Response(context, "\"{'Result':'Success','Message':'Hello'}\"");
                   continue;
                }

GetPostInput方法實現如下:

        private static string GetPostInput(HttpListenerRequest request)
        {
           Stream s = request.InputStream;
            int count = 0;
            byte[] buffer = new byte[1024];
            StringBuilder builder = new StringBuilder();
            while ((count = s.Read(buffer, 0, 1024)) > 0)
            {
                builder.Append(Encoding.UTF8.GetString(buffer, 0, count));
            }
            s.Flush();
            s.Close();
            s.Dispose();
            return builder.ToString();
        }

為了方便起見,輸入輸出的數據最好采用json格式。

 

四、調試

可以通過Chrome或Postman來進行調試。 

 

傳送門:

C#網絡編程入門系列包括三篇文章:

(一)C#網絡編程入門之UDP

(二)C#網絡編程入門之TCP

(三)C#網絡編程入門之HTTP


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM