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進行簡單的測試,簡單的進行請求和回應的梳理,對於想要復雜的瀏覽器功能,需要詳細的研究下其他瀏覽器的工作原理

