C#使用HttpListener构建一个简易的Http服务器

这个博客展示了如何使用C#创建一个简单的HTTP监听服务器,处理GET和POST请求。服务器初始化在8080端口,能响应不同的URL路径,如获取、删除、编辑和查询操作,并返回JSON格式的数据。此外,还处理了文件请求。
摘要由CSDN通过智能技术生成

调用

using System;
using System.Threading.Tasks;
using Demo.Services;
using Microsoft.Extensions.Hosting;

namespace Demo
{
    internal static class Program
    {
        public async static Task Main(string[] args)
        {
            FrameWorkInfoService.InitWebServer(8080);
            Console.WriteLine("监听的端口:8080");

            // 监听 Ctrl + C
            await new HostBuilder().RunConsoleAsync();
        }
    }
}

创建

using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;

using Demo.EFCore;
using Demo.Model;
using Demo.MyExtensions;
using Demo.Utils;

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace Demo.Services
{
    public static class FrameWorkInfoService
    {
        /// <summary>
        /// 初始化 简易web服务器
        /// </summary>
        /// <exception cref="Exception"></exception>
        public static void InitWebServer(int port)
        {
            var listener = new HttpListener();
            
            // 出现"访问拒绝"错误,则需要使用"管理员权限"打开IDE 或 运行程序
            listener.Prefixes.Add($"http://*:{port}/");
            
            listener.Start();

            listener.BeginGetContext(ListenerHandle, null);

            void ListenerHandle(IAsyncResult result)
            {
                if (listener.IsListening)
                {
                	//继续处理下一个请求
                    listener.BeginGetContext(ListenerHandle, null);
                    
                    var context = listener.EndGetContext(result);
                    
                    //解析Request请求
                    var request = context.Request;
                    var response = context.Response;

                    response.KeepAlive = true;

					// 将要返回的内容与状态码
                    object resultData = string.Empty;
                    var resultCode = HttpStatusCode.OK;

					// 获取请求类型"POST","GET" 等等 (此处转成了小写字母)
                    var httpMethod = request.HttpMethod.ToLower();
                    // 查询 "域名/IP" 与 "?" 之间的内容
                    var actionName = request.Url?.AbsolutePath;
                    // 查询地址中"?"后面的键值对
                    var queryString = request.QueryString;

                    try
                    {
                        switch (actionName)
                        {
                            case "/getMessageByFrameWorkId" when httpMethod is "get":
                            
                                resultData = R.Success(GetMessageByFrameWorkId(Convert.ToInt32(queryString.Get("id"))));
                                break;
                                
                            case "/run" when httpMethod is "get":
                            
                                CheckFromGithub(true);
                                resultData = R.Success("执行完毕");
                                break;
                                
                            case "/addOrEdit" when httpMethod is "post":
                            
                            	// 读取post的内容
                                var content = new StreamReader(context.Request.InputStream, Encoding.UTF8).ReadToEnd();
                                // 转为json对象
                                var data = JsonConvert.DeserializeObject<JObject>(content);
                                if (data != null)
                                {
                                	// 读取
                                    var id = Convert.ToInt32(data["id"]); // 如果为空,转int32结果为0           
                                    var name = data["name"]?.ToString();
                                    var url = data["url"]?.ToString();

                                    var (state, errorMsg) = AddOrEditFrameWorkInfo(id, name, url);
                                    if (state)
                                    {
                                        resultData = R.Success();
                                    }
                                    else
                                    {
                                        throw new Exception(errorMsg);
                                    }
                                }
                                break;
                                
                            case "/" when httpMethod is "delete":
                            
                                resultData = R.Success(DeleteFrameWorkById(Convert.ToInt32(queryString.Get("id"))));
                                break;
                                
                            case "/" when httpMethod is "get":

                                response.ContentType = "text/html;charset=UTF-8";
                                resultData = File.ReadAllText("./View/index.html");
                                break;
                                
                            case "/getFrameWorks" when httpMethod is "get":
                            
                                resultData = R.Success(GetFrameWorks(
                                        Convert.ToInt32(queryString.Get("index")),
                                        Convert.ToInt32(queryString.Get("size"))
                                    )
                                );
                                break;
                                
                            default:
                            
                            	//请求的是文件类型, (文件一定要在IDE中设置"复制到输出目录-->始终复制")
                                var filePath = $"./View{actionName}";
                                if (new FileInfo(filePath).Exists)
                                {
                                    if (actionName.Contains(".js"))
                                    {
                                        response.ContentType = "application/javascript; charset=utf-8";
                                    }

                                    resultCode = HttpStatusCode.OK;
                                    resultData = File.ReadAllText(filePath);
                                }
                                else
                                {
                                	// 返回 404
                                    resultCode = HttpStatusCode.NotFound;
                                }
                                break;
                        }
                    }
                    catch (Exception e)
                    {
                    	// 捕获异常,并统一格式后返回给前端
                        Console.WriteLine(e);
                        resultData = R.Error(e.Message);
                    }

                    // 设置 返回内容 与 code
                    response.StatusCode = (int)resultCode;
                    using var writer = new StreamWriter(response.OutputStream, Encoding.UTF8);
                    writer.Write(resultData);
                }
            }
        }

		// 方法例子
        public static PagedList<Message> GetMessageByFrameWorkId(int id){}
        public static bool DeleteFrameWorkById(int id){}
        public static PagedList<FrameWorkInfo> GetFrameWorks(int pageIndex = 1, int pageSize = 20){}
        public static (bool, string) AddOrEditFrameWorkInfo(int? id, string name, string url){}
        public static void CheckFromGithub(bool force = false){}
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值