c# HttpServer 的使用
在很多的时候,我们写的应用程序需要提供一个信息说明或者告示功能,希望借助于HttpServer来发布一个简单的网站功能,但是又不想架一个臃肿的Http服务器功能,
这时候,标准框架提供的HttpServer功能或许是我们的选择。
一引入using System.Net;
二开始服务
1 public class ServerHelper 2 { 3 HttpListener httpListener = new HttpListener(); 4 public void Setup(int port=8080) 5 { 6 httpListener.AuthenticationSchemes = AuthenticationSchemes.Anonymous; 7 httpListener.Prefixes.Add(string.Format("http://*:{0}/",port));//如果发送到8080 端口没有被处理,则这里全部受理,+是全部接收 8 httpListener.Start();//开启服务 9 10 Receive();//异步接收请求 11 } 12 13 private void Receive() 14 { 15 httpListener.BeginGetContext(new AsyncCallback(EndReceive), null); 16 } 17 18 void EndReceive(IAsyncResult ar) 19 { 20 var context = httpListener.EndGetContext(ar); 21 Dispather(context);//解析请求 22 Receive(); 23 } 24 25 RequestHelper RequestHelper; 26 ResponseHelper ResponseHelper; 27 void Dispather(HttpListenerContext context) 28 { 29 HttpListenerRequest request= context.Request; 30 HttpListenerResponse response = context.Response; 31 RequestHelper = new RequestHelper(request); 32 ResponseHelper = new ResponseHelper(response); 33 RequestHelper.DispatchResources(fs => { 34 ResponseHelper.WriteToClient(fs);// 对相应的请求做出回应 35 }); 36 } 37 }
三解析请求
1 public class RequestHelper 2 { 3 private HttpListenerRequest request; 4 public RequestHelper(HttpListenerRequest request) 5 { 6 this.request = request; 7 } 8 public Stream RequestStream { get; set; } 9 public void ExtracHeader() 10 { 11 RequestStream= request.InputStream; 12 } 13 14 public delegate void ExecutingDispatch(FileStream fs); 15 public void DispatchResources(ExecutingDispatch action) 16 { 17 var rawUrl = request.RawUrl;//资源默认放在执行程序的wwwroot文件下,默认文档为index.html 18 string filePath = string.Format(@"{0}/wwwroot{1}", Environment.CurrentDirectory, rawUrl);//这里对应请求其他类型资源,如图片,文本等 19 if (rawUrl.Length==1) 20 filePath = string.Format(@"{0}/wwwroot/index.html", Environment.CurrentDirectory);//默认访问文件 21 try { 22 if (File.Exists(filePath)) 23 { 24 FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite); 25 26 action?.Invoke(fs); 27 28 } 29 } 30 catch { return; } 31 } 32 public void ResponseQuerys() 33 { 34 var querys = request.QueryString; 35 foreach (string key in querys.AllKeys) 36 { 37 VarityQuerys(key,querys[key]); 38 } 39 } 40 41 private void VarityQuerys(string key,string value) 42 { 43 switch(key) 44 { 45 case "pic":Pictures(value); break; 46 case "text":Texts(value); break; 47 default:Defaults(value); break; 48 } 49 } 50 51 private void Pictures(string id) 52 { 53 54 } 55 56 private void Texts(string id) 57 { 58 59 } 60 61 private void Defaults(string id) 62 { 63 64 } 65 66 }
四回应请求
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进行简单的测试,简单的进行请求和回应的梳理,对于想要复杂的浏览器功能,需要详细的研究下其他浏览器的工作原理