在搞OSS對象存儲中發現了自身的一些不足(http協議原理 跟 流的概念)

最近在搞OSS對象存儲,發現了自身的一些不足,趁着有空在此作個總結,但願可以幫助到你們!!!

首先解釋下OSS,Object Storage Service(對象存儲服務),通常的雲公司,都會提供OSS的。說的通俗點,就是遠程服務器提供必定的空間專門來存儲文件的,這些文件能夠直接經過url任意時間,任意地點訪問。
而把文件存儲到OSS空間裏,就是使用的http協議。OSS中的Bucket就是Windows系統下的文件夾。html

1、http原理

咱們知道http協議是基於TCP/IP協議的,也就是說,經過http進行數據傳輸,首先須要進行TCP鏈接。TCP鏈接須要進行三次握手,斷開鏈接須要進行四次揮手。前端

關於TCP的三次握手跟四次揮手,話很少說,直接推薦,人家已經寫的很好了。 無需我多說廢話。
TCP的三次握手
TCP的四次揮手
握手要稍微瞭解一下的,否則可能沒法理解下面的keep-alive。
想了解https原理的,推薦完全搞懂https原理算法

http請求信息

http的請求報文,就是發送給服務端的信息,主要包含三個部分:請求行、請求頭部、請求數據
(借用別人的圖)
json

請求行主要包含請求方法(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(認證):當咱們須要訪問其餘公司提供的服務接口時,必需要有這個簽名認證。api

有興趣能夠了解一下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 響應數據:即服務器迴應客戶端的內容。若是咱們請求網頁,則返回網頁內容,若是隻是單純請求數據,則返回相應的數據。服務器

2、.NET中提供的相應的API

WebRequest,HttpWebRequest, WebResponse,HttpWebResponse
這幾個類作爬蟲的話,也常常用到的。可能不少人被這幾個類搞混了。鄙人也是的,怎麼這麼多類,好像還有什麼WebClient等。。。
app

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 ();

3、流的概念

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();

4、認證簽名

關於簽名的,確定會涉及到一些加密算法,base64,sha1,md5等這些算法,這些算法並不須要咱們去掌握,.NET已經提供了相應的API,只需會調用便可,不必去深究究竟是怎麼實現的。
使用其餘公司提供的接口服務,都會有相應的公鑰和私鑰,按照官網文檔來生成相應的認證簽名就能夠了。而後將認證簽名添加到請求頭部裏,即可以訪問其餘公司提供的接口服務了。
通常生成簽名的接口須要在本身的服務端本身寫一個,獲得的簽名與其餘公司服務端生成的簽名進行比對。

5、最後

最後祝你們國慶快樂,玩得開心,國慶Happy!!!