08
2019
12

c# HttpServer 的使用

在很多的时候,我们写的应用程序需要提供一个信息说明或者告示功能,希望借助于HttpServer来发布一个简单的网站功能,但是又不想架一个臃肿的Http服务器功能,

这时候,标准框架提供的HttpServer功能或许是我们的选择。

一引入using System.Net;

二开始服务

public class ServerHelper
    {
        HttpListener httpListener = new HttpListener();
        public void Setup(int port=8080)
        {            
            httpListener.AuthenticationSchemes = AuthenticationSchemes.Anonymous;
            httpListener.Prefixes.Add(string.Format("http://*:{0}/",port));//如果发送到8080 端口没有被处理,则这里全部受理,+是全部接收
            httpListener.Start();//开启服务

            Receive();//异步接收请求
        }

        private void Receive()
        {
            httpListener.BeginGetContext(new AsyncCallback(EndReceive), null);
        }

        void EndReceive(IAsyncResult ar)
        {
            var context = httpListener.EndGetContext(ar);
            Dispather(context);//解析请求
            Receive();
        }

        RequestHelper RequestHelper;
        ResponseHelper ResponseHelper;
        void Dispather(HttpListenerContext context)
        {
            HttpListenerRequest request= context.Request;
            HttpListenerResponse response = context.Response;
            RequestHelper = new RequestHelper(request);
            ResponseHelper = new ResponseHelper(response);
            RequestHelper.DispatchResources(fs => {
                ResponseHelper.WriteToClient(fs);// 对相应的请求做出回应
            });
        }
    }

三解析请求

public class RequestHelper
    {
        private HttpListenerRequest request;
        public RequestHelper(HttpListenerRequest request)
        {
            this.request = request;
        }
        public Stream RequestStream { get; set; }
        public void ExtracHeader()
        {
            RequestStream= request.InputStream;
        }

        public delegate void ExecutingDispatch(FileStream fs);
        public void DispatchResources(ExecutingDispatch action)
        {
            var rawUrl = request.RawUrl;//资源默认放在执行程序的wwwroot文件下,默认文档为index.html
            string filePath = string.Format(@"{0}/wwwroot{1}", Environment.CurrentDirectory, rawUrl);//这里对应请求其他类型资源,如图片,文本等
            if (rawUrl.Length==1)
               filePath = string.Format(@"{0}/wwwroot/index.html", Environment.CurrentDirectory);//默认访问文件
            try {
            if (File.Exists(filePath))
            {
                    FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite);
                
                    action?.Invoke(fs);
                
            }
            }
            catch { return; }
        }
        public void ResponseQuerys()
        {
            var querys = request.QueryString;
            foreach (string key in querys.AllKeys)
            {
                VarityQuerys(key,querys[key]);
            }
        }

        private void VarityQuerys(string key,string value)
        {
            switch(key)
            {
                case "pic":Pictures(value); break;
                case "text":Texts(value); break;
                default:Defaults(value); break;
            }
        }

        private void Pictures(string id)
        {

        }

        private void Texts(string id)
        {

        }

        private void Defaults(string id)
        {

        }

    }

四回应请求

public class ResponseHelper
    {
        private HttpListenerResponse response;
        public ResponseHelper(HttpListenerResponse response)
        {
            this.response = response;
            OutputStream = response.OutputStream;
           
        }
        public Stream OutputStream { get; set; }
        public class FileObject
        {
            public FileStream fs;
            public byte[] buffer;
        }
        public void WriteToClient(FileStream fs)
        {
            response.StatusCode = 200;
            byte[] buffer = new byte[1024];
            FileObject obj = new FileObject() { fs = fs, buffer = buffer };      
            fs.BeginRead(buffer, 0, buffer.Length, new AsyncCallback(EndWrite), obj);
        }       
        void EndWrite(IAsyncResult ar)
        {
            var obj = ar.AsyncState as FileObject;
            var num= obj.fs.EndRead(ar);
            OutputStream.Write(obj.buffer,0,num);
            if (num < 1) { 
          obj.fs.Close(); //关闭文件流
          OutputStream.Close();//关闭输出流,如果不关闭,浏览器将一直在等待状态
           return; 
        }
            obj.fs.BeginRead(obj.buffer, 0, obj.buffer.Length, new AsyncCallback(EndWrite), obj);
        }
    }

测试结果:

准备的index.html,里面包含了图片和普通html

资源目录:

 

 

 浏览器进行访问测试:

总结:

本文只是对httpserver进行简单的测试,简单的进行请求和回应的梳理,对于想要复杂的浏览器功能,需要详细的研究下其他浏览器的工作原理

转自:https://www.cnblogs.com/yeshuimaowei/p/9193463.html

« 上一篇 下一篇 »

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。