在很多的時候,我們寫的應用程序需要提供一個信息說明或者告示功能,希望借助於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進行簡單的測試,簡單的進行請求和回應的梳理,對於想要復雜的瀏覽器功能,需要詳細的研究下其他瀏覽器的工作原理