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); } } }