【Unity网络编程知识】C#的 Http相关类学习

1、搭建HTTP服务器

  • 使用别人做好的HTTP服务器软件,一般作为资源服务器时使用该方式(学习阶段建议使用)
  • 自己编写HTTP服务器应用程序,一般作为Web服务器或者短连接游戏服务器时使用该方式(工作后由后端程序员来做)

1.1 使用hfs搭建HTTP服务器,双击打开运行即可

1.2 添加服务器访问文件夹

右键打开添加文件夹

选择自己需要设置的访问文件夹

 1.3 设置允许访问和上传权限

移到目标文件夹右键选择Properties

创建允许访问用户凭证

 设置访问权限

设置上传权限

 设置删除权限

2、C#的Http关键类介绍

2.1 HttpWebRequest类

重要方法

1)Create 创建新的WebRequest,用于进行HTTP相关操作

2)Abort  如果正在进行文件传输,用此方法可以终止传输

3)GetRequestStream 获取用于上传的流

4)GetResponse 返回HTTP服务器响应

5)Begin/EndGetRequestStream 异步获取用于上传的流

6)Begin/EndGetResponse 异步获取返回的HTTP服务器响应

重要成员

1)Credentials通信凭证,设置为NetworkCredential对象

2)PreAuthenticate是否随请求发送一个身份验证标头,一般需要进行身份验证时需要将其设置为true

3)Headers构成标头的名称/值对的集合

4)ContentLength发送信息的字节数上传信息时需要先设置该内容长度

5)ContentType在进行POST请求时,需要对发送的内容进行内容类型的设置

6)Method操作命令设置

  •  WebRequestMethods.Http类中的操作命令属性
  • Get             获取请求,一般用于获取数据
  • Post           提交请求,一般用于上传数据,同时可以获取
  • Head          获取和Get一致的内容,只是只会返回消息头,不会返回具体内容
  • Put             向指定位置上传最新内容
  • Connect     表示与代理一起使用的HTTPCONNECT协议方法,该代理可以动态切换到隧道
  • MkCol        请求在请求 URI(统一资源标识符)指定的位置新建集合

2.2 HttpWebResponse类

重要方法

1)Close:释放所有资源

2)GetResponseStream:返回从FTP服务器下载数据的流

重要成员

1)ContentLength:接受到数据的长度

2)ContentType:接受数据的类型

3)StatusCode:HTTP服务器下发的最新状态码

4)StatusDescription:HTTP服务器下发的状态代码的文本

5)BannerMessage:登录前建立连接时HTTP服务器发送的消息

6)ExitMessage:HTTP会话结束时服务器发送的消息

7)LastModified:HTTP服务器上的文件的上次修改日期和时间

2.3 NetworkCredential

3、Http下载数据

3.1 检测资源可用性

            //利用Head请求参型,获取信息//1.创建HTTP通讯用连接对象HttpWebRequest对象HttpWebRequest req = HttpWebRequest.Create(new Uri("https://t7.baidu.com/it/u=2604797219,1573897854&fm=193&f=GIF")) as HttpWebRequest;//2.设置请求类型或其它相关参数req.Method = WebRequestMethods.Http.Head;req.Timeout = 2000;//3.发送请求,获取响应结果HttpWebResponse对象HttpWebResponse res = req.GetResponse() as HttpWebResponse;//4.判断资源是否存在if (res.StatusCode == HttpStatusCode.OK){print("文件存在且可用");print(res.ContentLength);print(res.ContentType);res.Close();}else{print("文件不可用" + res.StatusCode);}

3.2 下载资源

            //1.创建HTTP通讯用连接对象HttpWebRequest对象HttpWebRequest req2 = HttpWebRequest.Create(new Uri("https://t7.baidu.com/it/u=2604797219,1573897854&fm=193&f=GIF")) as HttpWebRequest;//2.设置请求类型或其它相关参数req2.Method = WebRequestMethods.Http.Get;req2.Timeout = 3000;//3.发送请求,获取响应结果HttpWebResponse对象HttpWebResponse res2 = req2.GetResponse() as HttpWebResponse;//4.获取响应数据流,写入本地路径if (res2.StatusCode == HttpStatusCode.OK){print(Application.persistentDataPath);using (FileStream fileStream = File.Create(Application.persistentDataPath + "/httpDownLoad.jpg")){Stream downLoadStream = res2.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);}fileStream.Close();downLoadStream.Close();res2.Close();}print("下载成功");}else{print("下载失败" + res2.StatusCode);}

3.3 Get请求类型携带额外信息

1)协议部分

2)域名或公网IP部分

3)端口部分(默认80不需要写)

4)虚拟目录部分

5)参数部分

        //我们在进行HTTP通信时,可以在地址后面加一些额外参数传递给服务端//一般在和短连接游戏服务器通讯时,需要携带额外信息// 举例://http://www.aspxfans.com:8080/news/child/index.boardID=5&ID=24618&page=1//这个链接可以分成几部分//1.协议部分:取决于服务器端使用的哪种协议//http:     //一 普通的http超文本传输协议//https:    //一 加密的超文本传输协议//2.域名部分://www.aspxfans.com//也可以填写服务器的公网IP地址//3.端口部分://8080//可以不写,如果不写默认为80//4.虚拟目录部分://news/child///域名后的/开始,到最后一个/之前的部分//5.文件名部分:// index.asp//?之前的最后一个 / 后的部分// 6.参数部分://boardID=5&ID=24618&page=1//?之后的部分就是参数部分,多个参数一&分隔开//这里有三个参数//boardID = 5//ID = 24618//page = 1//我们在和服务端进行通信时,只要按照这种规则格式进行通信,就可以传递参数给对象//主要可用于://1.web网站服务器//2.游戏短连接服务器//等

4、Http上传文件

4.1 上传文件到HTTP资源服务器需要遵守的规则

        //上传文件时内容的必备规则//  1:ContentType ="multipart/form-data;boundary=边界字符串";//  2:上传的数据必须按照格式写入流中//  --边界字符串//  Content - Disposition:form - data; name = "字段名字,之后写入的文件2进制数据和该字段名对应"; filename = "传到服务器上使用的文件名"//  Content - Type:application / octet - stream(由于我们传2进制文件所以这里使用2进制)//  空一行//  (这里直接写入传入的内容)//  --边界字符串--//  3:保证服务器允许上传//  4:写入流前需要先设置ContentLength内容长度

4.2 上传文件

        //1.创建HttpWebRequest对象HttpWebRequest req = HttpWebRequest.Create("http://192.168.1.25:8000/HttpServer/") as HttpWebRequest;//2.相关设置(请求类型,内容类型,超时,身份验证等)req.Method = WebRequestMethods.Http.Post;req.ContentType = "multipart/form-data;boundary=MrZhou";req.Timeout = 50000;req.Credentials = new NetworkCredential("ZT", "zt123");req.PreAuthenticate = true;//3.按格式拼接字符串并且转为字节数组之后用于上传//3-1.文件数据前的头部信息//  --边界字符串//  Content-Disposition:form-data;name="字段名字,之后写入的文件2进制数据和该字段名对应";filename="传到服务器上//  Content-Type:application/octet-stream(由于我们传2进制文件所以这里使用2进制)string head = "--MrZhou\r\n" +"Content-Disposition:form-data;name=\"file\";filename=\"http上传的文件.jpg\"\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--MrZhou--\r\n");//4.写入上传流//4-1.设置上传长度//4-2.先写入前部分头部信息//4-3.再写入文件数据//4-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();}//5.上传数据,获取响应HttpWebResponse res = req.GetResponse() as HttpWebResponse;if(res.StatusCode == HttpStatusCode.OK){print("上传通讯成功");}else{print("上传失败" + res.StatusCode);}

5、Http管理类

using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.Events;public class HttpMgr
{private static HttpMgr instance = new HttpMgr();public static HttpMgr Instance => instance;//private string HTTP_PATH = "https://t7.baidu.com/it/";private string HTTP_PATH = "http://192.168.1.25:8000/HttpServer/";private string USER_NAME = "ZT";private string PASS_WORD = "zt123";/// <summary>/// 下载指定文件到本地指定路径中/// </summary>/// <param name="url">远程文件路径</param>/// <param name="localPath">本地路径</param>/// <param name="action">下载结束后的回调函数</param>public async void DownLoadFile(string url, string localFilePath, UnityAction<HttpStatusCode> action = null){HttpStatusCode result = HttpStatusCode.OK;await Task.Run(() =>{try{//判断文件是否存在 Head//1.创建HTTP连接对象HttpWebRequest req = HttpWebRequest.Create(url) as HttpWebRequest;//2.设置请求类型 和 其他相关参数req.Method = WebRequestMethods.Http.Head;req.Timeout = 2000;//3.发送请求HttpWebResponse res = req.GetResponse() as HttpWebResponse;//存在才下载if(res.StatusCode == HttpStatusCode.OK){res.Close();//下载文件//1.创建HTTP连接对象req = HttpWebRequest.Create(url) as HttpWebRequest;//2.设置请求类型 和 其他相关参数req.Method = WebRequestMethods.Http.Get;req.Timeout = 2000;//3.发送请求res = req.GetResponse() as HttpWebResponse;//4.存储数据到本地if(res.StatusCode == HttpStatusCode.OK){//存储数据using (FileStream fileStream = File.Create(localFilePath)){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);}fileStream.Close();downLoadStream.Close();}result = HttpStatusCode.OK;}else{result = res.StatusCode;}}else{result = res.StatusCode;}res.Close();}catch (WebException e){result = HttpStatusCode.InternalServerError;Debug.LogError("文件下载失败" + e.Message + e.Status);}});action?.Invoke(result);}/// <summary>/// 上传文件/// </summary>/// <param name="fileName">传到远端服务器上的文件名</param>/// <param name="localFilePath">本地的文件路径</param>/// <param name="action">上传结束后的回调函数</param>public async void UpLoadFile(string fileName, string localFilePath, UnityAction<HttpStatusCode> action = null){HttpStatusCode result = HttpStatusCode.BadGateway;await Task.Run(() =>{try{HttpWebRequest req = HttpWebRequest.Create(HTTP_PATH) as HttpWebRequest;req.Method = WebRequestMethods.Http.Post;req.ContentType = "multipart/form-data;boundary=MrZhou";req.Timeout = 50000;req.Credentials = new NetworkCredential(USER_NAME, PASS_WORD);req.PreAuthenticate = true;//拼接字符串头部string head = "--MrZhou\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);Debug.Log(head);byte[] headBytes = Encoding.UTF8.GetBytes(head);//尾部的边界字符串byte[] endBytes = Encoding.UTF8.GetBytes("\r\n--MrZhou--\r\n");using(FileStream localStream =  File.OpenRead(localFilePath)){//设置长度req.ContentLength = headBytes.Length + localStream.Length + endBytes.Length;//写入流Stream upLoadStream = req.GetRequestStream();//写入头部upLoadStream.Write(headBytes, 0, headBytes.Length);//写入上传文件byte[] bytes = new byte[2048];int contentLength = localStream.Read(bytes, 0, bytes.Length);while (contentLength > 0){upLoadStream.Write(bytes, 0, contentLength);contentLength = localStream.Read(bytes, 0, bytes.Length);}//写入尾部upLoadStream.Write(endBytes, 0, endBytes.Length);upLoadStream.Close();localStream.Close();}HttpWebResponse res = req.GetResponse() as HttpWebResponse;//让外部去处理结果result = res.StatusCode;res.Close();}catch (WebException e){Debug.LogError("上传失败" + e.Message + e.Status);}});action?.Invoke(result);}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/75171.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android Studio - 解决 Please Select Android SDK

一、出现的问题 点击 Run 后弹窗&#xff0c;图一位置出现图二提示。 二、解决办法 进入 Tools -> SDK Manager&#xff0c;在 Android SDK Location 点击 Edit&#xff0c;一直 Next 就解决了。

UE5学习笔记 FPS游戏制作44 统一UI大小 sizeBox

如果我们希望多个类似的UI大小一样&#xff0c;例如不同菜单的标题&#xff0c;可以使用sizeBox组件 我们在标题控件上&#xff0c;用sizeBox包裹所有子物体 然后指定他的最小宽高&#xff0c;或最大宽高 如果指定的是最小宽高&#xff0c;当子元素&#xff08;如图片&#xf…

MCP协议介绍

MCP协议&#xff08;Model Context Protocol&#xff0c;模型上下文协议&#xff09;是由Anthropic公司推出的开放协议&#xff0c;旨在为AI大模型与外部数据源、工具之间建立标准化交互框架。其核心价值在于突破传统API限制&#xff0c;通过统一接口实现AI与多源数据、工具的双…

C#里使用WPF的MaterialDesignThemes

先要下载下面的包: <?xml version="1.0" encoding="utf-8"?> <packages><package id="MaterialDesignColors" version="5.2.1" targetFramework="net48" /><package id="MaterialDesignTheme…

基于 Spring Boot 瑞吉外卖系统开发(四)

基于 Spring Boot 瑞吉外卖系统开发&#xff08;四&#xff09; 新增分类 新增分类UI界面&#xff0c;两个按钮分别对应两个UI界面 两个页面所需的接口都一样&#xff0c;请求参数type值不一样&#xff0c;type1为菜品分类&#xff0c;type2为套餐分类。 请求方法都为POST。…

神经网络 | 基于脉冲耦合神经网络PCNN图像特征提取与匹配(附matlab代码)

内容未发表论文基于脉冲耦合神经网络(PCNN)的图像特征提取与匹配研究 摘要 本文提出一种基于脉冲耦合神经网络(Pulse-Coupled Neural Network, PCNN)的图像特征提取与匹配方法。通过模拟生物视觉皮层神经元的脉冲同步发放特性,PCNN能够有效捕捉图像纹理与边缘特征。实验表…

LeetCode 252 会议室题全解析:Swift 实现 + 场景还原

文章目录 摘要描述题解答案题解代码分析示例测试及结果时间复杂度空间复杂度总结 摘要 在这篇文章中&#xff0c;我们将深入探讨LeetCode第252题“会议室”的问题&#xff0c;提供一个用Swift编写的解决方案&#xff0c;并结合实际场景进行分析。通过这篇文章&#xff0c;你将…

HBuilder运行uni-app程序报错【Error: listen EACCES: permission denied 0.0.0.0:5173】

一、错误提示&#xff1a; 当使用HBuilder运行uni-app项目的时候提示了如下错误❌ 15:11:03.089 项目 project 开始编译 15:11:04.404 请注意运行模式下&#xff0c;因日志输出、sourcemap 以及未压缩源码等原因&#xff0c;性能和包体积&#xff0c;均不及发行模式。 15:11:04…

Flink框架:批处理和流式处理与有界数据和无界数据之间的关系

本文重点 从数据集的类型来看&#xff0c;数据集可以分为有界数据和无界数据两种&#xff0c;从处理方式来看&#xff0c;有批处理和流处理两种。一般而言有界数据常常使用批处理方式&#xff0c;无界数据往往使用流处理方式。 有界数据和无界数据 有界数据有一个明确的开始和…

虚拟列表react-virtualized使用(npm install react-virtualized)

1. 虚拟化列表 (List) // 1. 虚拟化列表 (List)import { List } from react-virtualized; import react-virtualized/styles.css; // 只导入一次样式// 示例数据 const list Array(1000).fill().map((_, index) > ({id: index,name: Item ${index},description: This is i…

IT+开发+业务一体化:AI驱动的ITSM解决方案Jira Service Management价值分析(文末免费获取报告)

本文来源atlassian.com&#xff0c;由Atlassian全球白金合作伙伴、DevSecOps解决方案提供商-龙智翻译整理。 无论是支持内部员工、处理突发事件还是批准变更申请&#xff0c;服务团队的每一分钟都至关重要。您的企业是否做好了充分准备&#xff1f; 许多企业仍然依赖传统的IT服…

leetcode刷题日记——167. 两数之和 II - 输入有序数组

[ 题目描述 ]&#xff1a; [ 思路 ]&#xff1a; 题目要求求数值numbers中的和为 target 的两个数的下标最简单的思路就是暴力求解&#xff0c;两两挨个组合&#xff0c;但时间复杂度为O(n2)&#xff0c;不一定能通过因为数组为非递减&#xff0c;那我们可以使用双指针&#…

【Leetcode-Hot100】盛最多水的容器

题目 解答 目的是求面积最大&#xff0c;面积是由两个下标和对应的最小值得到&#xff0c;因此唯一的问题就是如何遍历这两个下标。我采用begin和end两个变量&#xff0c;确保begin是小于end的&#xff0c;使用它们二者求面积&#xff0c;代码如下&#xff1a; 很不幸 出错了…

dify文本生成图片

安装Stability 授权 Stability AI - Developer Platform Stability AI - Developer Platform 创建智能体 模型要选好点的&#xff0c;要不可能会生成失败。

前端开发中的问题排查与定位:HTML、CSS、JavaScript(报错的解决方式)

目录 1.html 1. 结构错误调试&#xff1a;标签未正确嵌套 2. 语法问题调试&#xff1a;缺失引号 3. 断点调试&#xff1a;动态生成内容时的 JavaScript 错误 4. 网络调试&#xff1a;资源加载错误 5. 性能调试&#xff1a;页面加载性能 总结&#xff1a; 2.CSS 1. 定位…

Spring MVC 重定向(Redirect)详解

Spring MVC 重定向&#xff08;Redirect&#xff09;详解 1. 核心概念与作用 重定向&#xff08;Redirect&#xff09; 是 Spring MVC 中一种客户端重定向机制&#xff0c;通过 HTTP 302 状态码&#xff08;默认&#xff09;将用户浏览器重定向到指定 URL。 主要用途&#xf…

《深入探秘:分布式软总线自发现、自组网技术原理》

在当今数字化浪潮中&#xff0c;分布式系统的发展日新月异&#xff0c;而分布式软总线作为实现设备高效互联的关键技术&#xff0c;其自发现与自组网功能宛如打开智能世界大门的钥匙&#xff0c;为多设备协同工作奠定了坚实基础。 分布式软总线的重要地位 分布式软总线是构建…

eplan许可证的用户权限管理

在电气设计领域&#xff0c;EPLAN软件以其强大的功能和灵活性而备受用户青睐。然而&#xff0c;随着企业规模的扩大和团队人数的增加&#xff0c;如何确保软件使用的安全与效率成为了一个重要的问题。EPLAN许可证的用户权限管理功能为此提供了完美的解决方案。本文将详细介绍EP…

pytorch小记(十七):PyTorch 中的 `expand` 与 `repeat`:详解广播机制与复制行为(附详细示例)

pytorch小记&#xff08;十七&#xff09;&#xff1a;PyTorch 中的 expand 与 repeat&#xff1a;详解广播机制与复制行为&#xff08;附详细示例&#xff09; &#x1f680; PyTorch 中的 expand 与 repeat&#xff1a;详解广播机制与复制行为&#xff08;附详细示例&#xf…

Databricks: Why did your cluster disappear?

You may found that you created a cluster many days ago, and you didnt delete it, but it is disapear. Why did this happen? Who deleted the cluster? Actually, 30 days after a compute is terminated, it is permanently deleted automaticlly. If your workspac…