• 在搞OSS对象存储中发现了自身的一些不足(http协议原理 跟 流的概念)


    最近在搞OSS对象存储,发现了自身的一些不足,趁着有空在此做个总结,希望能够帮助到大家!!!

    首先解释下OSS,Object Storage Service(对象存储服务),一般的云公司,都会提供OSS的。说的通俗点,就是远程服务器提供一定的空间专门来存储文件的,这些文件可以直接通过url任意时间,任意地点访问。
    而把文件存储到OSS空间里,就是使用的http协议。OSS中的Bucket就是Windows系统下的文件夹。

    一、http原理

    我们知道http协议是基于TCP/IP协议的,也就是说,通过http进行数据传输,首先需要进行TCP连接。TCP连接需要进行三次握手,断开连接需要进行四次挥手。

    关于TCP的三次握手跟四次挥手,话不多说,直接推荐,人家已经写的很好了。 无需我多说废话。
    TCP的三次握手
    TCP的四次挥手
    握手要稍微了解一下的,不然可能无法理解下面的keep-alive。
    想了解https原理的,推荐彻底搞懂https原理

    http请求信息

    http的请求报文,就是发送给服务端的信息,主要包含三个部分:请求行、请求头部、请求数据
    (借用别人的图)

    请求行主要包含请求方法(GET,POST,PUT,DELETE),URL跟http协议版本
    请求头部:

    在这里,稍微了解一下
    Accept指的是,本次请求,接受哪些格式的文件
    Accept-Encoding :接受的文件压缩格式
    Host :域名,主机名

    比较重要的请求头部
    Connection :采用的连接方式
    Content-Type(请求编码方式): application/x-www-form-urlencoded(只能是键值对方式) application/form-data(可以包含文件)
    Content-Length(请求数据长度): 35
    Authorization(认证):当我们需要访问其他公司提供的服务接口时,必须要有这个签名认证。

    有兴趣可以了解一下http协议版本

    在1.0版本下,每次发送一个请求时都要进行一次TCP三次握手,然后再进行数据传输,TCP连接消耗成本较高。为了能够复用TCP的连接, 因而诞生了1.1版本,主要的变化就是可以进行持久连接,也就是说,一次TCP连接可以发送多个http请求,但服务端仍然一次只能处理一个请求,依次进行。只需设置请求头部的Connection的值为keep-alive,即可。如果超过一定的时间没有继续发送http请求,TCP连接会自动关闭,当然也可以设置主动关闭。 至于未来的2.0版本,最大的变化便是增加双工模式,使用多路复用技术,也就是说不仅客户端能够同时发送多个请求,服务端也能同时处理多个请求 2.0版本的还没捂热,3.0已经来了,学不动了呀。至于3.0是个什么情况,小爷也不知道。

    http响应信息

    http的响应报文就是服务端给http请求的回应信息,主要包含状态行、响应头部、响应数据。
    1 状态行:协议版本、状态码、简要描述,例如:HTTP/1.1 200 OK
    常见的状态码:200,一切正常 400,客户端错误 404,相关资源文件未找到 500,服务端错误

    2 响应头部:例如:Content-Type: text/plain,json等

    3 响应数据:即服务器回应客户端的内容。如果我们请求网页,则返回网页内容,如果只是单纯请求数据,则返回相应的数据。

    二、.NET中提供的相应的API

    WebRequest,HttpWebRequest, WebResponse,HttpWebResponse
    这几个类做爬虫的话,也经常用到的。可能很多人被这几个类搞混了。鄙人也是的,怎么这么多类,好像还有什么WebClient等。。。

    WebRequest类,这个类是一个抽象类,是对URI发出请求而进行了一种抽象,跟动物是对狗狗、猫咪、小老鼠等的一种抽象是一个道理。
    面向对象的思想很是伟大,他来源于真实世界的抽象,当然我们也可以用面向对象的思想来反观世界。
    很是精彩!!!

    HttpWebRequest类,这个类是WebRequest类的派生类,专门用于进行http特定的实现。里面有相应的属性和方法。
    WebResponse HttpWebResponse 同理。

    //请求
    HttpWebRequest request =(HttpWebRequest)WebRequest.Create("http://www.contoso.com/");
    request.KeepAlive = false;//设置是否为持久连接
    request.Method = "POST";
    string authorization="";//获取认证签名
    request.Headers.Add("Authorization", authorization);//将认证签名添加到请求头部
    
    Stream requestStream = request.GetRequestStream();//获取请求流
    
    string postData = "nickName=打游戏也要有梦想&hobby=coding";//添加请求数据
    ASCIIEncoding encoding = new ASCIIEncoding ();
    byte[] byte1 = encoding.GetBytes (postData);
    request.ContentType = "application/x-www-form-urlencoded";//请求编码方式
    request.ContentLength = byte1.Length;//请求数据长度
    
    requestStream.Write (byte1, 0, byte1.Length);//给请求流中添加请求数据
    requestStream.Close();//关闭请求流
    
    
    //响应
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    Stream responseStream = response.GetResponseStream();//获取响应流
    StreamReader readStream = new StreamReader (responseStream, Encoding.UTF8);//读取响应流
    string responseText=readStream.ReadToEnd();//响应信息
    response.Close ();
    readStream.Close ();
    
    
    

    三、流的概念

    http协议传输的数据其实就是通过流来传输的。流这东西,有数据流、文件流、读写流等,的确很是抽象,不知道到底是个什么东西,搞了半天,发现被这个高大上的名字给忽悠了。
    所谓的流呢,其实就是字节序列,就是字节数组。搞后端的应该都知道,需要将返回的对象进行序列化后再传输到前端。其中的序列化,便是将对象转为字节序列(流),来进行传输。这么说吧,http传输的数据都是通过流来传输的。
    那大家可能会有个问题,http协议中是怎么上传下载文件的,通过类HttpWebRequest,我们得到一个对象,接下来我们得到请求流,然后把文件添加到这个请求流里,便可以了;同理,下载文件也是如此,得到响应流,然后将流写入到一个新建的文件流便可以了。

    //通过http上传文件,只需在请求流中写入需要上传的文件    fileStream为需要上传的文件转为流的形式
    Stream requestStream = request.GetRequestStream();//请求流
    //上传文件
    byte[] buffer = new byte[64 * 1024];//设置缓存区大小,据说64KB最好(只是据说,没有亲测)
    int read = fileStream.Read(buffer, 0, buffer.Length);
    while (read > 0)
    {
        requestStream.Write(buffer, 0, red);//在请求流中继续写入文件流
        read = fileStream.Read(buffer, 0, buffer.Length);
    }
    //关闭流
    fileStream.Close();
    requestStream.Close();
    
    //通过http下载文件,只需将响应流中写入到新建的文件流中
    Stream responseStream = response.GetResponseStream();//获取响应流
    
    string fileName="";//新建的文件名,包含路径名称和文件名以及后缀
    FileStream fileStream = new FileStream(fileName, FileMode.Create, FileAccess.Write);//创建文件流
    byte[] buffer = new byte[64 * 1024];//设置缓存区大小,据说64KB最好(只是据说,没有亲测)
    int totalSize = 0;//文件总大小
    int size = responseStream.Read(buffer, 0, buffer.Length);
    while (size > 0)
    {
        totalSize += size;
        fileStream.Write(buffer, 0, size);//将响应流中写入到新建的文件流中
        size = responseStream.Read(buffer, 0, buffer.Length);
    }
    fileStream.Close();
    responseStream.Close();
    

    四、认证签名

    关于签名的,肯定会涉及到一些加密算法,base64,sha1,md5等这些算法,这些算法并不需要我们去掌握,.NET已经提供了相应的API,只需会调用即可,没必要去深究到底是怎么实现的。
    使用其他公司提供的接口服务,都会有相应的公钥和私钥,按照官网文档来生成相应的认证签名就可以了。然后将认证签名添加到请求头部里,便可以访问其他公司提供的接口服务了。
    一般生成签名的接口需要在自己的服务端自己写一个,得到的签名与其他公司服务端生成的签名进行比对。

    五、最后

    最后祝大家国庆快乐,玩得开心,国庆Happy!!!

  • 相关阅读:
    Maven项目类型和JAVASE项目和JAVAEE项目的关系
    使用faker 生成测试数据
    python 面向对象
    python csv读写
    分治
    django 部署
    js 时间格式转换
    python环境
    枚举
    递归
  • 原文地址:https://www.cnblogs.com/ywjbokeyuan/p/13746427.html
Copyright © 2020-2023  润新知