【C#】一個簡單的http服務器項目開發過程詳解

這跟安裝NoteJs程序運行腳本文件搭建一個簡單Http服務器一樣,相比起來,它的優點是可以開發的應用是免安裝,跨平臺的,放在移動盤上便捷的,這里著重講http服務器實現的過程,以便自主實現特定的功能和服務。

打開Visual Studio開發工具,創建一個項目,

注意,項目開發語言是C#,使用的Net framework 4+ 框架,

創建的項目可以是以下三種

  • Console 控制臺
  • WinForm 桌面程序
  • WPF 桌面程序

新建項目

這里以最簡單的Console控制臺項目開發為例,

新建項目,選一個項目來創建:控制臺應用(.NET Framework),如下圖

在這里插入圖片描述

編寫代碼

創建好一個項目后,在第一個代碼Program.cs文件中,

獲取本機IP

添加如下代碼如下,先獲取本機的IP列表

using System.Net;namespace ConsoleApp1
{class Program{static void Main(string[] args){var IPs = Dns.GetHostEntry(Dns.GetHostName()).AddressList.Where(ip => ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork && ip.ToString().EndsWith(".1") != true).Select(ip => ip.ToString()).ToList();//...}}
}

繼續寫,獲取第一個IP

var IP = IPs.FirstOrDefault();

啟用HTTP服務

接下來,實現一個Http服務器

var server = new HttpListener();
var url = $"http://{IP}:8080/";
server.Prefixes.Add(url);
server.Start();
Console.WriteLine("Http服務器已開啟,用瀏覽器訪問:" + url);

從上面代碼中可看出,先傳入IP和端口號,就可開啟一個Http服務

被拒絕訪問

可以試著編譯運行看,能否正常運行,

此時運行可會出現一個錯誤提示:拒絕訪問!

這就是觸及到網絡安全和權限問題了,有三種解決方案:

解決方案一

將IP換成’127.0.0.1’

缺點:只能本機訪問

解決方案二

以管理員身份運行程序

缺點:每次運行前都要授權:確認以管理員身份

解決方案三

在訪問控制規則中設置,

以管理員身份運行Shell終端(CMD),執行一條命令如下:

netsh http add urlacl url=http://{ip}:{port}/ user=Everyone

其中{ip}:{port} 換成自己的IP和端口號

這樣,下次運行程序就不會再次彈出拒絕訪問問題,

若想恢復,就執行一條命令,如下:

netsh http delete urlacl url=http://{ip}:{port}/

訪問首頁

那http服務器順利開啟后,

若要訪問頁面,那是看不到什么頁面內容的,

處理請求

需要自己實現,添加一行代碼如下

server.BeginGetContext((ar) => OnResult(server, ar), null);

從上面代碼看,當請求訪問它的時候,會調用那一個方法OnResult

實現那個方法OnResult,代碼如下

private static void OnResult(HttpListener server, IAsyncResult ar)
{if (!server.IsListening) return;var context = server.EndGetContext(ar);var request = context.Request;var response = context.Response;var method = request.HttpMethod.ToUpper();//...待實現if (server.IsListening) server.BeginGetContext((ar2)=>OnResult(server, ar2), null);
}

從上面代碼看,對寫過后端服務代碼的同學來說,就會覺得這很像服務器處理請求業務的邏輯

  • request 是處理請求的對象
  • response 是響應輸出的對象
  • method 是請求方法

在待實現那里,繼續添加代碼,

先判斷請求地址,添加代碼如下

var absUrl = HttpUtility.UrlDecode(request.Url.AbsolutePath);//request.RawUrl
if (absUrl=="/" || absUrl=="/index.html"){//...
}

從上面代碼看,判斷到地址是請求加載首頁的話,就去加載首頁文件

加載文件

把寫好的網頁文件index.html放到運行程序文件對應的文件夾wwwroot下,

然后實現,讀取本地文件內容,代碼如下

var filePath = System.IO.Path.Combine(Environment.CurrentDirectory, "wwwroot", "index.html");
var contents = System.IO.File.ReadAllText(filePath);
//...

響應內容

讀取到內容,將輸出給瀏覽器,代碼如下

response.ContentType = "text/html;charset=UTF-8";
response.AddHeader("Content-Type", "text/html");
using (var writer = new System.IO.StreamWriter(response.OutputStream))
{writer.Write(contents);
}

其中text/html,是表示文件內容類型,

注意,以上響應輸出方法只能處理符合條件text/*內容類型的文件,

其它文件類型的文件,需要另外的方法來實現處理請求響應,

輸出完成后,記得執行如下代碼,關閉響應

response.Close();

內容類型

網頁文件中還有加載的資源文件是比較常見的,它們的內容類型不一樣,如下表:

名稱文件后綴名內容類型
文本.txttext/plain
網頁.htmltext/html
網頁.htmtext/html
樣式.csstext/css
數據.jsonapplication/json
腳本.jsapplication/x-javascript
字體.ttfapplication/x-font-ttf
圖標.icoimage/x-icon
圖片.jpgimage/jpeg
圖片.jpegimage/jpeg

更多文件內容類型,這里就不多列舉了,如有需要請自行搜索

訪問請求數據

當瀏覽器訪問網頁后,網頁中有個資源標簽需要加載服務器資源文件,還有網頁腳本會請求訪問服務器的數據,

所有加載資源的請求方法通常是GET,

判斷請求方法

在之前的請求處理中,通過以下代碼能判斷

var method = request.HttpMethod.ToUpper();
if (method=="GET") {//...
} else if (method=="POST") {//...
}

處理GET請求

其中GET請求這里就不展開講,這實現很簡單吧,之前將加載網頁文件就是處理GET請求來的,

有的請求地址中會帶上查詢數據,同如下這樣

http://…com/q?csdn=zs1028

可判斷請求地址中的查詢部分,代碼如下

var query = request.QueryString;
//...

判斷請求地址里的查詢數據,再處理不同的請求響應

處理POST請求

是POST請求的話,通常會發來表單數據,

在請求處理中可以讀取表單數據,代碼如下:

// 檢查是否為 multipart/form-data
if (!request.ContentType.StartsWith("multipart/form-data", StringComparison.OrdinalIgnoreCase))
{throw new Exception("Only multipart/form-data is supported");
}var parser = new MultipartFormDataParser(request.InputStream);
//...

其中HttpMultipartParser是使用Nuget包管理器安裝的,當時是 2.1.7版本,
表單數據就在parser對象里,看里面有什么屬性,
例如,前端頁面操作上傳的文件,在請求處理中可從parser對象的屬性Files獲取

處理請求響應

處理完請求后,需要響應數據,

如果是返回文本內容,就執行以下代碼

response.AddHeader("Content-Type", "text/plain");var contents = "ok";
using (var writer = new System.IO.StreamWriter(response.OutputStream))
{writer.Write(contents);
}

如果返回JSON內容,就執行以下代碼

var result = new { code = 0, errMsg = "ok" };
response.AddHeader("Content-Type", "application/json");
var contents = new JavaScriptSerializer().Serialize(result);
using (var writer = new System.IO.StreamWriter(response.OutputStream))
{writer.Write(contents);
}

從代碼中看出,result就是object對象類型,可以轉換成json序列化數據

寫到這里,基本上就可以編譯運行測試了,

一個簡單HTTP服務器就這樣實現處理,是不是感覺很容易,它的應用場景可以多了,請自由想象!

對前端開發來說,可以把前端項目生成的網頁打包進一個程序中,輕松部署,再加上瀏覽器運行組件那就是跨平臺的程序。

就寫到這里,( _ )/~~拜拜
在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/83120.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/83120.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/83120.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

WPF【11_4】WPF實戰-重構與美化(MVVM 架構)

11-9 【理論】MVVM 架構 在 WPF 項目中,我們主要采用的是一種類似 MVC 的架構,叫做 MVVM。 MVVM 繼承了 MVC 的理念,是 Model-View-ViewModel 的縮寫,中文意思是模型、視圖、視圖模型。這三個詞分開看我們都能看懂,不…

使用PowerBI個人網關定時刷新數據

使用PowerBI個人網關定時刷新數據 PowerBI desktop連接mysql,可以設置定時刷新數據或在PowerBI服務中手動刷新數據,步驟如下: 第一步: 下載網關。以個人網關為例,如圖 第二步: 雙擊網關,點擊下一步&…

深度學習驅動的超高清圖修復技術——綜述

Deep Learning-Driven Ultra-High-Definition Image Restoration: A Survey Liyan Wang, Weixiang Zhou, Cong Wang, Kin-Man Lam, Zhixun Su, Jinshan Pan Abstract Ultra-high-definition (UHD) image restoration?? aims to specifically solve the problem of ??quali…

3 分鐘學會使用 Puppeteer 將 HTML 轉 PDF

需求背景 1、網頁存檔與文檔管理 需要將網頁內容長期保存或歸檔為PDF,確保內容不被篡改或丟失,適用于法律文檔、合同、技術文檔等場景。PDF格式便于存儲和檢索。 2、電子報告生成 動態生成的HTML內容(如數據分析報告、儀表盤)需導出為PDF供下載或打印。PDF保留排版和樣…

電子郵箱設置SSL:構建郵件傳輸的加密護城河

在數字化通信高度依賴的今天,電子郵件作為企業協作與個人隱私的核心載體,其安全性直接關系到數據主權與商業利益。SSL(Secure Sockets Layer)作為網絡通信加密的基石技術,通過為郵件傳輸建立加密隧道,有效抵…

Qt -使用OpenCV得到SDF

博客主頁:【夜泉_ly】 本文專欄:【暫無】 歡迎點贊👍收藏?關注?? 目錄 cv::MatdistanceTransform獲得SDF 本文的目標, 是簡單學習并使用OpenCV的相關函數, 并獲得QImage的SDF(Signed Distance Field 有向距離場) 至…

Compose仿微信底部導航欄NavigationBar :底部導航控制滑動并移動

文章目錄 1、準備工作1.1 參考1.2 依賴添加:1.3 主要控件NavigationBarHorizontalPager、VerticalPager 2、功能描述:3、實現過程3.1 創建一個數據類3.2 創建一個list變量3.3 具體實現3.3.1 創建共享的Pager狀態3.3.2 將頁面索引與頁面標題同步3.3.3 創建…

WindowServer2022下docker方式安裝dify步驟

WindowServer2022下docker方式安裝dify步驟(穩定后考慮部署至linux中) 教程:https://blog.csdn.net/qq_49035156/article/details/143264534 0、資源要求 ---windows:8核CPU、16G內存、200G500G存儲 ---10.21.31.122/administra…

【數據治理】要點整理-信息技術數據質量評價指標-GB/T36344-2018

導讀:指標為數據質量評估提供了一套系統化、標準化的框架,涵蓋規范性、完整性、準確性、一致性、時效性、可訪問性六大核心指標,助力組織提升數據處理效率、支持決策制定及業務流程優化,確保數據在數據生存周期各階段的質量可控。…

前端實現圖片壓縮:基于 HTML5 File API 與 Canvas 的完整方案

在 Web 開發中,處理用戶上傳的圖片時,前端壓縮可以有效減少服務器壓力并提升上傳效率。本文將詳細講解如何通過<input type="file">實現圖片上傳,結合 Canvas 實現圖片壓縮,并實時展示壓縮前后的圖片預覽和文件大小對比。 一、核心功能架構 我們將實現以…

通信算法之280:無人機偵測模塊知識框架思維導圖

1. 無人機偵測模塊知識框架思維導圖, 見文末章節。 2. OFDM參數估計,基于循環自相關特性。 3. 無人機其它參數估計

單片機寄存器的四種主要類型!

1. 控制寄存器&#xff08;Control Registers&#xff09;?? ??專業定義??&#xff1a;用于配置硬件行為或觸發操作的寄存器。 ??大白話??&#xff1a; 相當于設備的??“控制面板”??&#xff0c;通過寫入特定值來??開關功能??或??調整參數??。例如&am…

第100+41步 ChatGPT學習:R語言實現誤判病例分析

本期是《第33步 機器學習分類實戰&#xff1a;誤判病例分析》的R版本。 嘗試使用Deepseek-R1來試試寫代碼&#xff0c;效果還不錯。 下面上R語言代碼&#xff0c;以Xgboost為例&#xff1a; # 加載必要的庫 library(caret) library(pROC) library(ggplot2) library(xgboost)…

HTML Day04

Day04 0.引言1. HTML字符實體2. HTML表單2.1 表單標簽2.2 表單示例 3. HTML框架4. HTML顏色4.1 16進制表示法4.2 rgba表示法4.3 名稱表達法 5. HTML腳本 0.引言 剛剛回顧了前面幾篇博客&#xff0c;感覺寫的內容倒是很詳細&#xff0c;每個知識點都做了說明。但是感覺在知識組織…

comfyui 工作流中 視頻長度和哪些參數有關? 生成15秒的視頻,再加上RTX4060 8G顯卡,嘗試一下

想再消費級顯卡上生成15秒長視頻&#xff0c;還是比較慢的&#xff0c;不過動漫的畫質要求比較低 在ComfyUI中生成15秒視頻需綜合考慮視頻參數配置、模型選擇和硬件優化&#xff0c;尤其針對RTX 4060 8G顯存的限制。 ?? 一、影響視頻長度的核心參數 總幀數&#xff08;video_…

Netty 實戰篇:構建高性能聊天服務器

在前兩篇文章中&#xff0c;我們深入探討了 Netty 的 IO 模型以及其核心組件的工作原理。本篇文章將通過一個實際的聊天服務器示例&#xff0c;展示如何使用 Netty 構建高性能的網絡應用。 一、項目結構 項目主要包含以下幾個部分&#xff1a; ChatServer&#xff1a;服務器啟…

智紳科技——科技賦能健康養老,構建智慧晚年新生態

當老齡化浪潮與數字技術深度碰撞&#xff0c;智紳科技以 “科技賦能健康&#xff0c;智慧守護晚年” 為核心理念&#xff0c;錨定數字健康與養老服務賽道&#xff0c;通過人工智能、物聯網、大數據等技術集成&#xff0c;為亞健康群體與中老年人群構建 “監測 - 預防 - 輔助 - …

Tkinter軟件——顯示txt標簽的目標水平邊框圖像

代碼&#xff1a; import tkinter as tk from tkinter import filedialog from tkinter import messagebox import cv2 from PIL import Image, ImageTk import osclass ImageBoxApp:def __init__(self, master):self.master masterself.master.title("Image Box Drawer…

Linux 文件覆蓋機制與實踐:以 mv 命令為切入點

引言&#xff1a;文件覆蓋的本質 文件覆蓋是 Linux 文件系統中常見的操作&#xff0c;指的是在目標路徑已存在文件的情況下&#xff0c;將源文件的內容寫入目標文件&#xff0c;導致目標文件的原有內容被替換。在 Linux 中&#xff0c;文件覆蓋通常通過命令行工具&#xff08;…

學習路之PHP--easyswoole操作數據庫

學習路之PHP--easyswoole操作數據庫 0、安裝orm插件一、創建數據庫二、創建模型三、控制器顯示四、效果五、問題 0、安裝orm插件 composer require easyswoole/orm一、創建數據庫 表&#xff1a; CREATE TABLE cases (id int(11) NOT NULL AUTO_INCREMENT COMMENT 主鍵,titl…