2023年3月17日 星期五

利用 HttpListener 建立 Simple HTTP Server

 使用 C# 的 System.Net 其 HttpListener 類別建立一個 Simple HTTP Server 的筆記。


建立伺服器


要用 HttpListener 建立伺服器,可使用 Visual Studio 的 Console Application 來撰寫:

HttpListener server = new HttpListener();
server.Prefixes.Add("http://127.0.0.1:2222/");
server.Prefixes.Add("http://localhost:2222/");

server.Start();
即啟動伺服器

權限問題


建立伺服器後,欲啟動必須要使用管理員權限,建議可以先離開 Visual Studio 再以管理員權限重開。

伺服器文字回傳


啟動伺服器後,要針對所有的請求做回應,於是需要加入無限迴圈等待:
while (true)
{
    HttpListenerContext context = server.GetContext();
    HttpListenerResponse response = context.Response;
}

要回應時,在迴圈裡面加入將文字轉 stream 物件丟回去:
while (true)
{
    HttpListenerContext context = server.GetContext();
    HttpListenerResponse response = context.Response;

    //中文回傳測試
    StringBuilder builder = new StringBuilder("中文測試");
    string something = builder.ToString();
    byte[] buffer = Encoding.UTF8.GetBytes(something);
    response.ContentLength64 = buffer.Length;
    Stream st = response.OutputStream;
    st.Write(buffer, 0, buffer.Length);
    context.Response.Close();
}


檔案伺服器


伺服器回傳亦可使用檔案,則將迴圈中的回傳改為:

while (true)
{
    HttpListenerContext context = server.GetContext();
    HttpListenerResponse response = context.Response;

    string page = Directory.GetCurrentDirectory() + context.Request.Url.LocalPath;

    if (page == string.Empty)
        page = "index.html";

    TextReader tr = new StreamReader(page);
    string msg = tr.ReadToEnd();

    byte[] buffer = Encoding.UTF8.GetBytes(msg);

    response.ContentLength64 = buffer.Length;
    Stream st = response.OutputStream;
    st.Write(buffer, 0, buffer.Length);

    context.Response.Close();
}

請求字串


要獲得 Query (GET Parameter) 之類的參數,則可以使用以下方法來獲得:


Console.WriteLine(context.Request.QueryString.Get("test"));
//http://localhost:2222/theme?test=1


其他程式碼: 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//must to use
using System.Net;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
HttpListener server = new HttpListener();
server.Prefixes.Add("http://127.0.0.1:2222/");
server.Prefixes.Add("http://localhost:2222/");
server.Start();
Console.WriteLine("Listening...");
while (true)
{
HttpListenerContext context = server.GetContext();
HttpListenerResponse response = context.Response;
string page = Directory.GetCurrentDirectory() + context.Request.Url.LocalPath;
Console.WriteLine(context.Request.Url.LocalPath);
if (page == string.Empty)
page = "index.html";
StringBuilder builder;
switch (context.Request.Url.LocalPath) {
case "/":
builder = new StringBuilder("<!DOCTYPE html><html><head><title>測試</title><meta charset=\"utf-8\"></head><body>中文測試</body></html>");
break;
case "/readTheme":
Console.WriteLine(context.Request.QueryString.Get("test"));
builder = new StringBuilder("<!DOCTYPE html><html><head><title>測試</title><meta charset=\"utf-8\"></head><body>中文測試</body></html>");
break;
default:
builder = new StringBuilder("<!DOCTYPE html><html><head><title>測試</title><meta charset=\"utf-8\"></head><body>中文測試</body></html>");
break;
}
string something = builder.ToString();
byte[] buffer = Encoding.UTF8.GetBytes(something);
response.ContentLength64 = buffer.Length;
Stream st = response.OutputStream;
st.Write(buffer, 0, buffer.Length);
context.Response.Close();
}
}
}
}



Reference:
http://www.codingvision.net/networking/c-simple-http-server

資料來源:https://www.prochainsci.com/2018/04/c-httplistener-simple-http-server.html

沒有留言: