详解与HTTP服务器相关操作

news2025/4/20 13:33:32

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();
            }
            else
                print("文件不能用" + 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("下载成功");
            }
            else
                print("下载失败");
        }
        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 update
    void 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("上传成功");
        else
            print("上传失败"+res.StatusCode);

        #endregion

    }

    // Update is called once per frame
    void 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();
                }
                else
                    Debug.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 update
    void 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 frame
    void Update()
    {
        
    }
}

这样就实现了对Http服务器的操作了

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

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

相关文章

Moldflow模流分析教程

Moldflow模流分析教程&#xff1a;

计算机网络 3-4 数据链路层(局域网)

4.1 局域网LAN 特点 1.覆盖较小的地理范围 2.较低的时延和误码率 3.局域网内的各节点之间 4.支持单播、广播、多播 分类 关注三要素 &#xff08;出题点&#xff09; ①拓扑结构 ②传输介质 ③介质访问控制方式 硬件架构 4.2 以太网 4.2.1 层次划分 4.2.2 物理层标准…

单片机AIN0、AIN1引脚功能

目录 1. 模拟-数字转换器&#xff08;ADC&#xff09; 2. 交流电源&#xff08;AC&#xff09; 总结 这两部分有什么区别&#xff1f; 在这个电路图中&#xff0c;两个部分分别是模拟-数字转换器&#xff08;ADC&#xff09;和交流电源&#xff08;AC&#xff09;。以下是这…

如何增加 Elasticsearch 中的 primary shard 数量

作者&#xff1a;来自 Elastic Kofi Bartlett 探索增加 Elasticsearch 中 primary shard 数量的方法。 更多阅读&#xff1a; Elasticsearch&#xff1a;Split index API - 把一个大的索引分拆成更多分片 Elasticsearch&#xff1a;通过 shrink API 减少 shard 数量来缩小 El…

Java 并发性能优化:线程池的最佳实践

Java 并发性能优化&#xff1a;线程池的最佳实践 在 Java 并发编程的世界里&#xff0c;线程池堪称提高应用性能与稳定性的神器。恰如其分地运用线程池&#xff0c;能让我们在多线程任务调度时游刃有余&#xff0c;既能避免线程频繁创建销毁带来的开销&#xff0c;又能合理管控…

【综述】一文读懂卷积神经网络(CNN)

卷积神经网络&#xff08;Convolutional Neural Networks, CNN&#xff09;是一类包含卷积计算且具有深度结构的前馈神经网络&#xff08;Feedforward Neural Networks&#xff09;&#xff0c;是深度学习&#xff08;deep learning&#xff09;的代表算法之一。本文旨在介绍CN…

阿里云集群开启debug

1、安装 kubectl Macos brew install kubectl Windows&#xff1a; https://kubernetes.io/zh-cn/docs/tasks/tools/install-kubectl-windows/ 下载后&#xff0c;放到任意目录 2、配置连接信息 mac 将以下内容复制到计算机 $HOME/.kube/config 文件下: windows 不同集…

Unity之如何实现RenderStreaming视频推流

文章目录 前言引入 UnityRenderStreaming 的好处教程步骤 1:设置环境步骤 2: 创建项目步骤 3:安装软件包步骤 5:下载示例步骤 6:检查配置环境步骤 7:打开推流场景步骤 8: 准备用于流式传输的WebServer应用程序步骤 9: 运行 示例场景步骤 10:检查视频是否在浏览器中显示…

【java实现+4种变体完整例子】排序算法中【桶排序】的详细解析,包含基础实现、常见变体的完整代码示例,以及各变体的对比表格

以下是桶排序的详细解析&#xff0c;包含基础实现、常见变体的完整代码示例&#xff0c;以及各变体的对比表格&#xff1a; 一、桶排序基础实现 原理 将数据分到有限数量的桶中&#xff0c;每个桶内部使用其他排序算法&#xff08;如插入排序或快速排序&#xff09;&#xf…

计算机三级:信息安全基础技术与原理(2.1密码技术简单梳理)

以下是密码学发展历程的表格归纳: ​发展阶段​时间范围​关键节点与标志性技术​技术突破与核心贡献​古典密码时期古代至19世纪• 公元前17世纪 克里特岛Phaistos圆盘(未知符号加密) • 中国西周“阴符”、北宋五言诗密码 • 1466年 艾伯蒂多表代替密码 • 1883年 克尔克霍…

【每天一个知识点】模式识别

“模式识别”是一种从数据中识别出规律、结构或趋势的技术&#xff0c;它广泛应用于人工智能、机器学习、图像处理、语音识别、自然语言处理等领域。简单来说&#xff0c;就是让计算机学会“看出”数据中的规律&#xff0c;比如&#xff1a; 从图像中识别人脸&#xff08;人脸识…

Codeforces Educational Round 177 Div. 2 【B题,C待补

B 二分 题意 样例 5 3 10 3 4 2 1 512 找最右边的L下标即可 思路 二分最靠右的L端点&#xff0c;R端点取最右端(n*k处)&#xff0c;找到后&#xff0c;答案就是L的位置(pos)&#xff0c;&#xff08;因为如果pos满足&#xff0c;则pos左边的所有下标都满足 代码 const in…

哈夫曼编码和哈夫曼树

哈夫曼编码&#xff08;Huffman Coding&#xff09; 是一种基于字符出现频率的无损数据压缩算法&#xff0c;通过构建哈夫曼树&#xff08;Huffman Tree&#xff09; 来生成最优前缀编码&#xff0c;使得高频字符用短编码&#xff0c;低频字符用长编码&#xff0c;从而实现高效…

中西面点实训室虚拟仿真操作平台

在餐饮行业蓬勃发展的当下&#xff0c;中西面点作为其中极具特色与市场需求的重要分支&#xff0c;对于专业人才的渴望愈发强烈。一个功能完备、设施先进的中西面点实训室&#xff0c;已然成为培养高素质面点专业人才的关键阵地。凯禾瑞华——实训室建设 一、中西面点实训室建设…

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 原生设置有热点二维码分享功能&#xff0c;有些系统应用也会有这个需求。 下面看看是如何实现的。 本文是一个比较简单的内容。 二、热点二维码生成实现 1、效果 整个应用就一个普通的Activity&#xff0c;显示一个按钮和二维…

JAVAEE(网络原理—UDP报头结构)

我们本篇文章要讲的是UDP的报头结构以及注意事项。 下面呢&#xff0c;我先说一下UDP是什么&#xff1f; 1.UDP是什么&#xff1f; UDP是一种网络协议。网络协议是计算机网络中&#xff0c;为了使不同设备之间能够准确、高效地进行数据交换和通信&#xff0c;而预先制定的一…

通过docker create与export来分析诊断故障镜像

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编…