c# 網(wǎng)絡(luò)編程之http
一、概述
本文目的是通過(guò)C#代碼提供一個(gè)HTTP服務(wù),正常情況下如果我們需要向外界提供HTTP服務(wù),常規(guī)做法就是通過(guò)ASP.NET來(lái)實(shí)現(xiàn),有時(shí)我們的應(yīng)用程序或Windows服務(wù)需要向外提供一些簡(jiǎn)單的HTTP服務(wù)就可以自己實(shí)現(xiàn),從而避免部署IIS增加系統(tǒng)復(fù)雜性。這里必須強(qiáng)調(diào)是一些簡(jiǎn)單的應(yīng)用,如果應(yīng)用比較復(fù)雜,涉及到路徑解析HTML解析等,還是用WEB方式實(shí)現(xiàn)比較靠譜。
將HTTP和UDP、TCP放在同一個(gè)系列實(shí)際上有一點(diǎn)不合適,因?yàn)閁DP、TCP屬于傳輸層協(xié)議,HTTP屬于應(yīng)用層協(xié)議,希望讀者首先有一個(gè)明確的了解。
二、 提供服務(wù)
首先啟動(dòng)HHTP服務(wù):
if (!HttpListener.IsSupported) { Console.WriteLine("服務(wù)器操作系統(tǒng)不支持建立Http Server,需要更高版本的操作系統(tǒng)!"); return; } HttpListener httpListener = new HttpListener(); try { Console.WriteLine("正在啟動(dòng)Http服務(wù)"); int port = 9000; httpListener.Prefixes.Add($"http://*:{port}/"); httpListener.Start(); Console.WriteLine("Http服務(wù)啟動(dòng)成功。"); } catch (Exception ex) { Console.WriteLine($"啟動(dòng)Http服務(wù)出現(xiàn)異常:{ex.Message}"); return; }
進(jìn)行監(jiān)聽(tīng):
while (true) { Console.WriteLine("開(kāi)始監(jiān)聽(tīng)..."); HttpListenerContext context = httpListener.GetContext(); HttpListenerRequest request = context.Request; string Method = request.HttpMethod.ToUpper(); Console.WriteLine($"收到請(qǐng)求,URL:{ request.Url} Method:{Method}"); Response(context, "hello"); }
代碼循環(huán)進(jìn)行監(jiān)聽(tīng),GetContext方法會(huì)引起阻塞,當(dāng)收到瀏覽器請(qǐng)求時(shí),服務(wù)器立即返回“Hello”。
Response方法實(shí)現(xiàn)如下:
private static void Response(HttpListenerContext context, string responseTxt) { HttpListenerResponse response = context.Response; response.ContentType = "html"; response.ContentEncoding = Encoding.UTF8; using (Stream output = response.OutputStream) { byte[] buffer2 = Encoding.UTF8.GetBytes(responseTxt); output.Write(buffer2, 0, buffer2.Length); } }
此時(shí)打開(kāi)瀏覽器輸入地址 http://localhosthost:9000/ 看一下能否看到結(jié)果。(如果需要通過(guò)其他機(jī)器訪問(wèn),本機(jī)要開(kāi)放防火墻對(duì)應(yīng)端口。)
注意:程序需要以管理員模型運(yùn)行才能提供服務(wù)。
具體辦法:工程新增應(yīng)用程序清單文件:app.manifest,修改配置信息如下:
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"> <security> <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3"> <requestedExecutionLevel level="requireAdministrator" uiAccess="false" /> </requestedPrivileges> </security> </trustInfo>
三、 響應(yīng)
通過(guò)request.HttpMethod可以取得協(xié)議類(lèi)型,對(duì)于GET和POST方法將采取不同的處理方式。
通過(guò)request.RawUrl可以取得URL路徑,并進(jìn)行解析,通過(guò)request.QueryString可以用戶輸入的參數(shù)值。
if (Method == "GET") { Console.WriteLine($"Get:RawURL:{ request.RawUrl}"); if (request.RawUrl.StartsWith("/version")) { Response(context, "Simple Http Server Ver:0.11"); continue; } else { string username = request.QueryString["username"]; string pwd = request.QueryString["pwd"]; Response(context, $"Welcome:{username}"); continue; } }
以上代碼,如果輸入:http://localhost:9000?username=hahaha
輸出:Welcome:hahaha
在POST方法下,仍然可以通過(guò)request.QueryString取得用戶通過(guò)URL輸入的參數(shù),但通過(guò)Body傳輸?shù)臄?shù)據(jù)需要通過(guò)其他方式進(jìn)行讀取。
if (Method == "POST") { Console.WriteLine($"POST:RawURL:{ request.RawUrl}"); string content = GetPostInput(request); Console.WriteLine($"Content:{ content}"); Response(context, "\"{'Result':'Success','Message':'Hello'}\""); continue; }
GetPostInput方法實(shí)現(xiàn)如下:
private static string GetPostInput(HttpListenerRequest request) { Stream s = request.InputStream; int count = 0; byte[] buffer = new byte[1024]; StringBuilder builder = new StringBuilder(); while ((count = s.Read(buffer, 0, 1024)) > 0) { builder.Append(Encoding.UTF8.GetString(buffer, 0, count)); } s.Flush(); s.Close(); s.Dispose(); return builder.ToString(); }
為了方便起見(jiàn),輸入輸出的數(shù)據(jù)最好采用json格式。
四、調(diào)試
可以通過(guò)Chrome或Postman來(lái)進(jìn)行調(diào)試。
傳送門(mén):
C#網(wǎng)絡(luò)編程入門(mén)系列包括三篇文章:
(一)C#網(wǎng)絡(luò)編程入門(mén)之UDP
(二)C#網(wǎng)絡(luò)編程入門(mén)之TCP
(三)C#網(wǎng)絡(luò)編程入門(mén)之HTTP
以上就是c# 提供一個(gè)HTTP服務(wù)的實(shí)現(xiàn)示例的詳細(xì)內(nèi)容,更多關(guān)于c# 提供http服務(wù)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- C# TcpClient網(wǎng)絡(luò)編程傳輸文件的示例
- C# 網(wǎng)絡(luò)編程之UDP
- c# 網(wǎng)絡(luò)編程之tcp
- 深入學(xué)習(xí)C#網(wǎng)絡(luò)編程之HTTP應(yīng)用編程(下)
- 深入學(xué)習(xí)C#網(wǎng)絡(luò)編程之HTTP應(yīng)用編程(上)
- 淺談C#網(wǎng)絡(luò)編程詳解篇
- 詳解C# 網(wǎng)絡(luò)編程系列:實(shí)現(xiàn)類(lèi)似QQ的即時(shí)通信程序
- 總結(jié)C#網(wǎng)絡(luò)編程中對(duì)于Cookie的設(shè)定要點(diǎn)
- C# Socket網(wǎng)絡(luò)編程實(shí)例
- C#網(wǎng)絡(luò)編程基礎(chǔ)之進(jìn)程和線程詳解
- c# socket網(wǎng)絡(luò)編程接收發(fā)送數(shù)據(jù)示例代碼
- C#開(kāi)發(fā)之Socket網(wǎng)絡(luò)編程TCP/IP層次模型、端口及報(bào)文等探討
- C#網(wǎng)絡(luò)編程中常用特性介紹
相關(guān)文章
C#中dynamic的使用方法及應(yīng)用場(chǎng)景
在 C# 編程中,dynamic 類(lèi)型是一個(gè)非常特殊的類(lèi)型,它在編譯時(shí)并不會(huì)進(jìn)行類(lèi)型檢查,而是在運(yùn)行時(shí)才進(jìn)行類(lèi)型解析,本文將詳細(xì)講解 dynamic 的使用方法、優(yōu)缺點(diǎn)以及一些實(shí)際應(yīng)用場(chǎng)景,需要的朋友可以參考下2024-08-08C# DropDownList中點(diǎn)擊打開(kāi)新窗口的方法
C# DropDownList中點(diǎn)擊打開(kāi)新窗口的方法,需要的朋友可以參考一下2013-03-03C#服務(wù)器NFS共享文件夾搭建與上傳圖片文件的實(shí)現(xiàn)
本文主要介紹了C#服務(wù)器NFS共享文件夾搭建與上傳圖片文件的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07C#中數(shù)組Array,ArrayList,泛型List詳細(xì)對(duì)比
關(guān)于數(shù)組Array,ArrayList,泛型List,簡(jiǎn)單的說(shuō)數(shù)組就是值對(duì)象,它存儲(chǔ)數(shù)據(jù)元素類(lèi)型的值的一系列位置.Arraylist和list可以提供添加,刪除,等操作的數(shù)據(jù). 具體如何進(jìn)行選擇使用呢,我們來(lái)詳細(xì)探討下2016-06-06C# Socket連接請(qǐng)求超時(shí)機(jī)制實(shí)現(xiàn)代碼分享
這篇文章主要介紹了C# Socket連接請(qǐng)求超時(shí)機(jī)制實(shí)現(xiàn),下面提供代碼分享,大家可以參考使用2013-12-12C#中委托的基礎(chǔ)入門(mén)與實(shí)現(xiàn)方法
這篇文章主要給大家介紹了關(guān)于C#中委托的基礎(chǔ)入門(mén)與實(shí)現(xiàn)方法的相關(guān)資料,究竟什么是委托,用最通俗易懂的話來(lái)講,你就可以把委托看成是用來(lái)執(zhí)行方法(函數(shù))的一個(gè)東西,需要的朋友可以參考下2021-08-08c#中WinForm使用OpencvSharp4實(shí)現(xiàn)簡(jiǎn)易抓邊
本文主要介紹了c#中WinForm使用OpencvSharp4實(shí)現(xiàn)簡(jiǎn)易抓邊,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05WPF ComboBox獲取當(dāng)前選擇值的實(shí)例詳解
這篇文章主要介紹了WPF ComboBox獲取當(dāng)前選擇值的實(shí)例詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-01-01