深入探索 Android 網絡優化(一、網絡築基篇)上

前言

成爲一名優秀的Android開發,需要一份完備的知識體系,在這裏,讓我們一起成長爲自己所想的那樣~。

網絡優化一直被認爲是移動優化水最深的領域之一,因此要想對網絡進行深入優化,我們就必須先打下比較紮實的網絡基礎,在本文中,我們將再次重溫計算機網絡中的重點知識,以此在腦海中建立一個較爲全面的網絡基礎知識體系。

大綱

一、重識計算機網絡

1、計算機網絡是什麼?

  • 1)、主要由 「通用、可編程的硬件互連」 而成。

  • 2)、通過這些硬件,可以 「傳送不同類型的數據」

  • 3)、計算機網絡不僅包含 「軟件概念」,還包含 「硬件設備」

  • 4)、計算機網絡不僅僅是 「信息通信」,還可以 「支持廣泛和日益增長的應用」

2、計算機網絡的分類

1)、按作用範圍

廣域網(WAN)

幾十 KM ~ 幾千 KM,跨省、跨國。

城域網(MAN)

5 KM ~ 50 KM,城市間、城市內。

局域網(LAN)

1 KM 內,地區內、家庭間、公司內。

2)、按網絡使用者

公用網絡

所有可以通過付費方式就可以加入的網絡。

專用網絡

某些部隊、組織或者某些人 「爲了滿足特殊業務需求而建立起來的特殊的網絡」,例如軍隊、鐵路、銀行都有自己的專用網絡。

二、網絡歷史演進

1、世界互聯網發展歷史演進

1)、單個網絡

「ARPANET」,1969年美國國防部創建的一個網絡,可以連接周圍的計算機。

計算機直接通過交換機就可以進行信息交換。

2)、三級結構

「現代互聯網的雛形」,也稱爲 「互聯網絡」,可以把美國所有的大學、研究所、實驗室都連接起來。

從上至下,由 「主幹網、地區網、校園網」 組成。

3)、多層次 ISP

ISP(Internet Service Provider):網絡服務提供商,例如中國電信、中國移動、中國聯通等。「從上之下,由主幹 ISP、地區 ISP 組成」

主幹 ISP

中國的主幹 ISP 包括 「中國電信、中國移動、中國聯通」,它們可以連接美國和其它國家的主幹 ISP。

地區 ISP

例如移動網絡,在北京叫 「北京移動」,在上海叫 「上海移動」,這些就屬於地區 ISP。「地區 ISP 可以連接公司、校園、家庭的網絡」

4)、瞭解現代國際互聯網的主要線路

我們可以通過 infrapedia 網站了解國際互聯網的主要線路。

上圖刻畫了 「全球的所有主幹網絡的線路」,可以看到,「中國的主幹網絡出口基本都是位於廣東、福建等沿海地區,它們通過各自的海底電纜與位處於世界各地的主幹網絡相互連接,最終形成了互聯網」

2、中國互聯網發展歷史

1)、1980 年

中國鐵道部開始互聯網實驗。

2)、1989 年

建立並運行第一個公共網絡。

3)、1994 年

接入國際互聯網。

4)、至今

「當今中國最大的五個公用的計算機網絡」

  • 「中國電信互聯網(CHINANET)」

  • 「中國聯通互聯網(UNINET)」

  • 「中國移動互聯網(CMNET)」

  • 「中國教育與科研計算機網(CERNET)」

  • 「中國科學技術網(CSTNET)」

3、中國的互聯網企業

  • 1996年,張朝陽創建搜狐。

  • 1997年,丁磊創建網易。

  • 1998年,王志東創建新浪,馬化騰、張志東創建騰訊。

  • 1999年,馬雲創建阿里巴巴。

  • 2000年,李彥宏創建百度。

三、重識網絡層次結構

網絡爲什麼要分層?

因爲複雜的程序都要分層。這是一個架構設計的通用問題,不僅僅是網絡協議的問題,「只要涉及複雜的邏輯或軟件需求需要經常變動的情況通常都會通過分層來解決」

思考????:設計一個計算機網絡需要解決哪些問題?

  • 1)、傳輸數據時需要保證數據通路順暢。

  • 2)、需要識別目的計算機。

  • 3)、需要了解目的計算機的狀態。

  • 4)、數據是否錯誤。

總之,計算機網絡需要解決的問題是繁多而複雜的,所以我們需要 「採用分層的設計分別去解決不同的問題,實現不同的功能」

1、層級結構設計的基本原則

1)、相互獨立

每一層僅僅實現一個相對獨立的功能,並且需要確保層與層之間的耦合度是非常低的。

2)、靈活性

每一層的設計需要具備很好的靈活性、擴展性,以適應未來的網絡變化。

3)、耦合度

各層之間是完全解耦的,層與層之間的變化互不影響。

2、OSI 七層模型

OSI功能
應用層爲計算機用戶提供接口和服務。
表示層數據處理:編解碼、加解密等等。
會話層管理(建立、維護、重連)通信會話。
傳輸層管理端到端的通信連接。
網絡層數據路由:決定數據在網絡中的路徑。
數據鏈路層管理相鄰節點之間的數據通信。
物理層數據通信的光電物理特性。

1)、OSI 悲催的故事

  • 1)、一開始,OSI 欲稱爲全球計算機都遵守的標準。

  • 2)、但是,OSI 在市場化的過程中困難重重,因爲 TCP/IP 已經在全球範圍成功運行。

  • 3)、最終,OSI 並沒有稱爲廣爲使用的標準模型。

2)、OSI 七層模型失敗的原因

  • 1)、OSI 的專家沒有充分將理論與實際進行結合。

  • 2)、OSI 標準的制定週期過長,按 OSI 標準生產的設備無法及時進入市場。

  • 3)、OSI 模型的設計不合理,某些功能在多層重複出現。

3、TCP/IP 四層模型

我們需要理解數據通信過程中不同設備之間協議的轉換。從下圖可以看到 「路由器僅包括網絡層與網絡接口層」

從協議的數量來看,TCP/IP 四層模型構成了中間窄,兩端大的⏳沙漏形狀。如下圖所示:

四、初識現代網絡拓撲

1、爲什麼要了解網絡拓撲?

因爲它 「有助於我們在腦海裏面形成一個形象的計算機網絡」

2、網絡拓撲分類

1)、邊緣部分

家庭

「終端機器、路由器、網關、地區 ISP」 組成。

企業

不同於家庭的網絡拓撲,其 「網關細分爲內部網關與統一網關」

2)、核心部分

「地區 ISP、主幹 ISP、路由器、海底電纜或跨地區電纜」 組成。其中的 「通信設備(一般是華爲)主要是由移動、聯通所鋪設的」

現代互聯網的網絡拓撲形成了一個 「樹狀結構」

3)、C/S 模式

由 客戶端/服務端 模式組成,並可以相互進行通信。

4)、P2P 模式

不分爲服務端和客戶端,它們都是 「對等地進行連接的」,優勢在於可以使 「下載速度更快」,如迅雷下載器中就應用了這種模式。

五、網絡性能指標

1、速率

即 bps <==> bit/s
複製代碼

網絡數據傳輸的各種單位與之對應的常見設備

爲什麼電信拉的 100M 光纖,測試峯值速度只有 12M 每秒?

網絡常用單位爲(Mbps),因此這裏的 100M 指的是 100Mbps。

100 M/S = 100 Mbps = 100 Mbit/s
100 Mbit/s = (100/8)MB/s = 12.5 MB/s
複製代碼

2、時延

1)、發送時延

發送時延 = 數據長度(bit)/ 發送速率(bit/s)
複製代碼

數據長度是由用戶決定的,而發送速率是由計算機網卡所決定的。

2)、傳輸時延

傳播時延 = 傳輸路徑距離 / 傳播速率(bit/s)
複製代碼

傳輸路徑距離是由用戶決定的,而傳播速率則受限於傳輸介質。

3)、排隊時延

數據包在網絡設備中等待被處理的時間,例如路由器需要一個一個處理完前面的數據包才能處理後面的。

4)、處理時延

數據包到達設備或者目的機器被處理所需的時間。

總時延 = 發送時延 + 排隊時延 + 傳播時延 + 處理時延
複製代碼

3、往返時間 RTT(Route-Trip Time)

  • 評估網絡質量的一項重要指標。

  • 表示數據報文在端到端通信中來回一次的時間。

通常使用 ping 命令查看 RTT

1)、ping 查看當前城市中的 IP

quchao@quchaodeMacBook-Pro ~ % ping 119.29.148.149
PING 119.29.148.149 (119.29.148.149): 56 data bytes
64 bytes from 119.29.148.149: icmp_seq=0 ttl=116 time=13.210 ms
64 bytes from 119.29.148.149: icmp_seq=1 ttl=116 time=19.118 ms
64 bytes from 119.29.148.149: icmp_seq=2 ttl=116 time=34.384 ms
複製代碼

2)、ping 美國的 IP

quchao@quchaodeMacBook-Pro ~ % ping 191.101.238.160
PING 191.101.238.160 (191.101.238.160): 56 data bytes
64 bytes from 191.101.238.160: icmp_seq=0 ttl=52 time=191.791 ms
64 bytes from 191.101.238.160: icmp_seq=1 ttl=52 time=180.278 ms
64 bytes from 191.101.238.160: icmp_seq=2 ttl=52 time=186.399 ms
複製代碼

六、應用層

「傳輸層與之下的層已經提供了完整的通信服務」。而應用層是面向用戶的一層。它主要是用來 「定義應用間通信的規則」,例如應用進程的報文類型(請求報文、應答報文)、報文的語法、格式、應用進程發送數據的時機、規則等等。

1、DNS(Domain Name System) 域名系統服務

域即對應的網絡號,名即對應的主機名字。

1)、功能

通過把沒有規則的點分十進制 IP 地址轉換爲可以理解的一些域名。

2)、域名

  • 使用域名可以幫助記憶。

  • 域名通過 DNS 服務可以被轉換成 IP 地址。

  • 域名是由點、字母和數字組成的。

  • 點分割不同的域。

  • 「域名可以分爲頂級域、二級域、三級域...,例如:www.taobao.com => - 三級域.二級域.頂級域」

頂級域常見分類

  • 國家

    • cn

    • us

    • uk

    • ca

  • 通用

    • com

    • net

    • gov

    • org

二級域

例如:qq、aliyun、taobao、google、facebook 等等。

「頂級域、二級域、三級域組成了一個樹狀結構。且在頂級域名服務器上面還有一個根域名服務器」

3)、域名服務器

只要有一個外網的服務器就可以搭建一個域名的服務器。

2、DHCP(Dynamic Host Configuratin Protocol) 動態主機設置協議

1)、是什麼?

「網絡管理員只需配置一段共享的 IP 地址,每一臺新接入的機器都可以通過 DHCP 來這個共享的 IP 地址裏面申請 IP 地址,就可以自動配置。等用完還回去其它機器也能使用」。它的特點如下所示:

  • 1、「DHCP 是一個局域網協議」

  • 2、「DHCP 是應用 UDP 協議的應用層協議」

2)、功能

  • 「即插即用聯網」

  • 「在 IP 配置界面選中 自動獲得 IP 地址、自動獲得 DNS 服務器地址即可啓用 DHCP 協議去獲取一個臨時 IP(通常是一個內網地址)」

  • 「有一個租期,在租期過半時可以續租」

3)、DHCP 的過程

  • 1)、「DHCP 服務器監聽默認端口:67」

  • 2)、「主機使用 UDP 協議廣播 DHCP 發現報文」

  • 3)、「DHCP 服務器發出 DHCP 提供報文」

  • 4)、「主機向 DHCP 服務器發出 DHCP 請求報文」

  • 5)、「DHCP 服務器迴應並提供 IP 地址」

4)、向 DHCP 租用的 IP 地址是有租期的,IP 地址如何實現續租呢?

客戶端會在租期過去50%的時候,直接向爲其提供 IP 地址的 DHCP 服務器發送 DHCP request 消息報。客戶端接收到服務器迴應的 DHCP ACK 消息包後,會根據消息報中提供的新的租期以及其他已經更新的 TCP/IP 參數更新自己的配置。

3、HTTP(HyperText Tranfsfer Protocol) 超文本傳輸協議

1)、是什麼?

  • HyperText 即超文本、超鏈接,Http 是指在電腦中顯示的、「含有可以指向其他文本的鏈接文本」

  • 對於這些內容都有一個統一的路徑,例如:http(s)://<主機>:<端口>/<路徑>

  • 「HTTP 協議底層是 TCP 協議,因此它是可靠的數據傳輸協議」

2)、Web 服務器

分爲硬件部分(計算機或雲上的虛擬設備)和軟件部分(Nginx、Apache)。

過程

  • 1)、「接受客戶端連接」

  • 2)、「接受請求報文」

  • 3)、「處理請求」

  • 4)、「訪問 Web 資源」

  • 5)、「構造應答」

  • 6)、「發送應答」

3)、HTTP 請求方法

header 1header 2
GET獲取指定的服務端資源。
POST提交數據到服務端。
DELETE刪除指定的服務端資源。(很少用)
UPDATE更新指定的服務端資源。
PUT修改數據。
OPTIONS列出可對資源實行的請求方法,用來跨域請求。
CONNECT建立連接隧道,用於代理服務器
HEAD獲取資源的元信息
TRACE追蹤請求-響應的傳輸路徑

GET 和 POST 的區別

  • 1、「get參數通過url傳遞,post放在request body中」

  • 2、「get請求在url中傳遞的參數是有長度限制的,而post沒有」

  • 3、「get比post更不安全,因爲參數直接暴露在url中,所以不能用來傳遞敏感信息」

  • 4、「get請求只能進行url編碼,而post支持多種編碼方式」

  • 5、「get請求會瀏覽器主動cache,而post支持多種編碼方式」

  • 6、「get請求參數會被完整保留在瀏覽歷史記錄裏,而post中的參數不會被保留」

  • 7、「GET和POST本質上就是TCP鏈接,並無差別。但是由於HTTP的規定和瀏覽器/服務器的限制,導致他們在應用過程中體現出一些不同」

4)、HTTP 指定資源

1)、在地址中指定

https://www.wanandroid.com/repo/100.html

repo/100.html 是指定的請求資源。

https://www.wanandroid.com/?sort=0&unlearn=0&page=2

? 後面用來指定請求參數。

2)、在請求數據中指定

5)、HTTP 請求報文

HTTP 的請求報文與響應報文都滿足如下結構:

起始行 + 頭部 + 空行 + 實體

其中的 「空行是用來區分開頭部和實體的」

HTTP 請求報文的格式如下所示:

例如:

POST https://www.wanandroid.com HTTP/1.1
Accept-Encoding:gzip
Accept-Language:zh-CN
...
{ 請求的 jsonString 內容}
複製代碼

6)、HTTP 應答報文

7)、HTTP 應答狀態碼

header 1header 2
100~199協議處理的中間狀態,還需要後續操作
200~299成功
300~399重定向
400~499客戶端錯誤
500~599服務端錯誤

100~199

  • 101:Switching Protocols,服務器同意將 HTTP 升級爲 WebSocket 時發送。

200~299

  • 200:在響應體中放有數據。

  • 204:No Content,響應頭後沒有 body 數據。

  • 206:Partial Content,通常用於 HTTP 分塊下載和斷點續傳,同時帶上相應的響應頭字段 Content-Range。

300~399

  • 301:Moved Permanently,永久重定向。

  • 302:Found,臨時重定向。

  • 304:Not Modified,協商緩存命中時返回。

400~499

  • 400:Bad Request,請求出錯。

  • 403:Forbidden,服務器禁止訪問,原因有法律禁止、信息敏感等。

  • 404:Not Found,資源未找到。

  • 405:Method Not Allowed,請求方法不被允許。

  • 406:Not Acceptable,資源無法滿足條件。

  • 408:Request Timeout,請求超時。

  • 409:Conflict,多個請求發生了衝突。

  • 413:Request Entity Too Large,請求體的數據過大。

  • 414:Request-URI Too Long,請求行裏的 URI 太大。

  • 429:Too Many Request,客戶端發送的請求過多。

  • 431:Request Header Fields Too Large,請求頭的字段內容太大。

500~599

  • 500:Internal Server Error,服務內部出錯。

  • 501:Not Implemented: 請求的功能不支持。

  • 502:Bad Gateway: 服務器自身是正常的,只是數據通道有問題。

  • 503:Service Unavailable: 服務器很忙,無法響應服務。

8)、HTTP 工作結構

Web 緩存

通常遵循 「二八原則」:一個網站的內容通常分爲20%的熱門內容,80%的冷門內容。因此可以優先緩存熱門內容。

存儲器層次結構

緩存(CPU 高速緩存)/主存(內存)/輔存(磁盤)

Web 代理

  • 通過 Web 代理可以屏蔽服務器的部署結構。

  • 可以在 Web 代理裏面設置規則,如防火牆來保證安全。

Web 代理的分類
  • 1)、正向代理:代理客戶端去訪問 Server。

  • 2)、反向代理:代理 Server 把數據返回給客戶端。例如 Nginx、HAProxy 就是一些著名的代理軟件。

CDN(Content Delivery Network)內容分發網絡

  • 「用於將一些大的內容在臨近的服務器留一個備份」

  • 「使用 CDN 可以進行多媒體內容的加速」

CDN的基本原理是 「廣泛採用各種緩存服務器,將這些緩存服務器分佈到用戶訪問相對集中的地區或網絡中,在用戶訪問網站時,利用全局負載技術將用戶的訪問指向距離最近的工作正常的緩存服務器上,由緩存服務器直接響應」

爬蟲

用於在互聯網上採集信息, 例如百度、Google的本質就是一個爬蟲,它們通過把整個網絡的數據給取下來,並且做一個索引,然後把這些內容提供給大家,在進行搜索時就會匹配這些內容並返回。

不好的爬蟲的缺點:
  • 增加網絡擁塞。

  • 損耗服務器資源。

4、HTTPS(Secure) 安全的 HTTP 協議

https://<主機>:<443>/<路徑>

HTTP 是明文傳輸的,但是我們需要在網絡中傳輸 賬號密碼、個人信息、賬號金額、交易信息、敏感信息,這會導致中間人非法截取信息,導致信息泄露。

1)、加密模型

  • 「對稱加密:加密與解密都使用同一個祕鑰」

  • 「非對稱加密:公鑰加密,私鑰解密,並且公鑰與私鑰是擁有一定數學關係的一組祕鑰」

    • 「私鑰:自己使用,不對外公開」

    • 「公鑰:給大家使用,對外公開」

2)、數字證書 簽名校驗

「數字證書是可信任組織頒發給特定對象的認證。而可信任組織即客戶端與服務端都認爲安全的組織」

數字證書格式

  • 證書格式、版本號

  • 證書序列號

  • 簽名算法

  • 有效期

  • 對象名稱

  • 對象公開祕鑰

3)、SSL(Secure Sockets Layer)安全套接層

「SSL 位於傳輸層與應用層之間,它是一個子層,作用主要有兩點」

  • 1)、「數據安全(保證數據不會被泄漏)與數據完整(保證數據不會被篡改)」

  • 2)、「對數據進行加密後傳輸」

HTTPS 的通信過程

  • 1)、「443 端口的 TCP 連接」

  • 2)、「SSL 安全參數握手」

  • 3)、「客戶端發送數據」

  • 4)、「服務端發送數據」

SSL(Secure Sockets Layer) 安全套接層握手過程

1)、生成隨機數 1、2、3 的過程
2)、雙端根據隨機數 1、2、3 與相同的算法生成對稱祕鑰進行加密通信

「HTTPS 綜合地運用了對稱加密與非對稱加密,在進行隨機數校驗的階段是使用了非對稱加密來進行通信的,然後等雙方都確定了三個隨機數之後,就可以使用相同的算法來生成對稱祕鑰進行加密通信了。HTTPS 的優勢在於雙端分別生成了祕鑰,沒有經過傳輸,減少了祕鑰泄漏的可能性」

5、Http2

它的特點如下所示:

  • 1)、「頭部壓縮」

  • 2)、「多路複用:多路複用允許同時通過單一的HTTP/2連接發送多重請求-響應信息。改善了:在http1.1中,瀏覽器客戶端在同一時間,針對同一域名下的請求有一定數量限制(連接數量),超過限制會被阻塞」

  • 3)、「提升訪問速度:相比 http1.1 請求資源所需時間更少,訪問速度更快」

  • 4)、「二進制分幀:HTTP2.0 會將所有的傳輸信息分割爲更小的信息或者幀,並對他們進行二進制編碼」

  • 5)、「設置請求優先級」

  • 6)、「服務端推送」

6、cookie

「HTTP 是一個無狀態協議,因此 Cookie 的最大的作用就是存儲 sessionId 用來唯一標識用戶。並且,Cookie 本質上就是瀏覽器裏面存儲的一個很小的文本文件,內部以鍵值對的方式來存儲」

生存週期

通過 Expires 和 Max-Age 兩個屬性來設置:

  • Expires:過期時間。

  • Max-Age:表示一段時間間隔,單位是秒,從瀏覽器收到報文開始計算。

作用域

「我們可以使用 Domain 和 path 屬性給 Cookie 綁定域名和路徑。如果在發送請求之前,發現域名或者路徑和這兩個屬性不匹配,那麼就不會帶上 Cookie」。需要注意的是,路徑中含有 / 表示域名下的任意路徑都允許使用 Cookie。

安全

  • 「帶上 Secure:說明只能通過 HTTPS 傳輸 cookie」

  • 「帶上 HttpOnly:說明只能通過 HTTP 協議傳輸」

  • 「帶上 SameSite:預防 CSRF 攻擊」

缺點

  • 1)、「安全缺陷:Cookie 很容易被非法用戶截獲,然後進行一系列的篡改,最後在 Cookie 的有效期內重新發送給服務器」

  • 2)、「容量缺陷:體積上限只有4KB,只能用來存儲少量的信息」

  • 3)、「性能缺陷:Cookie 緊跟域名,因此域名下的請求都會攜帶上完整的 Cookie,這樣隨着請求數的增多,將會造成巨大的性能浪費,因爲請求攜帶了很多不必要的內容。這裏可以通過 Domain 和 Path 指定作用域去解決」

7、HTTP 傳輸中的常見問題

  • 1)、「跨域問題」

  • 2)、「數據傳輸」

  • 3)、「隊頭阻塞」

七、傳輸層

現在,當設備 A 與 設備 B 相互通信時,我們可以認爲它們就是通過一個虛擬的互連網絡進行連接的。「在虛擬的互連網絡裏面已經解決了網絡拓撲、數據路由的走向等問題。在傳輸層重點解決的是兩個設備它們直接是如何進行通信的」

1、傳輸層的主要功能

1)、進程與進程的通信

不同於在單個操作系統內使用的進程間通信(Unix 域套接字、共享內存),網絡通信可以跨設備、跨網絡進行通信。

2)、端口的概念

  • 「使用端口來標記不同的網絡進程」

  • 「端口使用16比特位表示(0~65535)」

常見的協議端口有:

協議端口
FTP21
HTTP80
HTTPS443
DNS53
TELNET23

2、UDP(User Datagram Protocol)用戶數據報協議

1)、功能

UDP 協議 「不會對數據報進行任何的處理,即不合並,也不拆分數據」

2)、特點

1)、無連接

通信時並不需要提前建立連接。

2)、不保證可靠的數據交付

想發就發,無法保證數據在網絡傳輸過程中是否丟失。

3)、面向報文傳輸

不對數據做任何處理,而是直接將應用層數據塞進報文裏面。

4)、沒有擁塞控制

不管網絡是否擁塞,它都會把數據給交付出去。

5)、首部開銷很小

首部僅僅佔用8個字節。

3)、報文結構

  • 「UDP 長度最小值爲 8, 即僅包括 UDP 首部」

  • 「校驗和是用來檢測 UDP 的數據報在傳輸過程中是否出錯」

4)、基於 UDP 定製化的 5 個例子????

1、來自網頁或者 App 的訪問

目前,HTTP 往往採取多個數據通道共享一個連接的策略,這樣做本來是爲了加快傳輸速度,但是 TCP 嚴格的順序策略使得哪怕共享通道,前一個包不來,後一個包即使與前一個包沒關係,也要等着,這樣就會使時延加大。

而 QUIC(Quick UDP Internet Connection,快速 UDP 互聯網連接)協議是 Google 提出的一種基於 UDP 改進的通信協議,其目的是降低網絡通信的延遲,提供更好的用戶互動體驗。

QUIC 會在應用層上自己快速建立連接、減少重傳時延、自適應擁塞控制,是應用層定製化的代表。

2、流媒體協議

直播通常都使用 RTMP(Real Time Messaging Protocol,實時消息傳輸協議),基於 TCP。但對於直播來說實時性比較重要,寧可丟包,也不要卡頓。

對於視頻播放來說,有的包可以丟,有的包不能,因爲在視頻的連續幀李,有的幀重要,有的不重要,如果一定要丟包,隔幾個丟一個,其實看視頻的人不會感知,但是如果是連續丟幀,就能感知到了,因此在網絡不好的情況下,應用一般會選擇性地丟幀。

當網絡不好的時候,TCP 會主動降低發送速度,這對本來當時就卡的視頻來講無疑是雪上加霜。TCP 應該讓應用層馬上重傳,而不是主動讓步。因此,很多直播應用都基於 UDP 實現了自己的視頻傳輸協議。

3、實時遊戲

維護 TCP 連接需要在內核維護一些數據結構,但是一臺機器能夠支撐的 TCP 連接數目是有限的。由於 UDP 是沒有連接的,所以在異步 I/O 機制引入之前,UDP 常常是應對海量客戶端連接的策略。

在遊戲對實時要求比較嚴格的情況下,可以採用自定義的可靠 UDP 來傳輸數據包,通過使用自定義重傳策略,能夠包丟包產生的延遲降到最低,儘量減少網絡問題對遊戲造成的影響。

4、物聯網

Google 旗下的 Nest 建立了 Thread Group,推出了物聯網通信協議 Thread,該協議就是基於 UDP 的。

5、移動通信領域

在 4G 網絡裏,通過移動通信傳輸數據面對的協議 GTP-U 就是基於 UDP 的。關於移動網絡的相關知識我們將在下一篇進行講解。

3、TCP(Transmission Control Protocol) 傳輸控制協議初識

1、TCP 報文詳解

1)、特點

  • 1)、「面向連接:面向連接就像是打電話時需要先撥通電話」

  • 2)、「點對點通信」

  • 3)、「可靠的傳輸服務」

  • 4)、「全雙工通信:兩個設備在連接時,它們都可以同時地發送數據與接收數據」

  • 5)、「面向字節流的協議:TCP 處理的是一個一個的字節,所以TCP 很可能會取出數據中的某一段進行傳輸,而剩下的數據會把它放到第二個及之後的 TCP 報文中進行傳輸。因此 TCP 協議可能會對用戶的數據進行合併或分拆」

TCP 的缺點在於 「傳輸效率慢,因爲它需要建立連接、發送確認包等等」

2)、報文首部字段

序號
  • 表示範圍爲 0 ~ 2^32 - 1

  • 「因爲 TCP 是面向字節流的,所以每一個字節都有一個與之對應的序號」

  • 「TCP 數據報的序號就是數據報中第一個字節的序號」

確認號
  • 表示範圍爲 0 ~ 2^32 - 1

  • 「表示期望收到數據的首字節序號,如果確認號爲 S,則表示 S - 1 序號的數據都已經收到了」

數據偏移
  • 「佔4位:0 ~ 15,單位爲:32位字。=> 首部範圍爲20~60字節」

  • 「TCP 數據偏移首部的距離,因爲 TCP 選項的大小是不確定的,所以需要此數據項」

TCP 標記

「佔6位」,每位都有不同的含義。

標記含義
URG(Urgent)緊急位,URG = 1,表示緊急數據。
ACK(Acknowledgement確認位,ACK = 1,確認號才生效。
PSH(Push)推送位,PSH = 1,表示需要儘快地把數據交付給應用層。
RST(Reset)重置位,RST = 1,重新建立連接。
SYN(Synchronization)同步位,SYN = 1表示連接請求報文。
FIN(Finish)終止位,FIN = 1表示釋放連接。
窗口
  • 佔16位:0 ~ 2 ^ 16 - 1

  • 「窗口指明允許對方發送的數據量。例如:確認號爲201,窗口爲300,那麼可以接收序號的範圍爲 201 ~ 500」

校驗和

與 UDP 類似,用來檢測 TCP 的數據在傳輸過程中是否出錯。

緊急指針
  • 「緊急數據(URG = 1)」

  • 「指定緊急數據在報文中的位置」

TCP 選項
  • 「最多40字節」

  • 「支持未來的擴展」

4、可靠傳輸的基本原理

1)、停止等待協議

當發送方發送一個消息時,接收方接收到了並將確認信息發給發送方,這個過程中 「發送方需要停止等待接收方的確認信息」

超時重傳

當消息發送出去後,發送方並沒有在超時時間內接收到接收方的確認消息或者超時了之後消息才收到,此時會向發送方重新發送該消息。超時重傳「通常都會處理三種異常情況」,如下所示:

  • 1)、「發送的消息在路上丟失了」

  • 2)、「確認的消息在路上丟失了」

  • 3)、「確認的消息超時了纔到」

超時定時器(超時重傳定時器)

  • 1)、「每發送一個消息,都需要設置一個超時定時器」

  • 2)、「主要應用在 TCP 的可靠傳輸協議裏面,它是爲了控制可能發生丟失的報文而設計的定時器,當 TCP 協議發送端發送一個報文時,就會爲該報文設置一個超時定時器」

  • 3)、「如果超時定時器在結束之前收到了來自接收端對該報文段的確認,則撤銷這個定時器」

  • 4)、「如果在超時定時器結束之前仍然沒有收到來自接收端對該報文段的確認(超時),則認爲這個報文可能已經丟棄,發送端會重新發送該報文,並設置一個超時定時器」

  • 5)、「需要注意的是,發送端在超時定時器撤銷之前,必須繼續緩存已發送未確認的報文,直到發送端收到了來自接收端的確認」

特點

  • 1、「停止等待協議是最簡單的可靠傳輸協議」

  • 2、「對信道的利用效率不高」

既然單個發送和確認效率低,那麼我們可以批量發送和確認嗎?

2)、連續 ARQ(Automatic Repeat Request) 自動重傳請求協議

ARQ 是對停止等待協議的改進,可以 「大幅提升信道利用率」 的一個協議。

滑動窗口

  • 1)、「窗口中的數據都可以發送」

  • 2)、「通過移動窗口的方式來標識沒有接收到確認的消息」

  • 3)、「採用了累積確認的方式,並不需要對每一個消息都進行確認」

累積確認

只要我收到第5個消息的確認了,就表示第 1 ~ 5 個消息接收方都收到了。

5、TCP 協議的可靠傳輸

TCP 的可靠傳輸基於連續 ARQ 協議。

  • 1)、「滑動窗口」

  • 2)、「累積確認」

  • 3)、「選擇重傳」

選擇重傳

  • 1)、「選擇重傳需要制定需要重傳的字節」

  • 2)、「每一個字節都有唯一的32位序號(4字節)」

  • 3)、「要重傳的數據是存儲在 TCP 選項 中,其中最多隻能存儲10個序號,即 5 個範圍段的信息」

  • 4)、「選擇重傳的是一個信息邊界,即一段字節流,例如:傳送 1000 ~ 1200, 2000 ~ 3000 這個範圍內的信息」

6、TCP 協議的流量控制

流量控制指的是 「讓發送方發送速率不要太快。TCP 使用了滑動窗口來實現流量控制」

1)、滑動窗口

  • rwnd = 300 ,表示窗口大小爲300。

  • 佔16位:0 ~ 2 ^ 16 - 1。

  • 窗口指明允許對方發送的數據量。例如:確認號爲201,窗口爲300,那麼可以接收序號的範圍爲 201 ~ 500。

  • 「接收方可以調整滑動窗口的大小來控制發送方發送數據的效率」

  • 「當接收方將 rwnd 從0調整爲1000並將這個信息發送給發送方時,消息丟失了,這就會導致發送方和接收方都會等待,形成一個死鎖局面」

如何解決這種死鎖局面呢?

2)、堅持定時器

堅持定時器是使用滑動窗口進行流量控制的時候設置的。

  • 1)、「當接收到窗口爲0的消息,則啓動堅持定時器」

  • 2)、「堅持定時器每隔一段時間發送一個窗口探測報文」

7、TCP 協議的擁塞控制

問題

  • 一條數據鏈路經過非常多的設備。

  • 數據鏈路中各個部分都有可能成爲網絡傳輸的瓶頸。

流量控制與擁塞控制的區別

「不同於流量控制考慮的是點對點的通信量的控制,擁塞控制考慮的是整個網絡,是一個全局性的考慮」

如何判斷是否發生了擁塞?

「簡單地認爲報文超時就發生了擁塞」

TCP 的擁塞控制

1)、慢啓動算法
  • 「由小到大逐漸增加發送數據量(呈指數增長,例如:1、2、4、8、16)」

  • 「每收到一個報文確認,就加一」

  • 「超過慢啓動閾值(ssthresh) 則不再增長」

2)、擁塞避免算法
  • 「維護一個擁塞窗口的變量」

  • 「只要網絡不擁塞,就試探着將擁塞窗口調大」

「TCP 的擁塞控制在前期使用了 慢啓動 算法對窗口大小進行指數增長,直到超過慢啓動閾值(ssthresh)則不再增長,後續則啓動擁塞避免算法對窗口進行線性增長」

8、TCP 鏈接的建立 - 三次握手

爲什麼發送方要發出第三個確認報文呢?

  • 1)、「已經失效的連接請求報文傳送到對方,引起錯誤:假設兩次握手就可以,失效的鏈接請求報文就會被接收並建立了重複的連接。當使用三次握手時,比較慢到達接收方的報文也會發送一個確認給發送方,但是發送方已經進行了第三次握手了,因此發送方會忽略掉第二次的確認,不會進行任何的操作」

  • 2)、「因爲信道不可靠,而 TCP 想在不可靠信道上建立可靠地傳輸,那麼三次通信是理論上的最小值。(而 UDP 則不需建立可靠傳輸,因此 UDP 不需要三次握手)」

  • 3)、「因爲雙方都需要確認對方收到了自己發送的序列號,確認過程最少要進行三次通信」

9、TCP 鏈接的釋放 - 四次揮手

1)、等待計時器

  • 會等待 2MSL 時間 => 4分鐘。

  • 時間等待定時器是由是在四次揮手時由主動關閉 TCP 連接的一方設置的,它主要是爲了 「保證主動關閉方在對最後一個 FIN 報文(第三次揮手)發送確認的報文可以到達接收方」

  • MSL(Max Segment Lifetime): 最長報文段壽命。MSL 建議設置爲2分鐘。

2)、爲什麼需要等待 2MSL?

  • 1)、「因爲最後一個報文沒有確認,我們需要確保發送方的 ACK 可以達到接收方,如果 2MSL 時間內沒有收到,則接收方會重發」

  • 2)、「2MSL 時間可以保證當發送方沒有收到確認時,接收方可以再次發送 FIN 報文,並且接收方可以再次收到並重新發送確認,所以 2MSL 的時間可以保證連接正常結束」

  • 3)、「確保當前連接的所有報文都已經過期了」

10、TCP 與UDP 的區別

  • 1)、「UDP 通常用於多媒體信息分發,即視頻、語音、實時信息 等等。而 TCP 通常用於可靠信息的傳輸,應用場景包括金融交易、可靠通信、MQ 等等」

  • 2)、「TCP 面向連接,UDP 是無連接的」

  • 3)、「TCP 提供可靠的服務,也就是說,通過 TCP 連接傳送的數據,無差錯,不丟失,不重複,且按序到達;UDP 盡最大努力交付,即不保證可靠交付」

  • 4)、「TCP 的邏輯通信信道是全雙工的可靠信道;UDP 則是不可靠信道」

  • 5)、「每一條 TCP 連接只能是點到點的;UDP 支持一對一,一對多,多對一和多對多的交互通信」

  • 6)、「TCP 面向字節流(可能出現黏包問題),實際上是 TCP 把數據看成一連串無結構的字節流;UDP 是面向報文的(不會出現黏包問題)」

  • 7)、「UDP 沒有擁塞控制,因此網絡出現擁塞不會使源主機的發送速率降低(對實時應用很有用,如 IP 電話,實時視頻會議等)」

  • 8)、「TCP 首部開銷20字節;UDP 的首部開銷小,只有 8 個字節」

11、套接字(Socket)

我們可以使用端口(Port)來標記不同的網絡進程,而端口使用了16比特位表示(0~65535)。

1)、Socket 概念

  • 套接字是一個抽象的概念,表示 TCP 連接的一端。

  • 通過套接字可以進行數據的發送或接收。

  • TCP = { Socket1:Socket2} = {{IP:Port}{IP:Port}},可以看到,TCP 由兩個套接字組成。

2)、Socket 編程

服務端編程

  • 1)、「創建 Socket」

  • 2)、「綁定 Socket」

  • 3)、「監聽 Socket」

  • 4)、「接收 & 處理信息」

其代碼如下所示:

import socket


def server():
    # 1、創建 Socket
    s = socket.socket()
    host = "127.0.0.1"
    port = 5678

    # 2、綁定 Socket
    s.bind(host, port)

    # 3、監聽
    s.listen()

    # 4、發送數據
    while True:
        c, addr = s.accept()
        print("connect addr", addr)
        c.send(b'Socket Study.')
        c.close()
複製代碼

客戶端編程

  • 1)、「創建 Socket」

  • 2)、「連接 Socket」

  • 3)、「發送消息」

其代碼如下所示:

import socket


def client(i):
    # 1、創建 Socket
    s = socket.socket()

    # 2、連接 Socket
    s.connect(('127.0.0.1', 5678))

    # 3、接收消息
    print("Received message:%s, client Id:%d" % (s.recv(1024), i))
    s.close()


if __name__ == '__main__':
    for i in range(10):
        client(i)
複製代碼

單機通信更推薦使用域 Socket,相比網絡通信數據需要在整個協議棧走一輪,域 Socket 它的處理流程更加簡單,系統消耗更加小。此外,如果對 Socket IO 實現機制有興趣的同學可以 點擊此處.

12、TCP 協議細節之 TCP 協議的四個定時器

  • 1)、「超時定時器」

  • 2)、「堅持定時器」

  • 3)、「時間等待定時器」

  • 4)、「保活定時器」:服務端一般都會設置一個保活定時器,它是爲了保活 TCP 連接而設計的,可以防止 TCP 連接的兩端出現長時間的空閒,當一方出現變化或故障時,另一方沒有察覺的情況。當服務端每次收到對方的數據則重置這個定時器,如果定時器超時,則會發送彈出報文段,以此探測客戶端是否在線,如果沒有收到響應的話,那麼則認爲客戶端已經斷開連接了,因此服務端也會終止這個鏈接。現如今,很多的分佈式系統都會使用保活定時器來檢測其它節點是否在線還是已經故障,或者其它節點也會每隔一段時間向主節點上報心跳信息以證明在線。

13、TCP 在三次握手的時候,IP 層和 MAC(Medium Access Control) 層在做什麼呢?

其實 TCP 每發送一個消息,都會帶着 IP 層和 MAC 層。因爲 TCP 每發送一個消息,IP 層和 MAC 層的所有機制都要運行一篇。

需要注意的是,「只要是在網絡上跑的包,都是完整的。可以有下層沒上層,絕對不可能有上層沒下層。所以,對 TCP 來說,無論是三次握手還是重試,只要想包網絡包發送出去,就要有 IP 層和 MAC 層,不然是發不出去的」

深入探索 Android 網絡優化(一、網絡築基篇)下


作者:jsonchao
鏈接:https://juejin.im/post/5eba5a39e51d454de64e49b1

Contanct Me

● 微信:

歡迎關注我的微信:bcce5360

關注我獲取更多知識或者投稿

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