• 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

  • 相关阅读:
    hibernate03增删改查
    hibernate02环境的搭建
    hibernate01ORM的引入
    20170623_oracle_优化与体系结构
    20170626_oracle_数据库设计
    logging模块
    hashlib模块
    json和pickle模块
    sys模块
    os模块
  • 原文地址:https://www.cnblogs.com/seabluescn/p/12972750.html
Copyright © 2020-2023  润新知