【C# & WebService】【3】使用HttpListener搭建简易版的Http服务器

新建一个Server对象

使用HttpListener搭建一个简单的Http服务器。用来方便设置调试第三方API时,没有服务器可以通讯的状况。
HttpListener提供了一个简单的、可通过编程方式控制的 HTTP 协议侦听器,可以监听通过Prefixes属性指定的端口。通过方法GetContext()获取传入的HTTP请求。

class HttpServer
{
    private const string BaseUrl = "http://+:5008/"; //监听所有IP的5008端口
    private static readonly HttpListener listener = new HttpListener();

    public static void Start()
    {
        listener.Prefixes.Add(BaseUrl);
        //listener.Prefixes.Add("http://+:80/");  
        //listener.Prefixes.Add("https://localhost:443/"); // 监听本地回环地址的443端口 
      

        listener.Start();
        //开始监听,并打印显示所有当前被监听的端口和IP
        Console.WriteLine("Listening...");
        foreach (string prefix in listener.Prefixes)
        {
            Console.WriteLine(prefix);
        }

		//在一个新的任务中异步处理阻塞请求,
        Task.Run(() =>
        {
            while (listener.IsListening)
            {
                var context = listener.GetContext(); //阻塞方式获取传入的HTTP请求的上下文
                //异步地处理每个请求。它读取请求信息,设置响应的内容类型,并将响应写入输出流
                Task.Run(() => ProcessRequestAsync(context));
            }
        });
    }

    private static async Task ProcessRequestAsync(HttpListenerContext context)
    {
        HttpListenerRequest request = context.Request;
        HttpListenerResponse response = context.Response;
        string responseString = "";
		//打印请求体的详细信息。
        Console.WriteLine($"\r\n ******* Date:{System.DateTime.Now} ******* \r\n"+
                          $"    HttpMethod : {request.HttpMethod}\r\n" +
                          $"  AbsolutePath : {request.Url.AbsolutePath}\r\n" + 
                          $"   ContentType : {request.ContentType}\r\n"+
                          $" ContentLength : {request.ContentLength64}"
                          );


        // 处理GET请求的方法处理  
        if (request.HttpMethod == "GET")
        {
            //提取路由地址
            string url = request.Url.AbsolutePath;
            switch (url)
            {
                case "/yoshi/exi/me/bobcat":
                    {
                        //设置响应的数据类型和编码格式
                        response.ContentType = "text/plain";
                        response.ContentEncoding = Encoding.UTF8;

                        //解析查询字符串的参数
                        var queryString = request.QueryString;
                        var queryParams = new Dictionary<string, string>();
                        foreach (string key in queryString.AllKeys)
                        {
                            queryParams[key] = queryString[key];
                        }

                        //打印查询字符串的所有参数和值
                        Console.WriteLine($"GET Request Received. Query Parameters: \r\n {string.Join(", ", queryParams.Select(q => $"{q.Key}={q.Value}"))}");
                    }
                    break;
                default:
                    response.StatusCode = 404;
                    responseString = "{\"error\": \"Not found\"}";
                    break;

            }

            //回复请求的响应
            if (!string.IsNullOrEmpty(responseString))
            {
                byte[] buffer = Encoding.UTF8.GetBytes(responseString);
                response.ContentLength64 = buffer.Length;
                Stream output = response.OutputStream;
                await output.WriteAsync(buffer, 0, buffer.Length);
            }
        }
        else if (request.HttpMethod == "POST")
        {
            // 处理POST请求
            string requestBody = "";
            using (Stream requestStream = request.InputStream)
            {
                using (StreamReader reader = new StreamReader(requestStream, Encoding.UTF8))
                {
                    string requestBodyAsync = await reader.ReadToEndAsync();

                    //打印请求体的数据信息 
                    Console.WriteLine($"POST Request Received. Body: {requestBodyAsync}");

                    if (string.IsNullOrEmpty(requestBodyAsync) || string.IsNullOrWhiteSpace(requestBodyAsync))
                    {
                        response.StatusCode = 404;
                        responseString = "{\"error\": \"Bad Request\"}";
                    }
                    else
                    {
                        requestBody = requestBodyAsync;
                    }
                }
            }


            //提取路由地址
            string url = request.Url.AbsolutePath;
            
            switch (url)
            {
                case "/v5/capture/errordata":
                    {
                        //判断数据是否可以正确转换为Json格式
                        if(false)
                        {
                            response.StatusCode = 404;
                            responseString = "{\"error\": \"Bad Request\"}";
                        }
                        break;
                    }
                case "/v5/capture/machinestate":
                case "/v5/capture/machinedata":
                case "/v5/capture/environmentaldata":
                    responseString = "{\"status\": \"OK\", \"data\": \"Some data\"}";
                    break;
                default:
                    response.StatusCode = 404;
                    responseString = "{\"error\": \"Not found\"}";
                    break;
            }

            // 写入响应数据
            if (!string.IsNullOrEmpty(responseString))
            {
                byte[] buffer = Encoding.UTF8.GetBytes(responseString);
                response.ContentLength64 = buffer.Length;
                Stream output = response.OutputStream;
                await output.WriteAsync(buffer, 0, buffer.Length);
            }
        }
        else
        {
            // 非GET或POST方法回复405 Method Not Allowed  
            response.StatusCode = 405;
            response.StatusDescription = "Method Not Allowed";
        }

        // 关闭响应数据流  
        response.OutputStream.Close();
    }

    public static void Stop()
    {
        listener.Close();
    }
}

使用测试HttpServer

新建一个控制台应用程序,演示Http服务器的使用。

class Program
{
    static void Main(string[] args)
    {
        HttpServer.Start();

        Console.WriteLine("Press Enter to quit the server...");
        Console.ReadLine();

        HttpServer.Stop();
    }
}

参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值