網絡編程---http協議 ---- 陳洪鑫

一. 網絡編程基礎

在移動互聯網時代,幾乎所有應用都需要用到網絡,只有通過網絡跟外界進行數據交互、數據更新,應用才能保持新鮮、活力。一個好的移動網絡應用不僅要有良好的UI和良好的用戶體驗也要具備實時更新數據的能力。網絡編程便是一種實時更新應用數據的常用手段也是開發優秀網絡應用的前提和基礎。

1. 在網絡編程中,有幾個必須掌握的基本概念

客戶端(Client):移動應用(iOS、android等應用)
服務器(Server):爲客戶端提供服務、提供數據、提供資源的機器
請求(Request):客戶端向服務器索取數據的一種行爲
響應(Response):服務器對客戶端的請求做出的反應,一般指返回數據給客戶端

我們通過下面圖片來理解這四者之間的關係



請求數據獲取數據的過程

二. HTTP協議

HTTP協議是在網絡開發中最常用的協議

1. 概念

協議:協議是指計算機通信網絡中兩臺計算機之間進行通信所必須共同遵守的規定或規則,超文本傳輸協議(HTTP)是一種通信協議。

HTTP協議:即超文本傳輸協議(Hypertext transfer protocol)。是一種詳細規定了瀏覽器和萬維網(WWW = World Wide Web)服務器之間互相通信的規則,通過因特網傳送萬維網文檔的數據傳送協議。

HTTP協議作用:HTTP協議是用於從WWW服務器傳輸超文本到本地瀏覽器的傳送協議。它可以使瀏覽器更加高效,使網絡傳輸減少。它不僅保證計算機正確快速地傳輸超文本文檔,還確定傳輸文檔中的哪一部分,以及哪部分內容首先顯示(如文本先於圖形)等。

URL:我們在瀏覽器的地址欄裏輸入的網站地址叫做URL (Uniform Resource Locator,統一資源定位符)。就像每家每戶都有一個門牌地址一樣,每個網頁也都有一個Internet地址。當你在瀏覽器的地址框中輸入一個URL或是單擊一個超級鏈接時,URL就確定了要瀏覽的地址。瀏覽器通過超文本傳輸協議(HTTP),將Web服務器上站點的網頁代碼提取出來,並翻譯成漂亮的網頁。

2.HTTP版本區別

HTTP/0.9和1.0 使用非持續連接,限制每次連接只處理一個請求,服務器對客戶端的請求做出響應後,馬上斷開連接,這種方式可以節省傳輸時間
HTTP/1.1 當前版本。持久連接被默認採用,並能很好地配合代理服務器工作。還支持以管道方式同時發送多個請求,以便降低線路負載,提高傳輸速度。

HTTP/1.1相較於 HTTP/1.0 協議的區別主要體現在:
1 緩存處理
2 帶寬優化及網絡連接的使用
3 錯誤通知的管理
4 消息在網絡中的發送
5 互聯網地址的維護
6 安全性及完整

3.HTTP工作流程

一次HTTP操作稱爲一個事務,其工作過程可分爲四步:

  1. 首先客戶機與服務器需要建立連接。只要單擊某個超級鏈接,HTTP的工作就開始了。
  2. 建立連接後,客戶機發送一個請求給服務器,請求方式的格式爲:統一資源標識符(URL)、協議版本號,後邊是MIME信息包括請求修飾符、客戶機信息和可能的內容。
  3. 服務器接到請求後,給予相應的響應信息,其格式爲一個狀態行,包括信息的協議版本號、一個成功或錯誤的代碼,後邊是MIME信息包括服務器信息、實體信息和可能的內容。
  4. 客戶端接收服務器所返回的信息通過瀏覽器顯示在用戶的顯示屏上,然後客戶機與服務器斷開連接。

如果在以上過程中的某一步出現錯誤,那麼產生錯誤的信息將返回到客戶端,由顯示屏輸出。對於用戶來說,這些過程是由HTTP自己完成的,用戶只要用鼠標點擊,等待信息顯示就可以了。

HTTP通信過程 - 請求詳細內容

HTTP協議規定:1個完整的由客戶端發給服務器的HTTP請求中包含以下內容
請求頭:包含了對客戶端的環境描述、客戶端請求信息等
GET /minion.png HTTP/1.1 // 包含了請求方法、請求資源路徑、HTTP協議版本
Host: 120.25.226.186:32812 // 客戶端想訪問的服務器主機地址
User-Agent: Mozilla/5.0 // 客戶端的類型,客戶端的軟件環境
Accept: text/html // 客戶端所能接收的數據類型
Accept-Language: zh-cn // 客戶端的語言環境
Accept-Encoding: gzip // 客戶端支持的數據壓縮格式

請求體:客戶端發給服務器的具體數據,比如文件數據(POST請求纔會有)

HTTP通信過程 - 響應詳細內容

客戶端向服務器發送請求,服務器應當做出響應,即返回數據給客戶端
HTTP協議規定:1個完整的HTTP響應中包含以下內容
響應頭:包含了對服務器的描述、對返回數據的描述
HTTP/1.1 200 OK // 包含了HTTP協議版本、狀態碼、狀態英文名稱
Server: Apache-Coyote/1.1 // 服務器的類型
Content-Type: image/jpeg // 返回數據的類型
Content-Length: 56811 // 返回數據的長度
Date: Mon, 23 Jun 2014 12:54:52 GMT // 響應的時間

響應體:服務器返回給客戶端的具體數據,比如文件數據
常見響應狀態碼


常見響應狀態碼

注意:HTTP是基於傳輸層的TCP協議,而TCP是一個端到端的面向連接的協議。所謂的端到端可以理解爲進程到進程之間的通信。所以HTTP在開始傳輸之前,首先需要建立TCP連接,而TCP連接的過程需要所謂的“三次握手”。
下圖所示TCP連接的三次握手。


TCP連接的三次握手

簡單來說就是

  1. 客戶端向服務器發送消息,告訴服務器我將要發送數據。
  2. 服務器端接收到客戶端請求後,確認自己準備好接收數據,並告知客戶端,我已經準備好,可以發送請求
  3. 客戶端接受到服務器端已準備好接收的消息後,發送數據給服務器端。

在TCP三次握手之後,建立了TCP連接,此時HTTP就可以進行傳輸了。一個重要的概念是面向連接,既HTTP在傳輸完成之間並不斷開TCP連接。在HTTP1.1中這是默認行爲。

4. HTTP協議的特點

HTTP協議永遠都是客戶端發起請求,服務器回送響應。這樣就限制了使用HTTP協議,無法實現在客戶端沒有發起請求的時候,服務器將消息推送給客戶端。

HTTP協議的主要特點可概括如下:

  1. 簡單快速:因爲HTTP協議簡單,使得HTTP服務器的程序規模小,因而通信速度很快。
  2. 靈活:HTTP允許傳輸任意類型的數據對象。正在傳輸的類型由Content-Type加以標記。
  3. HTTP 0.9和1.0使用非持續連接:限制每次連接只處理一個請求,服務器處理完客戶的請求,並收到客戶的應答後,即斷開連接。採用這種方式可以節省傳輸時間。
    HTTP 1.1使用持續連接:不必爲每個web對象創建一個新的連接,一個連接可以傳送多個對象。

5. URL

URL的全稱是Uniform Resource Locator(統一資源定位符)
URL就是資源的地址、位置。互聯網上的每個資源都有一個唯一的URL,通過這個個URL,能找到互聯網上唯一的一個資源。

URL的基本格式 = 協議://主機地址/路徑
協議:不同的協議,代表着不同的資源查找方式、資源傳輸方式
主機地址:存放資源的主機(服務器)的IP地址(域名)
路徑:資源在主機(服務器)中的具體位置

三. 發送HTTP請求

1.發送HTTP請求的方法

在HTTP/1.1協議中,定義了8種發送HTTP請求的方法
GET、POST、OPTIONS、HEAD、PUT、DELETE、TRACE、CONNECT、PATCH
各個方法的解釋如下(所有方法全爲大寫):
GET: 請求獲取Request-URI所標識的資源
POST: 在Request-URI所標識的資源後附加新的數據

HEAD: 請求獲取由Request-URI所標識的資源的響應消息報頭
PUT: 請求服務器存儲一個資源,並用Request-URI作爲其標識
DELETE: 請求服務器刪除Request-URI所標識的資源
TRACE: 請求服務器回送收到的請求信息,主要用於測試或診斷
CONNECT: 保留將來使用
OPTIONS: 請求查詢服務器的性能,或者查詢與資源相關的選項和需求

根據HTTP協議的設計初衷,不同的方法對資源有不同的操作方式
PUT :增
DELETE :刪
POST:改
GET:查
最常用的是GET和POST(實際上GET和POST都能辦到增刪改查)

2. GET和POST對比和區別

GET和POST的主要區別表現在數據傳遞上

GET:在請求URL後面以?的形式拼接發給服務器的參數,多個參數之間用&隔開。
比如http://www.test.com/login?username=123&pwd=234&type=JSON由於瀏覽器和服務器對URL長度有限制,因此在URL後面附帶的參數是有限制的,通常不能超過1KB

POST:發給服務器的參數全部放在請求體中,理論上,POST傳遞的數據量沒有限制(具體還得看服務器的處理能力)

注意:GET和POST都可以向服務器傳送數據,也都可以從服務器獲取數據

關於URL長度的限制
首先,HTTP協議及URL官方說明均對URL長度限制沒有說明,也就是說GET,POST都對URL長度沒有限制
,但是HTTP客戶端和服務器的實現對URL長度進行了限制,因此我們使用GET請求拼接參數,有時會導致URL過長而無法進行請求。

關於安全問題
並不是POST比GET特別安全,只不過GET傳遞的參數顯示在URL中,我們一眼就可以看到,POST方式看不到是因爲瀏覽器做了限制,我們同樣可以用第三方工具看到POST方式傳遞的數據。

GET 和POST 的選擇
選擇GET和POST的建議
如果僅僅是索取數據(數據查詢),建議使用GET
如果是增加、修改、刪除數據或者傳遞大量數據,比如文件上傳,建議用POST

URL中多值參數和中文輸出

  1. 多值參數
    有時候一個參數名,可能會對應多個值。例如
    http://120.25.226.186:32812/weather?place=Beijing&place=Henan&place=Hunan
    當一個參數有多個值的時候,需要使用下面這樣方式來賦值
    place=beijing&place=shanghai
    服務器的place屬性是一個數組

  2. 中文參數
    當url中有漢字的時候,我們需要先進行中文轉碼
    GET需要轉碼,POST當參數有漢字的時候就不用轉碼了,因爲POST參數在請求體中,但是當url有漢字的時候同樣需要轉碼。

    NSString *urlStr = @"http://120.25.226.186:32812/login2?username=漢字&pwd=520it";
    urlStr =  [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

3. iOS中發送HTTP請求的方案

在iOS中,常見的發送HTTP請求的方案有
蘋果原生(自帶)
NSURLConnection:用法簡單,最古老最經典最直接的一種方案
NSURLSession:功能比NSURLConnection更加強大,蘋果目前比較推薦使用這種技術(2013推出,iOS7開始使用的技術)

CFNetwork:NSURL*的底層,純C語言

第三方框架
AFNetworking:簡單易用,提供了基本夠用的常用功能,維護和使用者多
ASIHttpRequest:外號“HTTP終結者”,功能極其強大,可惜早已停止更新
MKNetworkKit:簡單易用,產自印度,維護和使用者少

爲了提高開發效率,我們開發用的基本是第三方框架,但是我們同樣也需要掌握蘋果原生的請求方案

四. 服務器返回的數據格式

服務器返回給客戶端的數據,一般都是JSON格式或者XML格式(文件下載除外)

1. JSON

什麼是JSON
JSON(JavaScript Object Notation):一種輕量級的數據交換格式,具有良好的可讀和便於快速編寫的特性。可在不同平臺之間進行數據交互。

JSON的格式
JSON的格式很像OC中的字典和數組
{"name" : "jack", "age" : 10}
{"names" : ["jack", "rose", "jim"]}
標準JSON格式的注意點:key必須用雙引號

JSON解析方案
要想從JSON中挖掘出具體數據,需要對JSON進行解析,將JSON數據轉換爲OC數據類型
在iOS中,蘋果爲我們提供了JSON的解析方案 NSJSONSerialization
NSJSONSerialization的常見方法
JSON數據 轉 OC對象

/*
   參數一:JSON數據
   參數二:options 一般填kNilOptions
   參數三:錯誤信息 nil
*/
+ (id)JSONObjectWithData:(NSData *)data options:(NSJSONReadingOptions)opt error:(NSError **)error;

OC對象 轉 JSON數據

+ (NSData *)dataWithJSONObject:(id)obj options:(NSJSONWritingOptions)opt error:(NSError **)error;

2. XML

什麼是XML
擴展標記語言 (Extensible Markup Language, XML) ,用於標記電子文件使其具有結構性的標記語言,可以用來標記數據、定義數據類型,是一種允許用戶對自己的標記語言進行定義的源語言。 XML使用DTD(document type definition)文檔類型定義來組織數據;格式統一,跨平臺和語言,早已成爲業界公認的標準。

XML格式
一個常見的XML文檔一般由以下部分組成

  1. 文檔聲明
    在XML文檔的最前面,必須編寫一個文檔聲明,用來聲明XML文檔的類型
    最簡單的聲明
    <?xml version="1.0" ?>
    用encoding屬性說明文檔的字符編碼
    <?xml version="1.0" encoding="UTF-8" ?>
  2. 元素(Element)
    一個元素包括了開始標籤和結束標籤
    擁有內容的元素:<video>小黃人</video>
    沒有內容的元素:<video></video>
    一個元素可以嵌套若干個子元素(不能出現交叉嵌套)
    規範的XML文檔最多隻有1個根元素,其他元素都是根元素的子孫元素
  3. 屬性(Attribute)

XML解析
要想從XML中提取有用的信息,必須得學會解析XML
XML的解析方式有2種
DOM:一次性將整個XML文檔加載進內存,比較適合解析小文件
SAX:從根元素開始,按順序一個元素一個元素往下解析,比較適合解析大文件

解析XML的工具
蘋果原生NSXMLParser: 使用SAX方式解析,使用簡單
GDataXML: 採用DOM方式解析,該框架由Goole開發,是基於xml2的

1. 使用NSXMLParser解析XML方法和步驟

//解析步驟:
//1 創建一個解析器
NSXMLParser *parser = [[NSXMLParser alloc]initWithData:data];
//2 設置代理
parser.delegate = self;
//3 開始解析
[parser parse];

NSXMLParser代理方法

//1.開始解析XML文檔
-(void)parserDidStartDocument:(nonnull NSXMLParser *)parser
{
}
//2.開始解析XML中某個元素的時候調用,比如<video>
-(void)parser:(nonnull NSXMLParser *)parser didStartElement:(nonnull NSString *)elementName namespaceURI:(nullable NSString *)namespaceURI qualifiedName:(nullable NSString *)qName attributes:(nonnull NSDictionary<NSString *,NSString *> *)attributeDict
{
    //可在此方法中做字典轉模型操作,參數attributeDict存放着元素的屬性
}
//3.當某個元素解析完成之後調用,比如</video>
-(void)parser:(nonnull NSXMLParser *)parser didEndElement:(nonnull NSString *)elementName namespaceURI:(nullable NSString *)namespaceURI qualifiedName:(nullable NSString *)qName
{
}
//4.XML文檔解析結束
-(void)parserDidEndDocument:(nonnull NSXMLParser *)parser
{
}

NSXMLParser採取的是SAX方式解析,特點是事件驅動,下面情況都會通知代理
當掃描到文檔(Document)的開始與結束
當掃描到元素(Element)的開始與結束

2. GDataXML解析XML方法和步驟
GDataXML需要配置環境

  1. 設置libxml2的頭文件搜索路徑(爲了能找到libxml2庫的所有頭文件)
    在Head Search Path中加入/usr/include/libxml2
  2. 設置鏈接參數(自動鏈接libxml2庫)
    在Other Linker Flags中加入-lxml2

使用方法

//1 加載XML文檔(使用的是DOM的方式次性把整個XML加載完畢)
    GDataXMLDocument *doc = [[GDataXMLDocument alloc]initWithData:data options:kNilOptions error:nil];
//2 獲取XML文檔的根元素,根據根元素取出XML中的每個子元素
  NSArray * elements = [doc.rootElement elementsForName:@"video"];
//3 取出每個子元素的屬性並轉換爲模型
for (GDataXMLElement *ele in elements) {
    //4 把轉換好的模型添加到tableView的數據源self.videos數組中
    [self.videos addObject:video];
}

3. JSON和XML比較

同一份數據,既可以用JSON來表示,也可以用XML來表示
相比之下,JSON的體積小於XML,並且易於解析,傳輸速度也快,所以服務器返回給移動端的數據格式以JSON居多。

五. HTTP應用

1. 斷點續傳的實現原理

HTTP協議設置請求頭內容,支持只請求某個資源的某一部分。
Range 請求的資源範圍;
Content-Range 響應的資源範圍;
在連接斷開重連時,客戶端只請求該資源未下載的部分,而不是重新請求整個資源,來實現斷點續傳。
分塊請求資源實例:
Eg1:Range: bytes=306302- :請求這個資源從306302個字節到末尾的部分;
Eg2:Content-Range: bytes 306302-604047/604048:響應中指示攜帶的是該資源的第306302-604047的字節,該資源共604048個字節;
客戶端通過併發的請求相同資源的不同片段,來實現對某個資源的併發分塊下載。從而達到快速下載的目的。目前流行的FlashGet和迅雷基本都是這個原理。

2. 多線程下載的原理

下載工具開啓多個發出HTTP請求的線程,每個http請求只請求資源文件的一部分,例如:Content-Range: bytes 20000-40000/47000;
最後合併每個線程下載的文件。

六. HTTPS

1. HTTPS簡介

HTTPS(全稱:Hyper Text Transfer Protocol over Secure Socket Layer),是以安全爲目標的HTTP通道,簡單講是HTTP的安全版。即HTTP下加入SSL層,HTTPS的安全基礎是SSL,因此加密的詳細內容就需要SSL。

2. HTTPS通信過程


HTTPS通信過程

3. HTTPS與HTTP的區別

超文本傳輸協議HTTP協議被用於在Web瀏覽器和網站服務器之間傳遞信息。HTTP協議以明文方式發送內容,不提供任何方式的數據加密,如果攻擊者截取了Web瀏覽器和網站服務器之間的傳輸報文,就可以直接讀懂其中的信息,因此HTTP協議不適合傳輸一些敏感信息,比如信用卡號、密碼等。

爲了解決HTTP協議的這一缺陷,需要使用另一種協議:安全套接字層超文本傳輸協議HTTPS。爲了數據傳輸的安全,HTTPS在HTTP的基礎上加入了SSL協議,SSL依靠證書來驗證服務器的身份,併爲瀏覽器和服務器之間的通信加密。

HTTPS和HTTP的區別主要爲以下四點:

一、https協議需要到ca申請證書,一般免費證書很少,需要交費。
二、http是超文本傳輸協議,信息是明文傳輸,https 則是具有安全性的ssl加密傳輸協議。
三、http和https使用的是完全不同的連接方式,用的端口也不一樣,前者是80,後者是443。
四、http的連接很簡單,是無狀態的;HTTPS協議是由SSL+HTTP協議構建的可進行加密傳輸、身份認證的網絡協議,比http協議安全。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章