zoukankan      html  css  js  c++  java
  • c# 自己制作一个httpserver

    根据网友的代码稍加改编完善

    httpserverbase.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    
    namespace HttpServer
    {
        // HTTP服务类
        public abstract class HttpServerBase : IDisposable
        {
            private readonly HttpListener _listener;                        // HTTP 协议侦听器
            private readonly Thread _listenerThread;                        // 监听线程
            private readonly Thread[] _workers;                             // 工作线程组
            private readonly ManualResetEvent _stop, _ready;                // 通知停止、就绪
            private Queue<HttpListenerContext> _queue;                      // 请求队列
            private event Action<HttpListenerContext> ProcessRequest;       // 请求处理委托
    
            public HttpServerBase(int maxThreads)
            {
                _workers = new Thread[maxThreads];
                _queue = new Queue<HttpListenerContext>();
                _stop = new ManualResetEvent(false);
                _ready = new ManualResetEvent(false);
                _listener = new HttpListener();
                _listenerThread = new Thread(HandleRequests);
            }
    
            public void Start(int port)
            {
                // 注册处理函数
                ProcessRequest += ProcessHttpRequest;
    
                // 启动Http服务
                _listener.Prefixes.Add(String.Format("http://*:{0}/", port));
                _listener.Start();
                _listenerThread.Start();
    
                // 启动工作线程
                for (int i = 0; i < _workers.Length; i++)
                {
                    _workers[i] = new Thread(Worker);
                    _workers[i].Start();
                }
            }
    
            // 请求处理函数
            protected abstract void ProcessHttpRequest(HttpListenerContext ctx);
    
            // 释放资源
            public void Dispose()
            {
                Stop();
            }
    
            // 停止服务
            public void Stop()
            {
                _stop.Set();
                _listenerThread.Join();
                foreach (Thread worker in _workers)
                {
                    worker.Join();
                }
                _listener.Stop();
            }
    
            // 处理请求
            private void HandleRequests()
            {
                while (_listener.IsListening)
                {
                    var context = _listener.BeginGetContext(ContextReady, null);
                    if (0 == WaitHandle.WaitAny(new[] { _stop, context.AsyncWaitHandle }))
                    {
                        return;
                    }
                }
            }
    
            // 请求就绪加入队列
            private void ContextReady(IAsyncResult ar)
            {
                try
                {
                    lock (_queue)
                    {
                        _queue.Enqueue(_listener.EndGetContext(ar));
                        _ready.Set();
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(string.Format("[HttpServerBase::ContextReady]err:{0}", e.Message));
                }
            }
    
            // 处理一个任务
            private void Worker()
            {
                WaitHandle[] wait = new[] { _ready, _stop };
                while (0 == WaitHandle.WaitAny(wait))
                {
                    HttpListenerContext context;
                    lock (_queue)
                    {
                        if (_queue.Count > 0)
                            context = _queue.Dequeue();
                        else
                        {
                            _ready.Reset();
                            continue;
                        }
                    }
    
                    try
                    {
                        ProcessRequest(context);
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(string.Format("[HttpServerBase::Worker]err:{0}", e.Message));
                    }
                }
            }
        }
    
    }
    

      

    httpserver.cs

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Net;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace HttpServer
    {
        class MyHttpServer : HttpServerBase
        {
            public MyHttpServer(int maxThreads) : base(maxThreads)
            { }
    
            protected override void ProcessHttpRequest(HttpListenerContext context)
            {
                string RootDir = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase+"www";//根目录
                string requestFileName = RootDir + context.Request.RawUrl;
                if(!System.IO.File.Exists(requestFileName))
                {
                    context.Response.StatusCode = 404;
                    context.Response.Close();
                    return;
                }
                using (var fs = new FileStream(requestFileName, FileMode.Open, FileAccess.Read))
                {
                    byte[] buffer = new byte[fs.Length];
                    //这次读取实际读到的字节数
                    int r = fs.Read(buffer, 0, buffer.Length);
                    context.Response.StatusCode = 200;
                    context.Response.ContentLength64 = buffer.Length;
                    context.Response.OutputStream.Write(buffer, 0, buffer.Length);
                    context.Response.OutputStream.Close();
                    context.Response.Close();
                }
                   
            }
        }
    
    }

    form1.cs

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace HttpServer
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                int port = 80;
                MyHttpServer httpServer = new MyHttpServer(10);
                httpServer.Start(port);
            }
        }
    }
  • 相关阅读:
    elementUI使用el-tabs时有个坑
    滚动条滚动到指定位置(锚点)的不同实现方式
    elementUI组件 el-checkbox 的值格式问题
    前端常见面试题(七)ajax
    this指向 以及 call、apply、bind的使用和区别
    vue 项目目录解释
    vue-lic
    vue 网络请求 axios
    vue 状态管理 vuex
    keep-alive+vue 路由 (vue-router)
  • 原文地址:https://www.cnblogs.com/chinamyqq/p/15307059.html
Copyright © 2011-2022 走看看