1. 介紹
okHttp技術(shù)已被Android4.4之后納入HttpURLConnection底層通信庫,重要性不言而喻。
okhttp對網(wǎng)絡通信中的通信協(xié)議,數(shù)據(jù)解析,I/O,緩存,并發(fā)請求實現(xiàn)了良好的策略,并拓展和支持了Application/NetWork攔截,HTTP2協(xié)議,數(shù)據(jù)ZIP壓縮等功能。HTTPS其實是有兩部分組成:HTTP + SSL / TLS
2. 通信
2.1 SSL/TLS加密: 保證數(shù)據(jù)傳輸?shù)陌踩?br> 方法:客戶端先向服務器端索要公鑰,然后用公鑰加密信息,服務器收到密文后,用自己的私鑰解密。雙方會通過通信中的幾個隨機隨機數(shù)生成對稱機密的“對話密鑰”。對話密鑰用戶加密傳輸?shù)臄?shù)據(jù),RSA公鑰和私鑰是為了驗證各自的身份。通過兩輪共四次握手確定了各自身份和加密方法。參考
SSL(Secure Socket Layer,安全套接字層):位于可靠的面向連接的網(wǎng)絡層協(xié)議和應用層協(xié)議之間的一種協(xié)議層。
TLS(Transport Layer Security,傳輸層安全協(xié)議):用于兩個應用程序之間提供保密性和數(shù)據(jù)完整性。
區(qū)別:TLS建立在SSL 3.0協(xié)議規(guī)范之上,是SSL 3.0的后續(xù)版本。在TLS與SSL3.0之間的差別主要是它們所支持的加密算法不同。參考
公鑰、私鑰 的解釋
公鑰 :用于向外發(fā)布,任何人都能獲取,
私鑰 :要自己保存,切勿給別人
一下兩種情況經(jīng)常有人弄混,一定要理解。
情況1:公鑰用于【加密】, 私鑰用于【解密】
如果加密密鑰是公開的,這用于客戶給私鑰所有者上傳加密的數(shù)據(jù),這被稱作為公開密鑰加密(狹義)。
例如,網(wǎng)絡銀行的客戶發(fā)給銀行網(wǎng)站的賬戶操作的加密數(shù)據(jù)。HTTPS 等。
情況2:公鑰用于【解密】,私鑰用于【加密】
如果解密密鑰是公開的,用私鑰加密的信息,可以用公鑰對其解密,用于客戶驗證持有私鑰一方發(fā)布的數(shù)據(jù)或文件是完整準確的,接收者由此可知這條信息確實來自于擁有私鑰的某人,這被稱作數(shù)字簽名,公鑰的形式就是數(shù)字證書。例如,從網(wǎng)上下載的安裝程序,一般都帶有程序制作者的數(shù)字簽名,可以證明該程序的確是該作者(公司)發(fā)布的而不是第三方偽造的且未被篡改過(身份認證/驗證)。
2.2 SOCKET通信
傳輸層的TCP是基于網(wǎng)絡層的IP協(xié)議的,而應用層的HTTP協(xié)議又是基于傳輸層的TCP協(xié)議的,而Socket本身不算是協(xié)議,它只是提供了一個針對TCP或者UDP編程的通信API。Socket除非主動斷開否則可保持長連接,HTTP1.0短連接,HTTP1.0的長連接有時限。HTTP通信服務可使用sockets實現(xiàn)。參考
3. I/O : Okio庫
- Okio作為OkHttp使用的I/O接口,實現(xiàn)對文件/字符流/字節(jié)流等的讀寫的良好封裝,使得通過
sink()
及souce()
即可進行數(shù)據(jù)讀寫。 - i/o流向
sink -> socket/File
Source <- socket/File
4. HTTP Interceptor圖
5. 通信Platform
OkHttp的最底層是Socket
okhttp//實現(xiàn)HTTP協(xié)議
framwork//JRE,實現(xiàn)JDK中Socket封裝
jvm//JDK的實現(xiàn),本質(zhì)對libc標準庫的native封裝
bionic//android下的libc標準庫
ystemcall//用戶態(tài)切換入內(nèi)核
kernel//實現(xiàn)下協(xié)議棧(L4,L3)與網(wǎng)絡驅(qū)動(一般是L2,L1)
6. 連接池的自動清理CleanUp
okhttp使用了類似于引用計數(shù)法與標記擦除法的混合使用,當連接空閑或者釋放時,StreamAllocation的數(shù)量會漸漸變成0,從而被線程池監(jiān)測到并回收,這樣就可以保持多個健康的keep-alive連接
7. HTTP緩存策略
okHttp緩存策略可通過Header中設置Expires/Cache-Control/ETag/Last-Modified等設置。Expires/Cache-Conrol確定是否進行網(wǎng)絡資源獲取,ETag(if-not-match)/Last-Modified(if-modified-since)確定網(wǎng)絡請求是否從代理CDN緩存中獲取。
8. HTTP緩存的存儲策略
緩存使用DiskLruCache結(jié)構(gòu)管理緩存文件FileSystem,DiskLruCache內(nèi)部使用LinkHashMap進行LRU算法實現(xiàn)。在緩存文件清理策略上使用LRU算法,以線程池進行緩存的自動清理。
擴展
LinkHashMap可以保持有序(插入順序/LRU訪問順序)是因為內(nèi)部維護了一個雙向鏈表。
9. OKHTTP線程隊列
OkHttp線程池可通過緩存和閾值控制CPU工作量。
采用Dispatcher分發(fā)技術(shù)與線程池配合,實現(xiàn)單生產(chǎn)者多消費者模式下的高并發(fā)低阻塞。
使try/finally減少使用采用wait/notify減少了編碼復雜性和出錯率。