详解与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.mzph.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()&…