【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);}}
相关文章:
【Unity网络编程知识】C#的 Http相关类学习
1、搭建HTTP服务器 使用别人做好的HTTP服务器软件,一般作为资源服务器时使用该方式(学习阶段建议使用)自己编写HTTP服务器应用程序,一般作为Web服务器或者短连接游戏服务器时使用该方式(工作后由后端程序员来做&#…...
Python operator 模块介绍
operator 模块是 Python 标准库中的一个模块,它提供了一系列与 Python 内置运算符对应的函数。这些函数可以用于替代一些常见的运算符操作,在某些场景下能让代码更加简洁、高效,还能方便地用于函数式编程。以下是对 operator 模块的详细介绍: 1. 导入模块 使用 operator …...
SpringBoot企业级开发之【用户模块-更新用户头像】
功能如下所示: 我们先看一下接口文档: 为什么头像是一串字符串呢?因为我们是将头像图片放到第三方去存储,比如:阿里云等 开发思路: 实操: 1.controller 注意!这里使用【PatchMapping】注解…...
DAPP实战篇:使用ethersjs连接智能合约并输入地址查询该地址余额
本系列目录 专栏:区块链入门到放弃查看目录-CSDN博客文章浏览阅读400次。为了方便查看将本专栏的所有内容列出目录,按照顺序查看即可。后续也会在此规划一下后续内容,因此如果遇到不能点击的,代表还没有更新。声明:文中所出观点大多数源于笔者多年开发经验所总结,如果你…...
网络流量管理-流(Flow)
1. 传统网络的问题:快递员送信模式 想象你每天要寄100封信给同一个朋友,传统网络的处理方式就像一个固执的快递员: 每封信都单独处理:检查地址、规划路线、盖章、装车…即使所有信的目的地、收件人都相同,也要重复100…...
每日文献(十一)——Part two
今天从第四章:快速RCNN,方法细节开始介绍。 目录 四、快速RCNN:方法细节 4.1 快速R-CNN回顾 4.2 对抗网络设计 4.2.1 遮挡的对抗空间信息损失 4.2.2 对抗空间Transformer网络 4.2.3 对抗融合 五、实验 5.1 实验设置 5.2 PASCAL VOC…...
Laravel 实现 队列 发送邮件功能
一. 什么是队列 在构建 Web 应用程序时,你可能需要执行一些任务,例如解析文件,发送邮件,大量的数据计算等等,这些任务在典型的 Web 请求期间需要很长时间才能执行。 庆幸的是,Laravel 可以创建在后台运行…...
一、绪论(Introduction of Artificial Intelligence)
写在前面: 老师比较看重的点:对问题的概念本质的理解,不会考试一堆运算的东西,只需要将概念理解清楚就可以,最后一个题会出一个综合题,看潜力,前面的部分考的不是很深,不是很难&…...
Web攻防—SSRF服务端请求伪造Gopher伪协议无回显利用
前言 重学Top10的第二篇,希望各位大佬不要见笑。 SSRF原理 SSRF又叫服务端请求伪造,是一种由服务端发起的恶意请求,SSRF发生在应用程序允许攻击者诱使服务器向任意域或资源发送未经授权的请求时。服务器充当代理,执行攻击者构造…...
2025蓝桥杯python A组题解
真捐款去了,好长时间没练了,感觉脑子和手都不转悠了。 B F BF BF 赛时都写假了, G G G 也只写了爆搜。 题解其实队友都写好了,我就粘一下自己的代码,稍微提点个人的理解水一篇题解 队友题解 B 思路: 我…...
使用Python建模量子隧穿
引言 量子隧穿是量子力学中的一个非常有趣且令人神往的现象。在经典物理学中,我们通常认为粒子必须克服一个势垒才能通过它。但是,在量子力学中,粒子有时可以“穿越”一个势垒,即使它的能量不足以克服这个势垒。这种现象被称为“量子隧穿”。今天,我们将通过 Python 来建…...
微信小程序开发常用语法和api
vue写习惯了,小程序太久不做,一些语法和api都忘记。本文总结下小程序常用的语法和api 语法 绑定事件和传参 绑定事件还有很多,触摸反馈事件,表单事件,媒体事件后续更新细说。 <!-- 绑定事件 bindtap 事件传参 da…...
【时时三省】(C语言基础)选择结构程序综合举例
山不在高,有仙则名。水不在深,有龙则灵。 ----CSDN 时时三省 下面综合介绍几个包含选择结构的应用程序。 例题1: 写一程序,判断某一年是否为闰年。 程序1: 先画出判别闰年算法的流程图,见下图用变量le…...
Redis实现分布式定时任务
设计思路 任务表示:每个任务通过一个特定格式的键来表示。键名可以包含任务ID等信息,值可以是任务的具体内容或指向任务详情的引用。过期机制:利用Redis的EXPIRE命令为任务设置过期时间,当到达设定的时间点时,Redis会…...
File 类 (文件|文件夹操作)
一、File 类 1.1 前言 在 JDK 中 通过 java.io.File 类,可以实现操作系统重文件|文件夹的创建、删除、查看、重命名等操作。 1.2 File 类构造方法 File 一共提供了四个构造方法,都是有参构造。其中最常使用的是 File(String) 和 File(String, String)…...
Html页面Table表格导出导入Excel文件 xlsx.full
Html页面Table表格导出Excel文件 引用 xlsx.full.min.js 文件 导出 <!DOCTYPE html> <html> <head><meta charset"utf-8" /><title></title><script src"https://cdn.bootcdn.net/ajax/libs/jquery/3.6.3/jquery.min.j…...
【资料分享】瑞芯微RK3576,8核2.2GHz+6T算力NPU工业核心板说明书
核心板简介 创龙科技SOM-TL3576-S是一款基于瑞芯微RK3576J/RK3576高性能处理器设计的4核ARM Cor...
埃隆·马斯克如何通过开源创新塑造未来
李升伟 编译 埃隆马斯克的名字在多个行业回响——从电动汽车、太空探索到人工智能及更多领域。虽然许多人关注他革命性的公司(如特斯拉、SpaceX、Neuralink和The Boring Company),但较少有人意识到他在开源软件运动中悄然却深远的影响力。本…...
ALOPS智能化运维管理平台
AIOps(Artificial Intelligence for IT Operations)即智能运维,是将人工智能技术应用于 IT 运维管理领域,以实现自动化、智能化的运维决策和管理。以下是关于 AIOps 的详细介绍: 核心能力 数据收集与整合:…...
Hadoop文件操作指南:深入解析文件操作
1 Hadoop文件系统概述 Hadoop分布式文件系统(HDFS)是Hadoop生态的核心存储组件,专为大规模数据集设计,具有高容错性和高吞吐量特性。 HDFS核心特性: 分布式存储:文件被分割成块(默认128MB)分布存储多副本机制:每个块默认3副本&…...
使用Fortran读取HDF5数据
使用Fortran读取HDF5数据 下面我将介绍如何在Fortran中读取HDF5文件中的各种类型数组数据,包括一维数组、二维数组、元数组和变长数组。 准备工作 首先需要确保系统安装了HDF5库,并且在编译时链接了HDF5库。例如使用gfortran编译时: gfor…...
STM32 HAL库之EXTI示例代码
外部中断按键控制LED灯 在main.c中 HAL_Init(); 初始化Flash,中断优先级以及HAL_MspInit函数,也就是 stm32f1xx_hal.c 中 HAL_StatusTypeDef HAL_Init(void) {/* Configure Flash prefetch */ #if (PREFETCH_ENABLE ! 0) #if defined(STM32F101x6) || …...
通过C#将GB18030编码转义为UTF-8
使用C#代码,对于GB18030编码转义为UTF-8格式。 using System.Text;public class FileEncodingConverter {// 支持转换的文件扩展名列表(可根据需求扩展)private static readonly string[] SupportedExtensions { ".sln", ".…...
《TCP/IP网络编程》学习笔记 | Chapter 23:IOCP
《TCP/IP网络编程》学习笔记 | Chapter 23:IOCP 《TCP/IP网络编程》学习笔记 | Chapter 23:IOCP通过重叠 I/O 理解 IOCPepoll 和 IOCP 的性能比较实现非阻塞模式的套接字以纯重叠 I/O 方式实现回声服务器端重新实现客户端测试从重叠 I/O 模型到 IOCP 模型…...
Java学习打卡-Day25-注解和反射、Class类
注解(JDK5引入) 什么是注解? Java注解(Annotation),也叫元数据。一种代码级别的说明,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面…...
电感、互感器、变压器和磁珠综合对比——《器件手册--电感/线圈/变压器/磁珠篇》
三、电感/线圈/变压器/磁珠 名称 定义 特点...
CAD导入arcgis中保持面积不变的方法
1、加载CAD数据,选择面数据,如下: 2、加载进来后,右键导出数据,导出成面shp数据,如下: 3、选择存储路径,导出面后计算面积,如下: 4、与CAD中的闭合线面积核对…...
rustdesk自建服务器怎么填写客户端配置信息
目录 # id、api、中继都怎么填?rustdesk程序启动后服务不自动启动 # id、api、中继都怎么填? rustdesk程序启动后服务不自动启动 完全退出RudtDesk程序(右下角托盘区有的话,需要右键点退出) 创建windows服务ÿ…...
c++进阶之----智能指针
1.概念 在 C 中,智能指针是一种特殊的指针类型,它封装了裸指针(raw pointer)的行为,并通过 RAII(Resource Acquisition Is Initialization,资源获取即初始化)机制自动管理动态分配的…...
六、测试分类
设计测试用例 万能公式:功能测试性能测试界面测试兼容性测试安全性测试易用性测试 弱网测试:fiddler上行速率和下行速率 安装卸载测试 在工作中: 1.基于需求文档来设计测试用例(粗粒度) 输入字段长度为6~15位 功…...
