詳解與HTTP服務器相關操作

HTTP 服務器是一種遵循超文本傳輸協議(HTTP)的服務器,用于在網絡上傳輸和處理網頁及其他相關資源。以下是關于它的詳細介紹:

工作原理

  • HTTP 服務器監聽指定端口(通常是 80 端口用于 HTTP,443 端口用于 HTTPS),等待客戶端(如瀏覽器)發送請求。當客戶端發送請求時,服務器解析請求,根據請求的 URL 和其他信息,找到對應的資源(如 HTML 文件、圖片、腳本等),然后將這些資源封裝在 HTTP 響應消息中,發送回客戶端。

搭建HTTP服務器

這里我們使用別人做好的HTTP服務器:hfs

HTTP的關鍵類

利用Head類型請求資源的可用性

? ? 在 C# 里,HTTP 的HEAD請求方法是一種特殊的 HTTP 請求類型。它和GET請求類似,區別在于HEAD請求僅要求服務器返回 HTTP 響應頭信息,而不返回請求資源的具體內容。這種方法在很多場景中都很有用,比如檢查資源是否存在、獲取資源的元數據(像文件大小、修改時間),同時避免傳輸大量數據。

 #region 知識點一 檢測資源的可用性try{//利用Head類型請求類型,獲取信息//1.創建Http通訊用連接對象HttpWebRequest對象HttpWebRequest req = HttpWebRequest.Create("http://172.41.2.6/HTTP_Server/測試圖片.png") as HttpWebRequest;//2.設置請求類型,或其他相關設置參數req.Method = WebRequestMethods.Http.Head;req.Timeout = 2000;//3.發送請求,獲取響應結果HttpWebResponse對象HttpWebResponse res = req.GetResponse() as HttpWebResponse;if (res.StatusCode == HttpStatusCode.OK){print("文件存在且可用");print(res.ContentLength);print(res.ContentType);res.Close();}elseprint("文件不能用" + res.StatusCode);}catch (WebException w){print("獲取出錯"+w.Message +w.Status);}#endregion

利用Get類型下載服務器中的資源

在 C# 里,GET是 HTTP 協議里最常用的請求方法之一,其作用是從指定的服務器獲取資源

  #region 下載資源try{//利用GET請求類型,下載資源//1.創建HTTP通訊用連接對象HttpWebRequest對象HttpWebRequest req = HttpWebRequest.Create(new Uri("http://172.41.2.6/HTTP_Server/測試圖片.png")) as HttpWebRequest;//2.設置請求類型,或其他相關操作req.Method = WebRequestMethods.Http.Get;req.Timeout = 3000;//3.發送請求,獲取響應結果HttpWebResponse對象HttpWebResponse res = req.GetResponse() as HttpWebResponse;//4.獲取響應數據流,寫入本地路徑if (res.StatusCode == HttpStatusCode.OK){print(Application.persistentDataPath);using (FileStream file = File.Create(Application.persistentDataPath + "/httpDowmload.png")){Stream downLoadStream = res.GetResponseStream();byte[] bytes = new byte[2048];int contentLength = downLoadStream.Read(bytes, 0, bytes.Length);while (contentLength != 0){file.Write(bytes, 0, contentLength);contentLength = downLoadStream.Read(bytes, 0, bytes.Length);}file.Close();downLoadStream.Close();res.Close();}print("下載成功");}elseprint("下載失敗");}catch (WebException w){print("下載出錯了" + w.Message + w.Status);}#endregion 

利用Post類型給服務器上傳資源

在 C# 里,POST請求方法用于向服務器提交數據,通常用于創建新資源,比如用戶注冊、表單提交等場景

Post的學前準備

Get和Post的區別是什么
語義和用途
  • GET:設計目的是從服務器獲取資源。例如,當你在瀏覽器地址欄輸入網址或者點擊超鏈接時,瀏覽器通常會發送GET請求來獲取對應的網頁、圖片、文件等資源。
  • POST:主要用于向服務器提交數據,通常用于創建、更新服務器上的資源。像用戶注冊、登錄、提交表單數據等場景,往往會使用POST請求。
數據傳輸方式
  • GET:請求參數會附加在 URL 后面,以鍵值對的形式出現,多個參數之間用&符號分隔。例如:https://example.com/search?keyword=apple&category=fruits
  • POST:請求參數會放在 HTTP 請求體中進行傳輸,不會顯示在 URL 里。這樣可以傳輸大量數據,并且更適合傳輸敏感信息。
數據長度限制
  • GET:由于請求參數會附加在 URL 后面,而不同的瀏覽器和服務器對 URL 的長度有一定限制,因此GET請求所能攜帶的數據量有限。
  • POST:請求參數放在請求體中,理論上對數據長度沒有限制,但服務器可能會對請求體的大小進行限制。
安全性
  • GET:請求參數會暴露在 URL 中,因此不適合傳輸敏感信息,如密碼、信用卡號等。此外,GET請求還可能被緩存,存在一定的安全風險。
  • POST:請求參數在請求體中,不會暴露在 URL 里,相對更安全。不過,如果不使用 HTTPS 協議進行加密傳輸,請求體中的數據仍可能被截獲。
緩存機制
  • GET:通常會被瀏覽器緩存,這意味著如果多次發送相同的GET請求,瀏覽器可能會直接從本地緩存中獲取響應,而不會再次向服務器發送請求。
  • POST:默認情況下不會被緩存,每次發送POST請求都會向服務器發送新的請求。
冪等性
  • GET:是冪等的,即多次執行相同的GET請求,得到的結果是相同的,不會對服務器上的資源產生額外的影響。
  • POST:不是冪等的,多次執行相同的POST請求可能會在服務器上創建多個相同的資源,或者對資源進行多次更新。
Post如何攜帶額外參數
   #region 知識點二 Post如何攜帶額外參數//關鍵點:將Content-Type設置為 application/x-www-form-urlencoded鍵值對類型HttpWebRequest req = HttpWebRequest.Create("http://172.41.2.6/HTTP_Server") as HttpWebRequest;req.Method = WebRequestMethods.Http.Post;req.Timeout = 2000;//設置上傳內容的類型req.ContentType = "application/x-www-form-urlencoded";//我們要上傳的數據string str = "Name=DamnF&ID=2";byte[] bytes = Encoding.UTF8.GetBytes(str);//我們在上傳之前一定要設置內容的長度req.ContentLength = bytes.Length;//上傳數據Stream stream = req.GetRequestStream();stream.Write(bytes, 0, bytes.Length);stream.Close();//發送數據得到響應結果HttpWebResponse res= req.GetResponse()as HttpWebResponse;print(res.StatusCode);#endregion
Content-Type中重要的類型
 #region 知識點四 ContentType中對于我們重要的類型//1.通用的2進制類型//application/octet-stream//2.通用文本類型//text/plain//3.鍵值對參數//application/x-www-form-urlencoded//4.復合類型(傳遞的信息由多種信息組成,比如有鍵值對參數,文件信息等,上傳資源服務器時需要用到該類型)//multipart//form-data#endregion

開始使用Post上傳資源

using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using UnityEngine;public class Lesson27 : MonoBehaviour
{// Start is called before the first frame updatevoid Start(){#region 知識點一 上傳文件到HTTP資源服務器需要遵守的規則//上傳文件內容必須遵守的規則//1:ContentType="multipart/form-data;boundary=邊界字符串";//2:上傳的格式必須按照格式寫入流中// ---邊界字符串//Content-Disposition:form-data;name="file";filename="傳到服務器上使用的文件名";//Content-Type:application/octet-stream(由于我們上傳2進制文件,所以這里使用2進制)//(這里直接寫入傳入的內容)//--邊界字符串--//3:保證服務器允許上傳//4:寫入流之前需要先設置ContentLength內容長度#endregion#region 知識點二 上傳文件//1.創建HttpWebRequest對象HttpWebRequest req = HttpWebRequest.Create("http://172.41.2.6/HTTP_Server/") as HttpWebRequest;//2.相關設置(請求類型,內容類型,超時,身份驗證等)req.Method = WebRequestMethods.Http.Post;req.ContentType = "multipart/form-data;boundary=DamnF";req.Timeout = 500000;req.Credentials = new NetworkCredential("DamnF", "123");req.PreAuthenticate = true;//先驗證身份,再上傳數據//3.按格式拼接字符串并且轉換為字節數組之后用于上傳//3-1.文件數據前的頭部信息//  --邊界字符串--//Content-Disposition:form-data;name="字段名字,之后寫入的文件2進制數據和該字段名對應";filename="傳到服務器上使用的文件名";//Content-Type:application/octet-stream(由于我們上傳2進制文件,所以這里使用2進制)//空一行string head = "--DamnF\r\n" +"Content-Disposition:form-data;name=\"file\";filename=\"http上傳文件.png\"\r\n" +"Content-Type:application/octet-stream\r\n\r\n";//頭部拼接字符串規則信息的字節數組byte[] headBytes = Encoding.UTF8.GetBytes(head);//3-2結束的邊界信息// --邊界字符串--byte[] endBytes = Encoding.UTF8.GetBytes("\r\n--DamnF--\r\n");//4.寫入上傳流using (FileStream localFileStream=File .OpenRead(Application .streamingAssetsPath +"/test.png")){//4-1設置上傳長度//總長度=前部分字符串長度+文件本身長度+后部分邊界字符串req.ContentLength = headBytes.Length + localFileStream.Length + endBytes.Length;//用于上傳的流Stream upLoadStream = req.GetRequestStream();//4-2先寫入前部分頭部信息upLoadStream.Write(headBytes, 0, headBytes.Length);//4-3再寫入文件數據byte[] bytes = new byte[2048];int contentLength = localFileStream.Read(bytes, 0, bytes.Length);while (contentLength !=0){upLoadStream.Write(bytes, 0, contentLength);contentLength = localFileStream.Read(bytes, 0, bytes.Length);}//4-4再寫入結束的邊界信息upLoadStream.Write(endBytes, 0, endBytes.Length);upLoadStream.Close();localFileStream.Close();}//上傳數據,獲取響應HttpWebResponse res = req.GetResponse() as HttpWebResponse;if (res.StatusCode == HttpStatusCode.OK)print("上傳成功");elseprint("上傳失敗"+res.StatusCode);#endregion}// Update is called once per framevoid Update(){}
}

將Get和Post用單例模式封裝到一個HTTPMgr模塊中(異步)

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.Events;public class HttpMgr
{private static HttpMgr instance=new HttpMgr ();public static HttpMgr Instance => instance;//http服務器地址private string HTTP_PATH = "http://172.41.2.6/HTTP_Server/";//Http服務器賬號和密碼private string HTTP_ID = "DamnF";private string HTTP_PASSWORD = "123";public async void DownLoadFile(string fileName,string localPath,UnityAction<bool>action=null){await Task.Run(()=>{try{HttpWebRequest req = HttpWebRequest.Create(new Uri(HTTP_PATH + fileName)) as HttpWebRequest;req.Method = WebRequestMethods.Http.Get;req.Timeout = 3000;HttpWebResponse res= req.GetResponse()as HttpWebResponse;if (res.StatusCode == HttpStatusCode.OK){using (FileStream fileStream = File.Create(localPath)){Stream downLoadStream = res.GetResponseStream();byte[] bytes = new byte[2048];int contentLength = downLoadStream.Read(bytes, 0, bytes.Length);while (contentLength != 0){fileStream.Write(bytes, 0, contentLength);contentLength = downLoadStream.Read(bytes, 0, bytes.Length);}Debug.Log("下載文件成功");action?.Invoke(true);fileStream.Close();downLoadStream.Close();}res.Close();}elseDebug.Log("下載文件失敗");}catch (WebException w){Debug.Log("下載文件出錯" + w.Message + w.Status);action?.Invoke(false);}});}public async void UpLoadFile(string fileName, string localFileName,UnityAction <bool>action=null){await Task.Run(() =>{try{HttpWebRequest req = HttpWebRequest.Create(HTTP_PATH) as HttpWebRequest;req.Method = WebRequestMethods.Http.Post;req.ContentType = "multipart/form-data;boundary=DamnF";req.Timeout = 500000;req.Credentials = new NetworkCredential(HTTP_ID, HTTP_PASSWORD);req.PreAuthenticate = true;string head = "--DamnF\r\n" +"Content-Disposition:form-data;name=\"file\";filename=\"{0}\"\r\n" +"Content-Type:application/octet-stream\r\n\r\n";head = string.Format(head, fileName);byte[] headBytes = Encoding.UTF8.GetBytes(head);byte[] endBytes = Encoding.UTF8.GetBytes("\r\n--DamnF--\r\n");using (FileStream localFileStream=File .OpenRead (localFileName)){req.ContentLength = headBytes.Length + localFileStream.Length + endBytes.Length;Stream upLoadStream = req.GetRequestStream();upLoadStream.Write(headBytes, 0, headBytes.Length);byte[] bytes = new byte[2048];int contentLength= localFileStream.Read(bytes, 0, bytes.Length);while (contentLength !=0){upLoadStream.Write(bytes, 0, contentLength);contentLength = localFileStream.Read(bytes, 0, bytes.Length);}upLoadStream.Write(endBytes, 0, endBytes.Length);upLoadStream.Close();localFileStream.Close();}HttpWebResponse res= req.GetResponse()as HttpWebResponse;if(res.StatusCode ==HttpStatusCode.OK ){action?.Invoke(true);}else{action?.Invoke(false);}}catch (WebException e){Debug.Log("上傳出錯了" + e.Message + e.Status);}});}
}

測試HTTPMgr模塊

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Lesson25_Test : MonoBehaviour
{// Start is called before the first frame updatevoid Start(){print(Application.persistentDataPath);HttpMgr.Instance.DownLoadFile("/測試圖片.png", Application.persistentDataPath + "/downTest.png", (result) =>{print(result ? "下載成功調用委托函數" : "下載失敗調用委托函數");});HttpMgr.Instance.UpLoadFile("http上傳測試文件.png",Application.streamingAssetsPath + "/test.png", (result) =>{print(result ? "文件上傳成功" : "文件上傳失敗");});}// Update is called once per framevoid Update(){}
}

這樣就實現了對Http服務器的操作了

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

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

相關文章

2. ubuntu20.04 和VS Code實現 ros的輸出 (C++,Python)

本節對應趙虛左ROS書籍的1.4.2 1)創建工作空間 mkdir -p catkin_ws/src cd catkin_ws catkin_make 2) 終端進入VS Code code . 3) vscoe 的基本配置 3.1&#xff09;修改.vscode/tasks.json ,修改內容如下&#xff1a; { // 有關 tasks.json 格式的文檔&#xff0c;請參見…

SAP系統中MD01與MD02區別

知識點普及&#xff0d;MD01與MD02區別 1、從日常業務中&#xff0c;我們都容易知道MD01是運行全部物料&#xff0c;MD02是運行單個物料 2、在做配置測試中&#xff0c;也出現過MD02可以跑出物料&#xff0c;但是MD01跑不出的情況。 3、MD01與MD02的差異: 3.1、只要在物料主數…

快速迭代收縮-閾值算法(FISTA)

文章目錄 1. 數學與優化基礎2. FISTA 算法的原理、推導與機制3. Matlab 實現4. FISTA 在圖像處理與壓縮感知中的應用4.1. 基于小波稀疏先驗的圖像去噪4.2 壓縮感知圖像重建 1. 數學與優化基礎 在許多信號處理與機器學習問題中&#xff0c;我們希望獲得稀疏解&#xff0c;即解向…

微服務之間打通用戶上下文

微服務之間打通用戶上下文 打通上下文步驟需求&#xff1a;1、gateway網關登錄攔截器&#xff1a;【LoginFilter】解釋&#xff1a;代碼 2、SpringMVC全局處理&#xff1a;【GlobalConfig】解釋&#xff1a;代碼&#xff1a; 3、自定義登錄攔截器&#xff1a;【LoginIntercepto…

Hutool之DateUtil:讓Java日期處理變得更加簡單

前言 在Java開發中&#xff0c;日期和時間的處理是一個常見問題。為了簡化這個過程&#xff0c;許多開發者會使用第三方工具包&#xff0c;如Hutool。Hutool是一個Java工具包&#xff0c;提供了許多實用的功能&#xff0c;其中之一就是日期處理。日期時間工具類是Hutool的核心包…

ES中常用的Query和查詢作用,以及SpringBoot使用實例

ES中常用的Query和查詢作用&#xff0c;以及 SpringBoot 使用實例 文章目錄 ES中常用的Query和查詢作用&#xff0c;以及 SpringBoot 使用實例MatchAllQueryTermQueryBoolQueryRangeQueryMatchQueryMultiMatchQueryTermsQueryPrefixQueryWildcardQueryRegexpQueryFuzzyQueryDis…

Flutter 自定義插件基礎

1、Flutter插件是什么&#xff1f;官方插件庫 在開發Flutter應用過程中會涉及到平臺相關接口調用&#xff0c;例如數據庫操作、相機調用、外部瀏覽器跳轉等業務場景。其實Flutter自身并不支持直接在平臺上實現這些功能&#xff0c;而是通過插件包接口去調用指定平臺API從而實現…

極狐GitLab 外部授權控制機制是怎樣的?

極狐GitLab 是 GitLab 在中國的發行版&#xff0c;關于中文參考文檔和資料有&#xff1a; 極狐GitLab 中文文檔極狐GitLab 中文論壇極狐GitLab 官網 外部授權控制 (BASIC SELF) 在高度控制的環境中&#xff0c;訪問策略可能需要由外部服務控制&#xff0c;該服務允許基于項目…

Linux系統之----馮諾依曼結構

1.簡要描述 馮諾依曼體系結構是現代計算機的基本設計思想&#xff0c;其核心理念是將計算機的硬件和軟件統一為一個整體&#xff0c;通過存儲程序的方式實現計算。馮諾依曼體系結構的核心思想是通過存儲程序實現自動計算&#xff0c;其五大部件協同工作&#xff0c;奠定了現代…

【八股】計算機網絡

1 概述 1.1 網絡的網絡 網絡把主機連接起來,而互連網(internet)是把多種不同的網絡連接起來,因此互連網是網絡的網絡。而互聯網(Internet)是全球范圍的互連網。 1.2 ISP 互聯網服務提供商 ISP 可以從互聯網管理機構獲得許多 IP 地址,同時擁有通信線路以及路由器等聯…

基于VS Code 為核心平臺的python語言智能體開發平臺搭建

以下是基于 VS Code 為核心平臺&#xff0c;整合 Node-RED、Gradio、Docker Desktop 的智能體可視化開發平臺優化方案&#xff0c;聚焦工具鏈深度集成與開發效率提升&#xff1a; 一、核心架構設計 #mermaid-svg-f8l9kYPAlJ2TlpGF {font-family:"trebuchet ms",verd…

STM32G0單片機自帶RTC

STM32有個自帶RTC外設&#xff0c;外接32.768KHz的晶振后可得到相對精確的計時功能。 實測了一個一小時快個1秒多。 1 cubeMX設置了RTC后自動生成的初始化代碼如下 static void MX_RTC_Init(void) {/* USER CODE BEGIN RTC_Init 0 *//* USER CODE END RTC_Init 0 */RTC_TimeT…

細說STM32單片機FreeRTOS任務管理API函數及多任務編程的實現方法

目錄 一、FreeRTOS任務管理API函數 1、任務管理API函數 2、獲取任務的句柄 &#xff08;1&#xff09;函數xTaskGetCurrentTaskHandle() &#xff08;2&#xff09;函數xTaskGetIdleTaskHandle() &#xff08;3&#xff09;函數xTaskGetHandle() 3、單個任務的操作 &a…

星露谷物語 7000+ 大型MOD整合包

衣服美化、家具美化、地圖美化、人物肖像美化 全地圖裝修存檔、人物美化、擴展包、環境美化、家具、動植物、通用前置包、新增NPC、功能、服裝發飾妝 帽子發型農場小鎮美化大型玩法拓展實用功能mod 動漫人物形象MOD 地點/動物/地圖/功能/機械/家具/建筑/界面美化/擴展/農場/食譜…

C++ `unique_ptr` 多線程使用

C unique_ptr 多線程使用 一、核心結論 操作同一個 unique_ptr&#xff1a;必須加鎖&#xff08;所有權轉移是非原子操作&#xff09;訪問被管理對象&#xff1a;若對象非線程安全&#xff0c;仍需額外同步獨立 unique_ptr 實例&#xff1a;不同線程操作不同實例時無需加鎖 二…

Android audio系統六 AudioEffect音效加載

對于Android系統智能硬件設備&#xff0c;音效處理的實現方式有以下幾種&#xff1a; AudioEffect – android系統音效處理 優點&#xff1a;純軟件實現&#xff0c;移植調試簡單方便 缺點&#xff1a;cpu上運行&#xff0c;容易因為資源競爭而出現卡頓 DSP/ADSP – 數字信號處…

深度學習總結(21)

超越基于常識的基準 除了不同的評估方法&#xff0c;你還應該了解的是利用基于常識的基準。訓練深度學習模型&#xff0c;你聽不到也看不到。你無法觀察流形學習過程&#xff0c;它發生在數千維空間中&#xff0c;即使投影到三維空間中&#xff0c;你也無法解釋它。唯一的反饋…

接口自動化測試(二)

一、接口測試流程&#xff1a;接口文檔、用例編寫 拿到接口文檔——編寫接口用例以及評審——進行接口測試——工具/自動化框架進行自動化用例覆蓋(70%)——輸出測試報告 自動化的目的一般是為了回歸 第一件事情&#xff1a;理解需求&#xff0c;學會看接口文檔 只需要找到我…

Linux上位機開發實踐(以MCU小系統入門嵌入式電路)

【 聲明&#xff1a;版權所有&#xff0c;歡迎轉載&#xff0c;請勿用于商業用途。 聯系信箱&#xff1a;feixiaoxing 163.com】 一直都主張嵌入式軟件工程師&#xff0c;也要會做一點電路設計的工作。哪怕自己做的是嵌入式linux上層開發&#xff0c;一個會硬件設計&#xff0c…

瀏覽器的存儲機制 - Storage

瀏覽器的存儲機制 - Storage 前言一、核心概念與區別二、常用 API1、存儲數據&#xff08;setItem(key, value)&#xff09;2、 獲取數據&#xff08;getItem(key)&#xff09;3、刪除單個數據&#xff08;removeItem(key)&#xff09;4、清空所有數據&#xff08;clear()&…