详解与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服务器相关操作
HTTP 服务器是一种遵循超文本传输协议(HTTP)的服务器,用于在网络上传输和处理网页及其他相关资源。以下是关于它的详细介绍: 工作原理 HTTP 服务器监听指定端口(通常是 80 端口用于 HTTP,443 端口用于 HT…...
-XX:+HeapDumpOnOutOfMemoryError 会打印哪些oom错误
-XX:HeapDumpOnOutOfMemoryError 参数会在 JVM 发生以下 OutOfMemoryError(OOM) 错误时自动生成堆转储文件(Heap Dump),便于后续分析内存溢出原因: 一、触发转储的 OOM 错误类型 Java 堆溢出…...
Moldflow模流分析教程
Moldflow模流分析教程:...
计算机网络 3-4 数据链路层(局域网)
4.1 局域网LAN 特点 1.覆盖较小的地理范围 2.较低的时延和误码率 3.局域网内的各节点之间 4.支持单播、广播、多播 分类 关注三要素 (出题点) ①拓扑结构 ②传输介质 ③介质访问控制方式 硬件架构 4.2 以太网 4.2.1 层次划分 4.2.2 物理层标准…...
加密与解密完全指南,使用Java实现
文章目录 1. 加密基础知识1.1 什么是加密?1.2 加密的历史简介1.2.1 古典加密1.2.2 现代加密的起源1.3 加密的基本概念1.3.1 密码学中的关键术语1.3.2 加密的基本原则1.4 加密的分类1.4.1 对称加密(Symmetric Encryption)1.4.2 非对称加密(Asymmetric Encryption)1.4.3 哈希…...
单片机AIN0、AIN1引脚功能
目录 1. 模拟-数字转换器(ADC) 2. 交流电源(AC) 总结 这两部分有什么区别? 在这个电路图中,两个部分分别是模拟-数字转换器(ADC)和交流电源(AC)。以下是这…...
如何增加 Elasticsearch 中的 primary shard 数量
作者:来自 Elastic Kofi Bartlett 探索增加 Elasticsearch 中 primary shard 数量的方法。 更多阅读: Elasticsearch:Split index API - 把一个大的索引分拆成更多分片 Elasticsearch:通过 shrink API 减少 shard 数量来缩小 El…...
Java 并发性能优化:线程池的最佳实践
Java 并发性能优化:线程池的最佳实践 在 Java 并发编程的世界里,线程池堪称提高应用性能与稳定性的神器。恰如其分地运用线程池,能让我们在多线程任务调度时游刃有余,既能避免线程频繁创建销毁带来的开销,又能合理管控…...
【综述】一文读懂卷积神经网络(CNN)
卷积神经网络(Convolutional Neural Networks, CNN)是一类包含卷积计算且具有深度结构的前馈神经网络(Feedforward Neural Networks),是深度学习(deep learning)的代表算法之一。本文旨在介绍CN…...
Python爬虫实战:获取网易新闻数据
一、引言 随着互联网的飞速发展,网络上蕴含着海量的信息资源。新闻数据作为其中的重要组成部分,对于舆情分析、市场研究、信息传播等多个领域具有重要价值。网易新闻作为国内知名的新闻平台,拥有丰富多样的新闻内容。使用 Python 的 Scrapy 框架进行网易新闻数据的爬取,可…...
YOLO学习笔记 | 基于COCO Stuff数据集与YOLOv11的多类别物体检测与分割
基于COCO Stuff数据集与YOLOv11的多类别物体检测与分割技术解析 一、技术背景与YOLOv11核心改进 YOLOv11是Ultralytics推出的新一代目标检测与分割模型,在YOLOv8的基础上进一步优化了架构设计与训练流程。其核心改进包括: 自适应特征增强(AFE)模块:通过空间上下文模块(…...
ICS丨Chapter 1 Introduction to Computer System
Chapter 1 Introduction to Computer System Courses About Systems: DBMSDistributed SystemsCompilersArchitectureOperating Systemse.t.c. 1. Brief Introduction 1.1. What’s about CSAPP?1.2. Power of Abstraction1.3. Importance of understanding HOW things wor…...
阿里云集群开启debug
1、安装 kubectl Macos brew install kubectl Windows: https://kubernetes.io/zh-cn/docs/tasks/tools/install-kubectl-windows/ 下载后,放到任意目录 2、配置连接信息 mac 将以下内容复制到计算机 $HOME/.kube/config 文件下: windows 不同集…...
Flink Hive Catalog最佳实践
Flink Hive Catalog 最佳实践 一、配置与初始化 依赖管理 Hive Connector 版本对齐:需确保 flink-sql-connector-hive 版本与 Hive 版本严格匹配(如 Hive 3.1.3 对应 flink-sql-connector-hive-3.1.3_2.12),同时添加 Hadoop 遮蔽…...
Unity之如何实现RenderStreaming视频推流
文章目录 前言引入 UnityRenderStreaming 的好处教程步骤 1:设置环境步骤 2: 创建项目步骤 3:安装软件包步骤 5:下载示例步骤 6:检查配置环境步骤 7:打开推流场景步骤 8: 准备用于流式传输的WebServer应用程序步骤 9: 运行 示例场景步骤 10:检查视频是否在浏览器中显示…...
【java实现+4种变体完整例子】排序算法中【桶排序】的详细解析,包含基础实现、常见变体的完整代码示例,以及各变体的对比表格
以下是桶排序的详细解析,包含基础实现、常见变体的完整代码示例,以及各变体的对比表格: 一、桶排序基础实现 原理 将数据分到有限数量的桶中,每个桶内部使用其他排序算法(如插入排序或快速排序)…...
计算机三级:信息安全基础技术与原理(2.1密码技术简单梳理)
以下是密码学发展历程的表格归纳: 发展阶段时间范围关键节点与标志性技术技术突破与核心贡献古典密码时期古代至19世纪• 公元前17世纪 克里特岛Phaistos圆盘(未知符号加密) • 中国西周“阴符”、北宋五言诗密码 • 1466年 艾伯蒂多表代替密码 • 1883年 克尔克霍…...
基于CNN与VGG16的图像识别快速实现指南
基于CNN与VGG16的图像识别快速实现指南 以下是从零实现代码到原理剖析的完整流程,包含TensorFlow/Keras框架的代码示例与关键优化技巧,满足快速实验需求。 一、核心原理对比 特性CNN(基础模型)VGG16结构深度5-10层(如…...
【内置函数】84个Python内置函数全整理
Python 内置函数全集(完整分类 参数详解 示例) 文章目录 Python 内置函数全集(完整分类 参数详解 示例)一、数值与数学函数abs(x)divmod(a, b)pow(x, y, modNone)round(number[, ndigits])sum(iterable, /, start0)hash(obj) …...
【每天一个知识点】模式识别
“模式识别”是一种从数据中识别出规律、结构或趋势的技术,它广泛应用于人工智能、机器学习、图像处理、语音识别、自然语言处理等领域。简单来说,就是让计算机学会“看出”数据中的规律,比如: 从图像中识别人脸(人脸识…...
Codeforces Educational Round 177 Div. 2 【B题,C待补
B 二分 题意 样例 5 3 10 3 4 2 1 512 找最右边的L下标即可 思路 二分最靠右的L端点,R端点取最右端(n*k处),找到后,答案就是L的位置(pos),(因为如果pos满足,则pos左边的所有下标都满足 代码 const in…...
哈夫曼编码和哈夫曼树
哈夫曼编码(Huffman Coding) 是一种基于字符出现频率的无损数据压缩算法,通过构建哈夫曼树(Huffman Tree) 来生成最优前缀编码,使得高频字符用短编码,低频字符用长编码,从而实现高效…...
中西面点实训室虚拟仿真操作平台
在餐饮行业蓬勃发展的当下,中西面点作为其中极具特色与市场需求的重要分支,对于专业人才的渴望愈发强烈。一个功能完备、设施先进的中西面点实训室,已然成为培养高素质面点专业人才的关键阵地。凯禾瑞华——实训室建设 一、中西面点实训室建设…...
Python字典深度解析:高效键值对数据管理指南
一、字典核心概念解析 1. 字典定义与特征 字典(Dictionary)是Python中基于哈希表实现的无序可变容器,通过键值对存储数据,具有以下核心特性: 键值对结构:{key: value}形式存储数据快…...
C++游戏服务器开发之⑦redis的使用
目录 1.当前进度 2.守护进程 3.进程监控 4.玩家姓名添加文件 5.文件删除玩家姓名 6.redis安装 7.redis存取命令 8.redis链表存取 9.redis程序结构 10.hiredisAPI使用 11.基于redis查找玩家姓名 12.MAKEFILE编写 13.游戏业务实现总结 1.当前进度 2.守护进程 3.进程监…...
模拟投资大师思维:AI对冲基金开源项目详解
这里写目录标题 引言项目概述核心功能详解多样化的AI投资智能体灵活的运行模式透明的决策过程 安装和使用教程环境要求安装步骤基本使用方法运行对冲基金模式运行回测模式 应用场景和实际价值教育和研究价值潜在的商业应用与现有解决方案的对比局限性与发展方向 结论 引言 随着…...
Cocos Creater打包安卓App添加隐私弹窗详细步骤+常见问题处理
最终演示效果,包含所有代码内容 + 常见错误问题处理 点击服务协议、隐私政策,跳转到相关网页, 点击同意进入游戏,不同意关闭应用 一,添加Activity,命名为MyLaunchActivity 二,编写MyLaunchActivity.java的内容 package com.cocos.game.launch;import android.os.Bund…...
Android 热点二维码简单示例
Android 热点二维码简单示例 一、前言 Android 原生设置有热点二维码分享功能,有些系统应用也会有这个需求。 下面看看是如何实现的。 本文是一个比较简单的内容。 二、热点二维码生成实现 1、效果 整个应用就一个普通的Activity,显示一个按钮和二维…...
探秘Python 工匠:案例、技巧与工程实践:解锁Python进阶的通关秘籍
重要的放前面 Python 工匠:案例、技巧与工程实践 探秘Python 工匠:案例、技巧与工程实践:解锁Python进阶的通关秘籍 在Python的编程世界中,从入门小白到技术大牛的进阶之路往往充满挑战。Python工匠:案例、技巧与工…...
JAVAEE(网络原理—UDP报头结构)
我们本篇文章要讲的是UDP的报头结构以及注意事项。 下面呢,我先说一下UDP是什么? 1.UDP是什么? UDP是一种网络协议。网络协议是计算机网络中,为了使不同设备之间能够准确、高效地进行数据交换和通信,而预先制定的一…...
