? ? ? ? 2019年即將結(jié)束,作為移動端開發(fā),我們常常需要與后臺進(jìn)行網(wǎng)絡(luò)數(shù)據(jù)的通信,在我們開發(fā)的過程中,常常只是通過一個url+參數(shù),然后就等待網(wǎng)路返回各種類型的數(shù)據(jù),那么我們有沒有更加深入的了解過網(wǎng)絡(luò)通信在底層的具體實現(xiàn)呢。
? ? ? ?下面我就幫大家梳理一下網(wǎng)絡(luò)通信相關(guān)的知識點,里面有些不太重要的可能就一筆帶過,個人認(rèn)為比較重要的就會詳細(xì)的解析相關(guān)知識點,由于內(nèi)容比較多,我把內(nèi)容分為三篇文章分享出來,希望大家喜歡。
? ? ? ? 前面的文章:網(wǎng)絡(luò)通信相關(guān)知識詳解(一)已經(jīng)總結(jié)了前六個部分的內(nèi)容,這篇文章是本系列三篇文章的第二篇。
相關(guān)知識點匯總:
一、手機(jī)與外界通信的手段
二、描述一次網(wǎng)絡(luò)請求的流程
三、網(wǎng)絡(luò)七層模型介紹
四、網(wǎng)絡(luò)相關(guān)設(shè)備詳解(路由器,交換機(jī),網(wǎng)橋,網(wǎng)關(guān))
五、TCP/IP協(xié)議族與相關(guān)知識(三次握手,四次揮手,流量控制,擁塞控制)
六、cookie,sessionId與token的區(qū)別
七、網(wǎng)絡(luò)數(shù)據(jù)傳輸類型的處理(文字,圖片,實時音頻流,實時視頻流,文件)
八、數(shù)據(jù)指紋,數(shù)據(jù)簽名,數(shù)字證書的概念
九、Base64、對稱加密算法、非對稱加密算法、數(shù)據(jù)摘要的概念
十、Http與Https知識點詳解
十一、基于TCP的Socket與基于UDP的Socket通信
十二、常見網(wǎng)絡(luò)攻擊手段與防護(hù)(重放攻擊,中間人攻擊,流量劫持)
十三、HttpClient,HttpUriConnection與Okhttp的區(qū)別
十四、Http 1.0,Http 1.1,Http 2.0,SPDY,Http 3.0的區(qū)別
十五、網(wǎng)絡(luò)請求框架對比:AndroidAsync-httpClient,Volley,Okhttp,Retrofit
十六、Bio,Nio,Aio的區(qū)別
十七、網(wǎng)絡(luò)性能優(yōu)化
十八、擴(kuò)展閱讀
七、網(wǎng)絡(luò)數(shù)據(jù)傳輸類型的處理(文字,圖片,音頻流,視頻流,文件)
第一種:文字類型(XML、JSON、Protobuf)
概念:什么是 XML?
XML 指可擴(kuò)展標(biāo)記語言(EXtensible Markup Language)
XML 是一種標(biāo)記語言,很類似 HTML
XML 的設(shè)計宗旨是傳輸數(shù)據(jù),而非顯示數(shù)據(jù)
XML 標(biāo)簽沒有被預(yù)定義。您需要自行定義標(biāo)簽。
XML 被設(shè)計為具有自我描述性。
XML 是 W3C 的推薦標(biāo)準(zhǔn)
附加:XML 被設(shè)計用來傳輸和存儲數(shù)據(jù)。
XML文檔內(nèi)容如下:
<apps>
?<app>
???<id>1</id>
???<name>Google maps</name>
???<version>1.0</version>
?</app>
?<app>
????<id>2</id>
????<name>chrome</name>
????<version>2.1</version>
?</app>
?<app>
????<id>3</id>
????<name>google play</name>
????<version>3.1</version>
?</app>
</apps>
Android 提供了三種解析XML的方式:
第一種:SAX
介紹:SAX解析器是一種基于事件的解析器,事件驅(qū)動的流式解析方式是,從文件的開始順序解析到文檔的結(jié)束,不可暫?;虻雇恕?/p>
優(yōu)點:解析速度快,占用內(nèi)存少。非常適合在Android移動設(shè)備中使用。
缺點:不會記錄標(biāo)簽的關(guān)系,而要讓你的應(yīng)用程序自己處理,這樣就增加了你程序的負(fù)擔(dān)。
工作原理:對文檔進(jìn)行順序掃描,當(dāng)掃描到文檔(document)開始與結(jié)束、元素(element)開始與結(jié)束、文檔 (document)結(jié)束等地方時通知事件處理函數(shù),由事件處理函數(shù)做相應(yīng)動作,然后繼續(xù)同樣的掃描,直至文檔結(jié)束。
第二種:PULL
介紹:PULL解析器的運(yùn)行方式和SAX類似,都是基于事件的模式。不同的是,在PULL解析過程中返回的是數(shù)字,且我們需要自己獲取產(chǎn)生的事件然后做相應(yīng)的操作,而不像SAX那樣由處理器觸發(fā)一種事件的方法,執(zhí)行我們的代碼。
優(yōu)點:PULL解析器小巧輕便,解析速度快,簡單易用,非常適合在Android移動設(shè)備中使用,Android系統(tǒng)內(nèi)部在解析各種XML時也是用PULL解析器,Android官方推薦開發(fā)者們使用Pull解析技術(shù)。
第三種:DOM
介紹:DOM,即對象文檔模型,它是將整個XML文檔載入內(nèi)存(所以效率較低,不推薦使用),每一個節(jié)點當(dāng)做一個對象,結(jié)合代碼分析。
優(yōu)點:由于DOM在內(nèi)存中以樹形結(jié)構(gòu)存放,因此檢索和更新效率會更高。
缺點:但是對于特別大的文檔,解析和加載整個文檔將會很耗資源。 當(dāng)然,如果XML文件的內(nèi)容比較小,采用DOM是可行的。
工作原理:使用DOM對XML文件進(jìn)行操作時,首先要解析文件,將文件分為獨(dú)立的元素、屬性和注釋等,然后以節(jié)點樹的形式在內(nèi)存中對XML文件進(jìn)行表示,就可以通過節(jié)點樹訪問文檔的內(nèi)容,并根據(jù)需要修改文檔。
總結(jié):DOM方式最直觀和容易理解,但是只適合XML文檔較小的時候使用,而SAX方式更適合在移動終端系統(tǒng)中使用,因為相比DOM占用內(nèi)存少,適合處理比較大的XML文檔,最后的Pull方式使用場合和SAX類似,但是更適合需要提前結(jié)束XML文檔解析的場合。
JSON數(shù)據(jù)格式:
概念:JSON(JavaScript Object Notation, JS 對象簡譜) 是一種輕量級的數(shù)據(jù)交換格式。采用完全獨(dú)立于編程語言的文本格式來存儲和表示數(shù)據(jù)。簡潔和清晰的層次結(jié)構(gòu)使得 JSON 成為理想的數(shù)據(jù)交換語言。 易于人閱讀和編寫,同時也易于機(jī)器解析和生成,并有效地提升網(wǎng)絡(luò)傳輸效率。
JSON 語法規(guī)則:在 JS 語言中,一切都是對象。因此,任何支持的類型都可以通過JSON 來表示,例如字符串、數(shù)字、對象、數(shù)組等。
常見數(shù)據(jù)類型:
{
"people":[
{
"firstName": "Brett",
"lastName":"McLaughlin"??????
},
{
"firstName":"Jason",
"lastName":"Hunter"
}
]
}
解析json數(shù)據(jù)的開源框架:
1、Gson(https://github.com/google/gson)
2、fastjson(https://github.com/alibaba/fastjson)
Protobuf:是一種靈活高效可序列化的數(shù)據(jù)協(xié)議,相于XML,具有更快、更簡單、更輕量級等特性。支持多種語言,只需定義好數(shù)據(jù)結(jié)構(gòu),利用Protobuf框架生成源代碼,就可很輕松地實現(xiàn)數(shù)據(jù)結(jié)構(gòu)的序列化和反序列化。一旦需求有變,可以更新數(shù)據(jù)結(jié)構(gòu),而不會影響已部署程序。(谷歌推出)
優(yōu)點:Protobuf是一種平臺無關(guān)、語言無關(guān)、可擴(kuò)展且輕便高效的序列化數(shù)據(jù)結(jié)構(gòu)的協(xié)議,可以用于網(wǎng)絡(luò)通信和數(shù)據(jù)存儲。
Protocol Buffer總結(jié):

Android網(wǎng)絡(luò)請求框架匯總:

備注:RESTFUL是一種網(wǎng)絡(luò)應(yīng)用程序的設(shè)計風(fēng)格和開發(fā)方式,基于HTTP,可以使用XML格式定義或JSON格式定義。RESTFUL適用于移動互聯(lián)網(wǎng)廠商作為業(yè)務(wù)使能接口的場景,實現(xiàn)第三方OTT調(diào)用移動網(wǎng)絡(luò)資源的功能,動作類型為新增、變更、刪除所調(diào)用資源。
? ? ? ?后續(xù)會詳細(xì)區(qū)分不同框架的區(qū)別,這里簡單看下圖就好。
第二種:圖片類型(webP、jpeg、png,git動態(tài)圖)
框架一:Universal-Image-Loader
優(yōu)點:
1、支持下載進(jìn)度監(jiān)聽;
2、可以在 View 滾動中暫停圖片加載;
3、默認(rèn)實現(xiàn)多種內(nèi)存緩存算法這幾個圖片緩存都可以配置緩存算法,不過 ImageLoader 默認(rèn)實現(xiàn)了較多緩存算法,如 Size 最大先刪除、使用最少先刪除、最近最少使用、先進(jìn)先刪除、時間最長先刪除等;
4、支持本地緩存文件名規(guī)則定義;
缺點:
1、不支持GIF圖片加載,緩存機(jī)制沒有和http的緩存很好的結(jié)合,完全是自己的一套緩存機(jī)制。
框架二:Picasso
優(yōu)點:
1、自帶統(tǒng)計監(jiān)控功能,支持圖片緩存使用的監(jiān)控,包括緩存命中率、已使用內(nèi)存大小、節(jié)省的流量等。
2、支持優(yōu)先級處理
3、支持延遲到圖片尺寸計算完成加載
4、支持飛行模式、并發(fā)線程數(shù)根據(jù)網(wǎng)絡(luò)類型而變,手機(jī)切換到飛行模式或網(wǎng)絡(luò)類型變換時會自動調(diào)整線程池最大并發(fā)數(shù)。
5、“無”本地緩存。Picasso 自己沒有實現(xiàn)本地緩存,而由okhttp 去實現(xiàn),這樣的好處是可以通過請求 Response Header 中的 Cache-Control 及 Expired 控制圖片的過期時間。
缺點:
1、不支持GIF,默認(rèn)使用ARGB_8888格式緩存圖片,緩存體積大。
框架三:Glide(官方推薦)
優(yōu)點:
1、圖片緩存->媒體緩存 ,支持 Gif、WebP、縮略圖。甚至是 Video。
2、支持優(yōu)先級處理
3、與 Activity/Fragment 生命周期一致,支持 trimMemory
4、支持 okhttp、Volley。Glide 默認(rèn)通過 UrlConnection 獲取數(shù)據(jù),可以配合 okhttp 或是 Volley 使用。實際 ImageLoader、Picasso 也都支持 okhttp、Volley。
5、內(nèi)存友好,內(nèi)存緩存更小圖片,圖片默認(rèn)使用默認(rèn) RGB565 而不是 ARGB888
缺點:
1、清晰度差。
框架四:Fresco
優(yōu)點:
1、圖片存儲在安卓系統(tǒng)的匿名共享內(nèi)存,而不是虛擬機(jī)的堆內(nèi)存中,所以不會因為圖片加載而導(dǎo)致oom,同時也減少垃圾回收器頻繁調(diào)用回收Bitmap導(dǎo)致的界面卡頓,性能更高。
2、漸進(jìn)式加載JPEG圖片, 支持圖片從模糊到清晰加載。
3、圖片可以以任意的中心點顯示在ImageView, 而不僅僅是圖片的中心。
4、JPEG圖片改變大小也是在native進(jìn)行的, 不是在虛擬機(jī)的堆內(nèi)存, 同樣減少OOM。
5、很好的支持GIF圖片的顯示。
缺點:
6、框架較大, 影響Apk體積,使用較繁瑣
第三種:音頻流與視頻流
一個實時音視頻應(yīng)用共包括幾個環(huán)節(jié):

? ? ? ? 播放聲音可以使用 MediaPlayer 和 AudioTrack,兩者都提供 Java API 給應(yīng)用開發(fā)者使用。兩者的差別在于:MediaPlayer 可以播放多種格式的音源,如 mp3、flac、wma、ogg、wav 等,而 AudioTrack 只能播放解碼后的 PCM 數(shù)據(jù)流。從上面 Android 音頻系統(tǒng)架構(gòu)圖來看:MediaPlayer 在 Native 層會創(chuàng)建對應(yīng)的音頻解碼器和一個 AudioTrack,解碼后的數(shù)據(jù)交由 AudioTrack 輸出。所以 MediaPlayer 的應(yīng)用場景更廣,一般情況下使用它也更方便;只有一些對聲音時延要求非常苛刻的應(yīng)用場景才需要用到 AudioTrack。
AudioTrack 播放音頻時會有兩種方式:
1、MODE_STATIC:應(yīng)用進(jìn)程將回放數(shù)據(jù)一次性付給 AudioTrack,適用于數(shù)據(jù)量小、時延要求高的場景
2、MODE_STREAM:用進(jìn)程需要持續(xù)調(diào)用 write() 寫數(shù)據(jù)到 FIFO,寫數(shù)據(jù)時有可能遭遇阻塞(等待 AudioFlinger::PlaybackThread 消費(fèi)之前的數(shù)據(jù)),基本適用所有的音頻場景。
視頻流:
? ? ? ?視頻編解碼的作用:就是在設(shè)備的攝像頭采集畫面和前處理后,將圖像進(jìn)行壓縮,進(jìn)行數(shù)字編碼,用于傳輸。編解碼器的優(yōu)劣基本在于:壓縮效率的高低,速度和功耗。
? ? ? ?主流的視頻編碼器分為3個系列:VPx(VP8,VP9),H.26x(H.264,H.265),AVS(AVS1.0,AVS2.0)。VPx系列是由Google開源的視頻編解碼標(biāo)準(zhǔn)。在保證相同質(zhì)量情況下,VP9相比VP8碼率減少約50%。H.26x系列在硬件支持上比較廣泛,H.265的編碼效率能比上一代提高了30-50%,但是復(fù)雜度和功耗會比上一代大很多,所以純軟件編碼實現(xiàn)的話有一定瓶頸,現(xiàn)有的技術(shù)下,還是需要依靠硬件編解碼為主。
開源項目:
1、Vitamio:https://github.com/yixia/VitamioBundle(視頻播放框架)
2、JieCaoVideoPlayer:https://github.com/lipangit/JieCaoVideoPlayer(播放器控件)
3、GSYVideoPlayer:https://github.com/CarGuo/GSYVideoPlayer(播放器控件)
第四種:文件類型
單線程下載:(系統(tǒng)默認(rèn))
Android中的文件下載——DownLoadManager
多線程下載:
FileDownloader:https://github.com/lingochamp/FileDownloader
八、數(shù)據(jù)指紋,數(shù)據(jù)簽名,數(shù)據(jù)證書的概念
數(shù)據(jù)指紋:采用某種摘要算法,將明文轉(zhuǎn)化為固定長度的字符,摘要也被稱為指紋,相同的文件內(nèi)容和文件名具有相同的指紋。
數(shù)據(jù)簽名:就是只有信息的發(fā)送者才能產(chǎn)生的別人無法偽造的一段數(shù)字串,這段數(shù)字串同時也是對信息的發(fā)送者發(fā)送信息真實性的一個有效證明,數(shù)字簽名是非對稱密鑰加密技術(shù)與數(shù)字摘要技術(shù)的應(yīng)用。
使用:對非對稱加密技術(shù)與數(shù)字摘要技術(shù)的綜合運(yùn)用,將信息先用摘要算法生成摘要信息,然后用私鑰加密,然后將密文和原文一起發(fā)送,然后接受方用公鑰獲得摘要信息,使用相同的摘要算法對原文產(chǎn)生摘要,然后對比兩者,如果相同說明內(nèi)容是完整的。

數(shù)字簽名的作用:
1、保證信息是由簽名者自己簽名發(fā)送的,簽名者不能否認(rèn)或難以否認(rèn)。
2、接收方可以驗證信息自簽發(fā)后到收到為止未曾做過任何修改,簽發(fā)的文件是真實文件。
數(shù)字證書:數(shù)字證書就是互聯(lián)網(wǎng)通訊中標(biāo)志通訊各方身份信息的一串?dāng)?shù)字,提供了一種在Internet上驗證通信實體身份的方式,數(shù)字證書不是數(shù)字身份證,而是身份認(rèn)證機(jī)構(gòu)蓋在數(shù)字身份證上的一個章或?。ɑ蛘哒f加在數(shù)字身份證上的一個簽名)。它是由權(quán)威機(jī)構(gòu)——CA機(jī)構(gòu),又稱為證書授權(quán)(Certificate Authority)中心發(fā)行的,人們可以在網(wǎng)上用它來識別對方的身份。
使用:以數(shù)字證書為核心的加密技術(shù)(加密傳輸、數(shù)字簽名、數(shù)字信封等安全技術(shù))可以對網(wǎng)絡(luò)上傳輸?shù)男畔⑦M(jìn)行加密和解密、數(shù)字簽名和簽名驗證,確保網(wǎng)上傳遞信息的機(jī)密性、完整性及交易的不可抵賴性。使用了數(shù)字證書,即使您發(fā)送的信息在網(wǎng)上被他人截獲,甚至您丟失了個人的賬戶、密碼等信息,仍可以保證您的賬戶、資金安全。
數(shù)據(jù)證書的組成:
1、證書的發(fā)布機(jī)構(gòu)(Issuer)
2、證書的有效期(Validity)
3、消息發(fā)送方的公鑰
4、證書所有者(Subject)
作用:主要是用來解決公鑰的安全發(fā)放問題,也稱為電子證書,類似于日常生活中的身份證,也是一種形式的身份認(rèn)證,用于標(biāo)識網(wǎng)絡(luò)中的用戶身份。
如何驗證證書的合法性?
CA認(rèn)證中心:CA認(rèn)證中心是負(fù)責(zé)簽發(fā),管理,認(rèn)證數(shù)字證書的機(jī)構(gòu),是基于國際互聯(lián)網(wǎng)平臺建立的一個公正,權(quán)威,可信賴的第三方組織機(jī)構(gòu)。

驗證方法:
? ? ? ?既然是合法性的問題,服務(wù)器和客戶端倆個當(dāng)事人誰說了都不算,由數(shù)字證書認(rèn)證機(jī)構(gòu)(CA,Certificate Authority)和其相關(guān)機(jī)構(gòu)頒發(fā)的公開密鑰證書說了算。
? ? ? ?證書包含以下信息:申請者公鑰、申請者的組織信息和個人信息、簽發(fā)機(jī)構(gòu) CA 的信息、有效時間、證書序列號等信息的明文,同時包含一個簽名;
簽名的產(chǎn)生算法:首先,使用散列函數(shù)計算公開的明文信息的信息摘要,然后,采用 CA 的私鑰對信息摘要進(jìn)行加密,密文即簽名;
? ? ? ?客戶端在對服務(wù)器say hello之后,服務(wù)器將公開密鑰證書發(fā)送給客戶端,注意這個證書里面包含了公鑰+各種信息+簽名(私鑰對各種信息加密后生成簽名),客戶端收到公開密鑰證書后,相當(dāng)于收到了一個包裹里面有公鑰+各種信息+簽名,那么怎么樣使用這三個數(shù)據(jù)來校驗?zāi)?,很簡單,公鑰加密,私鑰解密,私鑰加密公鑰也可以解,只要利用公鑰對簽名進(jìn)行解密,然后就和各種信息做比較就可以校驗出證書的合法性。
解決問題:(SSL/TLS協(xié)議運(yùn)行機(jī)制)
1、所有信息都是加密傳播,第三方無法竊聽。
2、具有校驗機(jī)制,一旦被篡改,通信雙方會立刻發(fā)現(xiàn)。
3、配備身份證書,防止身份被冒充。
九、Base64、對稱加密算法、非對稱加密算法、數(shù)據(jù)摘要的概念
Base64:由于某些系統(tǒng)中只能使用ASCII字符。Base64就是用來將非ASCII字符的數(shù)據(jù)轉(zhuǎn)換成ASCII字符的一種方法,而且base64特別適合在http,mime協(xié)議下快速傳輸數(shù)據(jù)。(數(shù)據(jù)兼容)
對稱加密算法:數(shù)據(jù)發(fā)送方將明文(原始數(shù)據(jù))和加密密鑰一起經(jīng)過特殊加密算法處理后,生成復(fù)雜的加密密文進(jìn)行發(fā)送,數(shù)據(jù)接收方收到密文后,若想讀取原文,則需要使用加密使用的密鑰及相同算法的逆算法對加密的密文進(jìn)行解密,才能使其恢復(fù)成可讀明文加密和解密的密鑰相同,前提是雙方都知道密鑰。
圖解:

常見對稱加密算法:
AES:強(qiáng)安全性、高性能、高效率、易用和靈活等優(yōu)點,設(shè)計有三個密鑰長度:128,192,256位,比DES算法的加密強(qiáng)度更高,更為安全。
DES,3DES:明文按64位進(jìn)行分組,密鑰長64位,但事實上只有56位參與,原版DES容易被暴力破解,演變出了3DES算法,使用3條56位的密鑰對數(shù)據(jù)進(jìn)行三次加密。
RC4:是密鑰長度可變的流加密算法簇。RC4算法是一種在電子信息領(lǐng)域加密的技術(shù)手段,用于無線通信網(wǎng)絡(luò),是一種電子密碼,只有經(jīng)過授權(quán)(繳納相應(yīng)費(fèi)用)的用戶才能享受該服務(wù)。
對稱加密算法對比:

非對稱加密算法:非對稱加密算法本身是一種加密算法,但由于RSA本身加解密的性能在現(xiàn)在的計算機(jī)硬件條件下存在一定瓶頸,同時對加密數(shù)據(jù)的“安全長度”也有限制,被加密數(shù)據(jù)的長度一般要求不超過公鑰的長度。所以RSA更多的是被用來商量一個密鑰,如果密鑰是安全的,那么后續(xù)的通信都可以使用上面提到的AES來完成,AES在性能上不存在瓶頸。
使用:公鑰與私鑰需要配對使用,如果用公鑰對數(shù)據(jù)進(jìn)行加密,只有用對應(yīng)的私鑰才能進(jìn)行解密,而如果使用私鑰對數(shù)據(jù)進(jìn)行加密,那么只有用對應(yīng)的公鑰才能進(jìn)行解密。甲方將公鑰公開,乙方使用甲方的公鑰對信息加密,甲方再用私鑰解密。
圖解:

RSA:基于一個十分簡單的數(shù)論事實:將兩個大素數(shù)相乘十分容易,但反過來想要對其乘積進(jìn)行因式分解卻極其困難, 因此可以將乘積公開作為加密密鑰。
使用:因為RSA算法是目前最流行的公開密鑰算法,既能用于加密,也能用戶數(shù)字簽名。不僅在加密貨幣領(lǐng)域使用,在傳統(tǒng)互聯(lián)網(wǎng)領(lǐng)域的應(yīng)用也很廣泛。從被提出到現(xiàn)在20多年,經(jīng)歷了各種考驗,被普遍認(rèn)為是目前最優(yōu)秀的公鑰方案之一。比特幣所使用的Sha256算法,也是在其基礎(chǔ)之上建立的。
DSA:是基于整數(shù)有限域離散對數(shù)難題的,其安全性與RSA相比差不多。DSA的一個重要特點是兩個素數(shù)公開,這樣,當(dāng)使用別人的p和q時,即使不知道私鑰,你也能確認(rèn)它們是否是隨機(jī)產(chǎn)生的,還是作了手腳。RSA算法卻做不到。
ECC:RSA有另一個競爭者ECC,ECC現(xiàn)在使用也越來越廣泛。二者在安全性上都不存在問題。不過ECC額外的優(yōu)勢,公鑰私鑰的生成速度快于RSA,在需要大量生產(chǎn)密鑰對的業(yè)務(wù)場景下ECC會是更好的選擇。ECC的最短安全公鑰也比RSA要短的多,224bits的ECC公鑰就已經(jīng)足夠安全,而同等級別的RSA公鑰需要長達(dá)2048bits。RSA由于實現(xiàn)簡單,出現(xiàn)較早,可以預(yù)見在很長一段時間內(nèi)都將和ECC共存。
十、Http與Https知識點詳解
Http請求報文:

描述:一個HTTP請求報文由四個部分組成:請求行、請求頭部、空行、請求數(shù)據(jù)。
圖解:
請求行:請求行由請求方法字段、URL字段和HTTP協(xié)議版本字段3個字段組成,它們用空格分隔。比如 GET /data/info.html HTTP/1.1。
請求頭部:HTTP客戶程序(例如瀏覽器),向服務(wù)器發(fā)送請求的時候必須指明請求類型(一般是GET或者 POST)。如有必要,客戶程序還可以選擇發(fā)送其他的請求頭。大多數(shù)請求頭并不是必需的,但Content-Length除外。對于POST請求來說 Content-Length必須出現(xiàn)。
空行:它的作用是通過一個空行,告訴服務(wù)器請求頭部到此為止。
請求數(shù)據(jù):若方法字段是GET,則此項為空,沒有數(shù)據(jù),若方法字段是POST,則通常來說此處放置的就是要提交的數(shù)據(jù),比如:要使用POST方法提交一個表單,其中有user字段中數(shù)據(jù)為“admin”, password字段為123456,那么這里的請求數(shù)據(jù)就是 user=admin&password=123456,使用&來連接各個字段。
Http響應(yīng)報文:
圖解:

響應(yīng)行:響應(yīng)行一般由協(xié)議版本、狀態(tài)碼及其描述組成 比如 HTTP/1.1 200 OK。
其中協(xié)議版本HTTP/1.1或者HTTP/1.0,200就是它的狀態(tài)碼,OK則為它的描述。
常見狀態(tài)碼:
100~199:表示成功接收請求,要求客戶端繼續(xù)提交下一次請求才能完成整個處理過程。
200~299:表示成功接收請求并已完成整個處理過程。常用200
300~399:為完成請求,客戶需進(jìn)一步細(xì)化請求。例如:請求的資源已經(jīng)移動一個新地址、常用302(意味著你請求我,我讓你去找別人),307和304(我不給你這個資源,自己拿緩存)
400~499:客戶端的請求有錯誤,常用404(意味著你請求的資源在web服務(wù)器中沒有)403(服務(wù)器拒絕訪問,權(quán)限不夠)
500~599:服務(wù)器端出現(xiàn)錯誤,常用500
響應(yīng)頭:用于描述服務(wù)器的基本信息,以及數(shù)據(jù)的描述,服務(wù)器通過這些數(shù)據(jù)的描述信息,可以通知客戶端如何處理等一會兒它回送的數(shù)據(jù)。
? ? ? ?設(shè)置HTTP響應(yīng)頭往往和狀態(tài)碼結(jié)合起來。例如,有好幾個表示“文檔位置已經(jīng)改變”的狀態(tài)代碼都伴隨著一個Location頭,而401(Unauthorized)狀態(tài)代碼則必須伴隨一個WWW-Authenticate頭。然而,即使在沒有設(shè)置特殊含義的狀態(tài)代碼時,指定應(yīng)答頭也是很有用的。
響應(yīng)體:響應(yīng)體就是響應(yīng)的消息體,如果是純數(shù)據(jù)就是返回純數(shù)據(jù),如果請求的是HTML頁面,那么返回的就是HTML代碼,如果是JS就是JS代碼,如此之類,在Android開發(fā)中,常常分為三個部分:ResultMessage,ResultCode,data。
HTTPS詳解
描述:HTTPS是一種通過計算機(jī)網(wǎng)絡(luò)進(jìn)行安全通信的傳輸協(xié)議。HTTPS經(jīng)由HTTP進(jìn)行通信,但利用SSL/TLS來加密數(shù)據(jù)包。HTTPS開發(fā)的主要目的,是提供對網(wǎng)站服務(wù)器的身份認(rèn)證,保護(hù)交換數(shù)據(jù)的隱私與完整性。
Http與Https的區(qū)別:
1、https協(xié)議需要到CA申請證書,一般免費(fèi)證書較少,因而需要一定費(fèi)用。
2、http是超文本傳輸協(xié)議,信息是明文傳輸,https則是具有安全性的ssl加密傳輸協(xié)議。
3、http和https使用的是完全不同的連接方式,用的端口也不一樣,前者是80,后者是443。
4、http的連接很簡單,是無狀態(tài)的;HTTPS協(xié)議是由SSL+HTTP協(xié)議構(gòu)建的可進(jìn)行加密傳輸、身份認(rèn)證的網(wǎng)絡(luò)協(xié)議,比http協(xié)議安全(HTTPS其實是有兩部分組成:HTTP + SSL / TLS)
Https流程圖:

流程圖步驟詳解:
步驟一:客戶端發(fā)起一個https的請求,把自身支持的一系列Cipher Suite(密鑰算法套件,簡稱Cipher)發(fā)送給服務(wù)端。
步驟二:服務(wù)端,接收到客戶端所有的Cipher后與自身支持的對比,如果不支持則連接斷開,反之則會從中選出一種加密算法和HASH算法,以證書的形式返回給客戶端,證書中還包含了公鑰 頒證機(jī)構(gòu) 網(wǎng)址 失效日期等等。
步驟三:客戶端收到服務(wù)端響應(yīng)后會做以下幾件事。
3.1、驗證證書的合法性???
? 頒發(fā)證書的機(jī)構(gòu)是否合法與是否過期,證書中包含的網(wǎng)站地址是否與正在訪問的地址一致等,證書驗證通過后,在瀏覽器的地址欄會加上一把小鎖(每家瀏覽器驗證通過后的提示不一樣 不做討論)
3.2、生成隨機(jī)密碼
? ? ? ? ?如果證書驗證通過,或者用戶接受了不授信的證書,此時瀏覽器會生成一串隨機(jī)數(shù),然后用證書中的公鑰加密。
3.3、HASH握手信息
? ? ? ? 用最開始約定好的HASH方式,把握手消息取HASH值,然后用隨機(jī)數(shù)加密 “握手消息+握手消息HASH值(簽名)”?并一起發(fā)送給服務(wù)端
? ? ? ? 在這里之所以要取握手消息的HASH值,主要是把握手消息做一個簽名,用于驗證握手消息在傳輸過程中沒有被篡改過。
步驟四:服務(wù)端拿到客戶端傳來的密文,用自己的私鑰來解密握手消息取出隨機(jī)數(shù)密碼,再用隨機(jī)數(shù)密碼解密握手消息與HASH值,并與傳過來的HASH值做對比確認(rèn)是否一致,然后用隨機(jī)密碼加密一段握手消息(握手消息+握手消息的HASH值 )給客戶端
步驟五:客戶端用隨機(jī)數(shù)解密并計算握手消息的HASH,如果與服務(wù)端發(fā)來的HASH一致,此時握手過程結(jié)束,之后所有的通信數(shù)據(jù)將由之前瀏覽器生成的隨機(jī)密碼并利用對稱加密算法進(jìn)行加密。
? ? ? ? 因為這串密鑰只有客戶端和服務(wù)端知道,所以即使中間請求被攔截也是沒法解密數(shù)據(jù)的,以此保證了通信的安全。?
附加:
1、非對稱加密算法:RSA,DSA/DSS,在客戶端與服務(wù)端相互驗證的過程中用的是非對稱加密。
2、對稱加密算法:AES,RC4,3DES,客戶端與服務(wù)端相互驗證通過后,以隨機(jī)數(shù)作為密鑰時,就是對稱加密。
3、HASH算法:MD5,SHA1,SHA256,在確認(rèn)握手消息沒有被篡改時。
開源框架:https://github.com/hongyangAndroid/okhttputils
十一、基于TCP的Socket與基于UDP的Socket通信
描述:Android與服務(wù)器的通信方式主要有兩種:
第一種:Http通信,第二種:Socket通信。兩者的最大差異在于,http連接使用的是“請求—響應(yīng)方式”,即在請求時建立連接通道,當(dāng)客戶端向服務(wù)器發(fā)送請求后,服務(wù)器端才能向客戶端返回數(shù)據(jù)。
? ? ? ?而Socket通信中基于TCP/IP協(xié)議的通信則是在雙方建立起連接后就可以直接進(jìn)行數(shù)據(jù)的傳輸,在連接時可實現(xiàn)信息的主動推送,而不需要每次由客戶端向服務(wù)器發(fā)送請求。而UDP則是提供無連接的數(shù)據(jù)報服務(wù),UDP在發(fā)送數(shù)據(jù)報前不需建立連接,不對數(shù)據(jù)報進(jìn)行檢查即可發(fā)送數(shù)據(jù)包。
什么是socket?
? ? ? ?Socket(套接字)是用來描述IP地址和端口,是通信鏈的句柄,應(yīng)用程序可以通過Sokcet向網(wǎng)絡(luò)發(fā)送請求或者應(yīng)答網(wǎng)絡(luò)請求,Socket是支持TCP/IP協(xié)議的網(wǎng)絡(luò)通信的基本操作單元,是對網(wǎng)絡(luò)通信過程中端點的抽象表示,包含了進(jìn)行網(wǎng)絡(luò)通信所必須的五種信息:連接所使用的協(xié)議,本地主機(jī)的IP地址,本地遠(yuǎn)程的協(xié)議端口,遠(yuǎn)地主機(jī)的IP地址以及遠(yuǎn)地的協(xié)議端口。
Socket通信模型:

Socket通信實現(xiàn)步驟解析:
Step 1:創(chuàng)建ServerSocket和Socket。
Step 2:打開連接到的Socket的輸入/輸出流。
Step 3:按照協(xié)議對Socket進(jìn)行讀/寫操作。
Step 4:關(guān)閉輸入輸出流,以及Socket。
基于TCP的Socket編程:
發(fā)送:
Socket m_socket = new Socket();
m_socket.connect(new InetSocketAddress(rc_ip, TcpAgreementHelp.port_2), 2000);
OutputStream m_out = m_socket.getOutputStream();
m_out.write(SendMessageFormat.aboutConversation(704, rId, opType, 0));
m_out.flush();
接收:
static private ServerSocket server_socket_18022 = null;
//靜態(tài),只有一個實例,以后做后臺重啟的時候避免重復(fù)監(jiān)聽相同端口
static private Socket socket_18022 = null;
server_socket_18022 = new ServerSocket(port_1);
socket_18022 = server_socket_18022.accept();
InputStream in = socket_18022.getInputStream();
byte[] headByte = new byte[20];???
//保證先把數(shù)據(jù)頭給接下來,所以其他終端的數(shù)據(jù)頭一定要同一個數(shù)據(jù)包發(fā),或者這里強(qiáng)行接收20個字節(jié)。??????
in.read(headByte);
基于UDP的編程:
hostSocket = new DatagramSocket();
sendPacket = new DatagramPacket(SendMessageFormat.arpData(rId,0), 21, broadIp, UDP_PORT_DISCOVER);
hostSocket.setBroadcast(true);????//這是用于發(fā)送廣播用的
hostSocket.send(sendPacket);
hostSocket.close();
hostSocket = null;
TCP和UDP最大的區(qū)別:
描述:區(qū)別在于是否需要客戶端與服務(wù)端建立連接后才能進(jìn)行數(shù)據(jù)傳輸。
TCP:傳輸前先開服務(wù)端,accept,等客戶端接入,然后獲得客戶端socket然后進(jìn)行IO操作,而UDP則不用。
UDP:以數(shù)據(jù)報作為數(shù)據(jù)的傳輸載體,在進(jìn)行傳輸時首先要把傳輸?shù)臄?shù)據(jù)定義成數(shù)據(jù)報(Datagram),在數(shù)據(jù)報中指明數(shù)據(jù)要到達(dá)的Socket(主機(jī)地址 和端口號),然后再將數(shù)據(jù)以數(shù)據(jù)報的形式發(fā)送出去。
Socket圖例:

客戶端與服務(wù)器socket圖解:

問題:Socket通信是否屬于TCP/IP協(xié)議族,Socket通信相關(guān)知識點與常見使用場景?
解答:不屬于,Socket是應(yīng)用層與TCP/IP協(xié)議族通信的中間軟件抽象層,它是一組接口。在設(shè)計模式中,Socket其實就是一個門面模式,它把復(fù)雜的TCP/IP協(xié)議族隱藏在Socket接口后面,對用戶來說,一組簡單的接口就是全部,讓Socket去組織數(shù)據(jù),以符合指定的協(xié)議。
? ? ? ? 是一種抽象層,應(yīng)用程序通過它來發(fā)送和接收數(shù)據(jù),使用Socket可以將應(yīng)用程序添加到網(wǎng)絡(luò)中,與處于同一網(wǎng)絡(luò)中的其他應(yīng)用程序進(jìn)行通信。簡單來說,Socket提供了程序內(nèi)部與外界通信的端口并為通信雙方的提供了數(shù)據(jù)傳輸通道。
? ? ? ? 那么,什么是socket?Socket又稱套接字,在程序內(nèi)部提供了與外界通信的端口,即端口通信。通過建立socket連接,可為通信雙方的數(shù)據(jù)傳輸傳提供通道。socket的主要特點有數(shù)據(jù)丟失率低,使用簡單且易于移植。
? ? ? ? 今天這篇文章就先說這么多,后續(xù)還有一篇文章在把剩余的內(nèi)容給補(bǔ)充上。
十八:擴(kuò)展閱讀
1、https://www.cnblogs.com/guolingyun/p/6148462.html
(Android中XML的三種解析方式)
2、https://blog.csdn.net/langtop/article/details/77972855
(HttpClient、HttpURLConnection、OKHttp和Volley優(yōu)缺點和性能對比,如何選擇)
3、https://www.cnblogs.com/index-html/p/traffic-hijack.html(流量劫持是如何產(chǎn)生的)
4、https://server.zzidc.com/fwqcjwt/2557.html(如何防止中間人攻擊)
5、https://blog.csdn.net/sd19871122/article/details/79399441(Android4種網(wǎng)絡(luò)連接
方式HttpClient、HttpURLConnection、OKHttp和Volley優(yōu)缺點和性能對比)
6、https://www.cnblogs.com/heluan/p/8620312.html(HTTP1.0、HTTP1.1和HTTP2.0的區(qū)別)
7、http://www.itdecent.cn/p/bb3eeb36b479(QUIC協(xié)議淺析與HTTP/3.0)
8、https://www.cnblogs.com/chenjinxinlove/p/10104854.html(HTTP3.0(QUIC的實現(xiàn)機(jī)制))
9、http://www.itdecent.cn/p/050c6db5af5a(Android開源:主流網(wǎng)絡(luò)請求庫對比(Android-Async-Http、Volley、OkHttp、Retrofit))
10、https://blog.csdn.net/u014756827/article/details/78870365(BIO與NIO、AIO的區(qū)別(這個容易理解))
11、https://github.com/jeanboydev/Android-ReadTheFuckingSourceCode/blob/master/article/android/performance/05_network.md(網(wǎng)絡(luò)性能優(yōu)化那些事)
12、https://blog.csdn.net/qq_41727218/article/details/82461089(IP協(xié)議詳解)