開發中最全網絡相關內容

iOS中網絡相關內容

聲明:部分圖片來源於網絡,有些內容也來自各個平臺老師講解的視頻,部分內容來自《計算機網絡》這本書中,除去參考其他博客鏈接外,其他部分不作出參考鏈接來源展示,如有相關原創博客有雷同,聯繫我附上出處鏈接,尊重原創作品,本博文不作商業用途,只是加上自己的理解總結大神們的精華,便於廣大的開發者查找

整體目錄

  1. 網絡中的7層模型
  2. 應用層的HTTP、HTTPS
  3. 對稱加密,非對稱加密,混合加密
  4. HTTPS建立連接流程
  5. 網絡層中的IP協議IP數據報首部概述
  6. 傳輸層中的TCP與UDP協議
  7. DNS解析
  8. TCP三次握手與四次揮手
  9. TCP流量控制,擁塞控制,可靠傳輸
  10. 結束語

1. 網絡中的7層模型

在計算機網絡中,我們把對網絡七層協議從上到下,分別定義爲:
在這裏插入圖片描述

  • 應用層: 爲操作系統或網絡應用程序提供訪問網絡服務的接口,例如我們常見的:TeInte、FTP、HTTP、SNMP、DNS等
  • 表示層:解密與加密,圖片解碼與編碼,數據的壓縮與解壓縮,例如我們常見的有:URL加密、口令加密、圖片編解碼等
  • 會話層:主要是使用校驗點使會話在通信是小時從校驗點恢復通信,例如:服務器驗證用戶登錄、斷點續傳
  • 傳輸層:建立連接,處理數據包錯誤,數據包次序,例如:TCP、UDP、SPX
  • 網絡層:對子網間的數據包進行路由選擇,例如路由器、多層交換機、防火牆,IP協議
  • 鏈路層:將數據分幀、物理地址尋址,例如:網卡,網橋,二層交換機等
  • 物理層:傳輸介質 例如網線等

那麼對於我們客戶端的同學,其實網絡大概分爲3層就足夠我們去研究,分別爲應用層、傳輸層、網絡層,所以,在這裏着重的展開對這四個層定義的概述:

應用層(Application Layer):

(象徵性的說一些沒用的屁話)主要負責對軟件提供接口以使程序能使用網絡服務。術語“應用層”並不是指運行在網絡上的某個特別應用程序 ,應用層提供的服務包括文件傳輸、文件管理以及電子郵件的信息處理。
常見的協議:HTTPFTPHTTPSDNS
以下篇章裏着重介紹HTTP,HTTPS

傳輸層(Transport Layer)

定義了一些傳輸數據的協議和端口號(WWW端口80等),如:TCP(傳輸控制協議,傳輸效率低,可靠性強,用於傳輸可靠性要求高,數據量大的數據),UDP(用戶數據報協議,與TCP特性恰恰相反,用於傳輸可靠性要求不高,數據量小的數據,如QQ聊天數據就是通過這種方式傳輸的)。 主要是將從下層接收的數據進行分段和傳輸,到達目的地址後再進行重組。常常把這一層數據叫做段。
在以下篇章裏講述UDP差錯校驗已經TCP差錯校驗與流量控制

網絡層(Network Layer)

網絡層通過綜合考慮發送優先權、網絡擁塞程度、服務質量以及可選路由的花費來決定從一個網絡中節點A 到另一個網絡中節點B 的最佳路徑。由於網絡層處理,並智能指導數據傳送,路由器連接網絡各段,所以路由器屬於網絡層。在網絡中,“路由”是基於編址方案、使用模式以及可達性來指引數據的發送。
以下篇章終點闡述:IP協議

2.應用層的HTTP、HTTPS、DNS解析

HTTP協議概念

闡述HTTP的概念,大致目錄爲:

  1. HTTP基本概念
  2. HTTP請求方式
  3. HTTP特點

超文本傳輸協議,HTTP是基於TCP的應用層協議
請求報文與響應報文:
在這裏插入圖片描述
請求報文:
在這裏插入圖片描述

GET /8qUJcD3n0sgCo2Kml5_Y_D3/v.gif?pid=201&pj=www&fm=behs&qid=81f0291600046ade&tab=indexHot&path=https%3A%2F%2Fwww.baidu.com%2F&wd=&rsv_sid=31658_1445_31671_21080_31591_31605_31464_31715_30823&rsv_did=22f98012412ca12cf10abc42251952bc&t=1590563319831 HTTP/1.1
Host: sp1.baidu.com
Connection: keep-alive
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36
Accept: image/webp,image/apng,image/*,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8  
//以上是首部行
(此處必須有一空行)  //空行分割header和請求內容 
name=world   請求體
  • Host:指明瞭該對象所在的主機
  • Content-Type:首部行用來表明 HTTP會將請求參數用key1=val1&key2=val2的方式進行組織,並放到請求實體裏面
  • Connection:告訴服務端使用持久連接
  • User-agent:首部行用來指明用戶代理,即向服務器發送請求的瀏覽器類型
  • Accept-Language:首部行表示用戶想得到該對象的法語版本(如果服務器中有這樣的對象的話),否則,服務器應發送它的默認版本

響應報文:
在這裏插入圖片描述

HTTP/1.1 200 OK    
//以上是狀態行:協議版本字段、狀態碼、相應狀態信息
Connection:close
Server:Apache/2.2.3(CentOS)
Date: Mon, 5 Dec 2020 23:59:59 GMT
Content-Type: text/html
Content-Length: 103
//以上是首部行
(此處必須有一空行)  //空行分割header和實體主體
(data data data data)//響應實體主體
  • Connection:close首部行告訴客戶,發送完報文後將關閉TCP連接。
  • Server:首部行指示該報文是由一臺Apache Web服務器產生的,類似於HTTP請求報文裏的User-agent
  • Date:指的不是對象創建或最後修改的時間,而是服務器從文件系統中檢索到該對象,插入到響應報文,併發送該響應報文的時間。
  • Content-Type:部行指示了實體體中的對象是HTML文本
  • Content-Length:首部行指示了被髮送對象中的字節數

一些常見的狀態碼:

狀態碼 含義
200 請求成功,返回數據在請求響應報文中
301 請求發生了重定向,拿到服務器返回的這個狀態碼後會自動跳轉到一個新的URL地址,這個地址可以從響應的Location首部中獲取
400 客戶端請求錯誤,服務無法識別該請求
404 被請求的文件不在該服務器
5XX 與服務器相關的問題

一般以4開頭的狀態碼,幾乎都與客戶端相關,以5開頭的代碼,幾乎都與服務器相關

HTTP協議請求方式

GET、POST、PUT、DELETE、HEAD、OPTIONS
這裏重點說明GETPOST請求
GET
首先GET請求是:安全的 冪等的 可緩存的
安全:這裏的安全是指不應引起Server端的任何狀態變化
冪等:同一個請求方法執行多次和執行一次的效果完全相同
可緩存:請求是否可以被緩存,GET請求會主動進行Cache

  • GET的請求參數一般以?分割拼接到URL後面
  • GET參數長度限制爲2048個字符
  • GET請求由於參數裸露在URL中, 是不安全的(這裏的不安全是指在外界通過外部很容易就能能獲取到參數,並非語義上的安全的概念)

POST
首先POST請求是:非安全的 非冪等的 不可緩存的
非安全:可能會引起服務器狀態變化的,即是不安全的
非冪等:同一個請求方法執行多次和執行一次的效果可能不相同,例如執行刪除等等的操作
可緩存:POST請求不可緩存

GET和POST本質上就是TCP鏈接,並無差別。但是由於HTTP的規定和瀏覽器/服務器的限制,導致他們在應用過程中體現出一些不同。
在響應時,GET產生一個TCP數據包;POST產生兩個TCP數據包:對於GET方式的請求,瀏覽器會把Header和實體主體一併發送出去,服務器響應200(返回數據);
而對於POST,瀏覽器先發送Header,服務器響應100 Continue,瀏覽器再發送實體主體,服務器響應200 OK(返回數據)。

這裏並不是說POST請求就一定要比GET請求要好,是要看具體的需求而定,如果是隻讀顯示類的需求,還是優先使用GET請求,減少傳輸過程中額外個開銷,同事由於可以緩存,所以會大大減少服務器的開銷

HTTP特點

無狀態無連接
無狀態:即協議對於事務處理沒有記憶能力。
每次的請求都是獨立的,它的執行情況和結果與前面的請求和之後的請求時無直接關係的,它不會受前面的請求應答情況直接影響,也不會直接影響後面的請求應答情況
也就是說服務器中沒有保存客戶端的狀態,客戶端必須每次帶上自己的狀態去請求服務器
標準的HTTP協議指的是不包括cookies,session,application的HTTP協議

無連接:即當本次請求完成結束後,就會斷開連接,也就是說每個連接處理一個請求。想要一個連接可以處理多個請求,那麼我們就需要保持持久力連接
如果想要保持持久連接,那麼需要加上Cookie/Session的輔助。持久連接情況下,服務器發出響應後讓TCP連接繼續打開着。同一對客戶/服務器之間的後續請求和響應可以通過這個連接發送。
對於非持久連接,TCP得在客戶端和服務端分配TCP緩衝區,並維持TCP變量,會嚴重增加服務器負擔。因爲TCP有流量控制,後續會講到,會增加每次請求的等待時長
在這裏插入圖片描述
那麼在網絡請求過程中,我們是怎麼判斷一個HTTP請求結束的呢?在這裏引用慕課網有關講解HTTP的一些方法:(不建議大家去聽該老師,看看課件就行了,在這裏只是標明原創的出處)

  • 根據所接收字節數是否達到Content-length
  • 當選擇分塊傳輸時chunked,響應頭中可以不包含Content-Length,服務器會先回復一個不帶數據的報文(只有響應行和響應頭和\r\n),然後開始傳輸若干個數據塊。當傳輸完若干個數據塊後,需要再傳輸一個空的數據塊,當客戶端收到空的數據塊時,則客戶端知道數據接收完畢。

HTTPS協議

首先我們用一張圖來對比HTTP與HTTPS
HTTP:
在這裏插入圖片描述
HTTPS:
在這裏插入圖片描述
HTTPS基於HTTP協議,通過SSL或TLS提供加密處理數據、驗證對方身份以及數據完整性保護,也可以理解爲HTTPS = HTTP + SSL/TLS協議
SSL:全稱是Secure Sockets Layer,即安全套接層協議,是爲網絡通信提供安全及數據完整性的一種安全協議。
TLS:的全稱是Transport Layer Security,即安全傳輸層協議。

3. 對稱加密、非對稱加密、混合加密

我們想要了解HTTP/HTTPS傳輸過程,就不得不先了解這些加密的含義
對稱加密
對稱加密,顧名思義,加密方與解密方使用同一鑰匙(祕鑰)。具體一些就是,發送方通過使用相應的加密算法和祕鑰,對將要發送的信息進行加密;對於接收方而言,使用解密算法和相同的祕鑰解鎖信息,從而有能力閱讀信息。
常見的算法有:DES、3DES、Blowfish…
在這裏插入圖片描述

非對稱加密
在對稱加密中,發送方與接收方使用相同的祕鑰。那麼在非對稱加密中則是發送方與接收方使用的不同的祕鑰。其主要解決的問題是 防止在祕鑰協商的過程中發生泄漏。比如在對稱加密中,假如一個渣男和情婦打電話說今晚去哪裏哪裏約會,順便將房號以對稱加密的方式發送到對方手機,而不巧的是渣男老婆僱了私人偵探竊取到了這個公共祕鑰,這樣很容易發生不愉快的事情,那麼如果渣男以情婦的公鑰加密發送短信,即使偵探拿到公鑰後,因爲沒有情婦的私鑰,也無法解密相關房號信息…
公鑰算法:RSA等:
在這裏插入圖片描述

混合加密
爲什麼要使用混合加密呢,首先,非對稱加密的解密過程是一個相當耗時打的操作,如果發送的信息很長,那麼解密時需要消耗大量的時間,渣男情婦等不了啊…那麼急於這麼一個原因,就有人研究出混合加密算法,發短信的信息可以使用對稱加密,將對稱加密的祕鑰進行非對稱加密,也就是說,非對稱加密的內容其實是對稱加密的祕鑰,也就是一串數字,即實現了防止在傳輸中途被竊取,又解決了解密時間長的問題
在這裏插入圖片描述
圖中的會話祕鑰:通過隨機數加對稱加密算法生成,可以簡單的理解爲對稱加密祕鑰

指紋
在這裏,我也提一下與數字簽名有關的東西,首先我們要知道單向散列函數
單向散列函數(哈希函數):在這裏我只是簡單的介紹一下,不展開敘述,單向散列函數可以根據任意長度的消息,計算出固定長度的散列值,這個計算過程速度很快,散列函數輸出的散列值通常又被成作爲指紋,消息不同,散列值就不同,而且,根據散列值,無法確定出原來的消息是什麼,稱爲不可逆,所以,散列函數是單向的
在這裏插入圖片描述
常見的單向散列函數算法有:MD5SHA1SHA2

那麼這個數字簽名是幹什麼用的呢?其實很好理解,不要和我們對稱加密,非對稱加密,混合加密混到一塊,我們可以試想這麼一個場景:
在這裏插入圖片描述
Bob突然接收到Alice發送的一段消息,解密後就裂開了,打電話找Alice理論,Alice很委屈,說不是他發送的,那麼爲了證明是不是Alice發送的,就需要用到單向散列函數,對Alice發送的消息進行指紋的輸出,生成一個數字指紋,那麼當Bob接收到這段消息的明文時候,可以再次利用單向散列函數進行散列值的輸出,然後對比兩個指紋,一樣的話,沒毛病,就是Alice發的,友誼的小船說翻就翻,不一樣的話,證明確實不是Alice發的,是別人僞裝的.

數字簽名
數字簽名基於指紋加上非對稱加密實現的傳輸過程,廢話不多說,直接上圖
在這裏插入圖片描述
首先

  1. 在圖中沒有反映,就是Alice要生成自己的公私鑰,將公鑰給Bob
  2. Alice用單向散列函數進行散列值輸出
  3. Alice用自己的私鑰對散列值(指紋進行)加密,這一步叫做簽名
  4. 利用混合加密的方式發送消息的同時,將自己私鑰加密後的簽名發送給Bob
  5. Bob通過自己的私鑰解密Alice發送過來的消息,用同樣的單向散列函數對Alice發送過來的消息進行散列值輸出
  6. Bob同時用Alice的公鑰對Alice的簽名進行解密
  7. 將這兩個散列值進行對比

敲黑板!!!!:這裏同時也爲iOS端App數字簽名的原理,也就是你從Appstore官網上下載的證書,打包簽名一系列的流程,在這裏都是這個原理,這裏考慮到篇幅,不在過多贅述

總結下數字簽名的作用

  • 可以保證數據的完整性
  • 防止別人篡改消息
  • 防止別人否認自己發送的消息

4.HTTPS建立連接流程

此段原文出處:(點我看原文(其實原文也是對慕課網網絡這節課的總結))
在HTTP中,也同時使用了混合加密的方式進行加密
在這裏插入圖片描述

  • 服務端生成的私鑰公鑰,用來非對稱加密
  • 客戶端生成臨時的會話祕鑰,用來進行對稱加密

過程:

  1. 客戶端訪問HTTPS連接
    客戶端會把安全協議版本號客戶端支持的加密算法列表隨機數C發給服務端。
  2. 服務端發送證書給客戶端
    服務端接收密鑰算法配件後,會和自己支持的加密算法列表進行比對,如果不符合,則斷開連接。否則,服務端會在該算法列表中,選擇一種對稱算法(如AES)、一種公鑰算法(如具有特定祕鑰長度的RSA)和一種MAC算法發給客戶端。服務器端有一個密鑰對,即公鑰私鑰,是用來進行非對稱加密使用的,服務器端保存着私鑰,不能將其泄露,公鑰可以發送給任何人。
    在發送加密算法的同時還會把數字證書隨機數S發送給客戶端
  3. 客戶端驗證server證書
    會對server公鑰進行檢查,驗證其合法性,如果發現發現公鑰有問題,那麼HTTPS傳輸就無法繼續。驗證方式爲上面提到的指紋認證
  4. 客戶端組裝會話祕鑰
    如果公鑰合格,那麼客戶端會用服務器公鑰來生成一個前主祕鑰(Pre-Master Secret,PMS),並通過該前主祕鑰和隨機數CS來組裝成會話祕鑰
  5. 客戶端將前主祕鑰加密發送給服務端
    是通過服務端的公鑰來對前主祕鑰進行非對稱加密,發送給服務端
  6. 服務端通過私鑰解密得到前主祕鑰
    服務端接收到加密信息後,用私鑰解密得到主祕鑰
  7. 服務端組裝會話祕鑰
    服務端通過前主祕鑰隨機數CS來組裝會話祕鑰。
    至此,服務端和客戶端都已經知道了用於此次會話的主祕鑰
  8. 數據傳輸
    客戶端收到服務器發送來的密文,用客戶端密鑰對其進行對稱解密,得到服務器發送的數據。
    同理,服務端收到客戶端發送來的密文,用服務端密鑰對其進行對稱解密,得到客戶端發送的數據。

會話祕鑰 = random S+ random C+ 前主祕鑰

5. 網絡層中的IP協議

我在寫這篇博文的時候順序調整了很久,最後將IP協議調整到了第四部分,因爲,想要了解構建請求過程,就必須瞭解TCP協議,要想了解TCP協議,就涉及到TCP協議的差錯校驗已經流量控制來保證可靠傳輸,有序傳輸,要想了解TCP的可靠傳輸與有序傳輸,那我們必須瞭解IP協議的無序性,這樣纔有對比

IP協議的數據報格式(IPV4爲例)

在這裏插入圖片描述

  • 版本號:佔四位,就是IP協議的版本,通信雙方的IP協議必須要達到一致,IPv4的版本就是4
  • 首部長度:佔四位,因爲長度爲四比特,所以首部長度的最大值爲1111,15,又因爲首部長度代表的單位長度爲32個字(也就是4個字節),所以首部長度的最小值就是0101,當然,也確實如此,大部分的ip頭部中首部字節都是0101.也就是5*4=20個字節,如果是最大值15的話,ip首部的最大值就是60個字節,所以記好了,ipv4首部長度的最大值就是60,當然當中我們又能發現,IPv4的首段長度一定是4字節的整數倍,要是不是怎麼辦呢?別急,後面的填充字段會自動填充補齊到4字節的整數倍的。
  • 這個沒有什麼用處,也沒有什麼好講的了,只要自動這玩意佔八位,一個字節就可以了
  • 總長度:佔16位,這個的意思就是ip數據報中首部和數據的總和的長度,因爲佔16位,所以很好理解,總長度的最大值就是2的16次方減一,65535,這玩意也對應着還有一個很簡單的概念,最大傳輸單元mtu,意味着一個IP數據報的最大長度就只能裝下65535個字節,要是傳輸的長度超過這個怎麼辦,很簡單,分片。
  • 位標識(id):佔16位 唯一的標識主機發送的報文. 如果IP報文在數據鏈路層被分片了, 那麼每一個片裏面的這個id是相同的
  • 3位標誌位:第一位保留,第二位置爲1表示禁止分片, 這時候如果報文長度超MTU, IP模塊就會丟棄報文. 第三位表示”更多分片”, 如果分片了的話, 最後一個分片置爲1, 其他是0
  • 片偏移:佔13位,是分片相對於原始IP報文開始處的偏移. 其實就是在表示當前分片在原報文中處在哪個位置
  • 生存時間(TTL):數據報到達目的地的最大報文跳數
  • 協議類型:佔8位,表示上層協議的類型
  • 校驗和:佔16位重點首部檢驗和我們要說一下

在這裏插入圖片描述

過程爲

  1. 發送數據報時首先將ip首部的校驗和全部置爲0,然後,以16位爲單位,全部相加,如果有進位,那麼加到第四位,然後將加起來的和取按位反碼得到校驗和
  2. 接收數據時,將首部以16位爲單位相加,包括校驗和,然後再取反,看結果是否爲0,是0則保留,非0則丟棄
  • 源地址和位目標地址:各佔32位,表示發送端和接收端
  • 選項:位數不定,最多40個字節,因爲首部20個字節,一個IP數據報最大是60個字節

6. TCP與UDP

TCP:Transmission Control Protocol 傳輸控制協議
UDP:User Datagram Protocol 用戶數據報協議
這兩個協議均屬於傳輸層協議

UDP

面向非連接的協議,傳送數據不需要和服務器連接,只需要知道ip和監聽端口,不需要鏈接沒有目的的socket,只是將數據報投遞出去,不管接收方是否成功接收到,是一種不可靠的傳輸。

UDP特點:
  • UDP是無連接的,即通信時不需要創建連接(發送數據結束時也沒有連接可以釋放)所以減小了開銷和發送數據前的時延;
  • UDP採用最大努力交付,不保證可靠交付,因此主機不需要維護複雜的連接狀態
  • UDP是面向報文的,只在應用層交下來的報文前增加了首部後就向下交付IP層
  • UDP是無阻塞控制的,即使網絡中存在阻塞,也不會影響發送端的發送頻率
  • UDP的首部開銷小,只有8個字節,它比TCP的20個字節的首部要短。
  • 可以一對多,一對一,多對一
UDP的報文結構

在這裏插入圖片描述
應用層數據佔用UDP報文段的數據字段。UDP首部只有4個字段,每個字段由2個字節組成,即UDP首部僅有8字節。

  • 端口號:可以使目的主機將應用數據交給運行在目的端系統中端相應進程,執行分用功能
  • 長度:該字段指示了在UDP報文段中的字節數(首部+數據)
  • 檢驗和:接收方使用檢驗和來檢查在該報文段中是否出現了差錯,即差錯檢測。
    UDP的校驗和與IP校驗和算法稍有不同:
  1. 沒有將校驗和位置0的過程,將3個字全部相加後按位取反碼存入校驗和中,相加的時候如果出現最高位有進位則回捲加到到最低位。
  2. 接收端將4個字全部相加,如果爲11111111 11111111,如果這16位置有0出現,那麼就出現了差錯

舉個例子:
0110011001100000
0101010101010101
1000111100001100
這是首部3個字 每個字16位,佔2個字節,前兩個字相加後得到
1011101110110101
然後與第三個字相加
10100101011000001 發現有溢出,那麼將首位的1加到最後一位
0100101011000010
然後按位取反
1011010100111101
將該值存入到校驗和
接收端能接收到後,將這4個字全部相加得出
1111111111111111 那麼證明無差錯
UDP在端到端基礎上在運輸層提供差錯檢測,在系統設計中被稱爲端到端原則
而UDP雖然提供差錯檢測,但它對差錯恢復無能爲力。這就需要用到可靠數據傳輸–TCP了

TCP

TCP特點:
  • 面向連接
  • 可靠傳輸
  • 面向字節流
  • 全雙工服務
TCP的報文結構

在這裏插入圖片描述
如圖,與UDP一樣,首部包括源端口號目的端口號,用於多路複用/分解來自上層或送到上層應用的數據。TCP首部也同樣包括檢驗和字段
TCP首部還包含下列字段:

  • 32比特的序號字段seq(sequence number field)和32比特的確認號字段ack(acknowledge number field)
  • 4比特的首部長度字段(header length field),該字段指示了以32比特的字爲單位的TCP首部長度。由於TCP選項字段的原因,TCP首部長度是可變的。(通常,選項字段爲空,所以TCP首部的典型長度就是20字節)
  • 16比特的接收窗口字段RW(receive window field),該字段用於流量控制,用於指示接收方願意接收的字節數量。
  • 可選和變長的選項字段(option field),該字段用於發送方和接收方協商最大報文段長度(MSS)時,或用作窗口調節因子時使用。
  • 6比特的標誌字段(flag field)ACK比特用於指示確認字段中的值是有效的,即該報文段包括一個對已被接收報文段的確認。RSTSYNFIN比特用於連接建立和拆除。PSH比特指示接收方應立即將數據交給上層。URG比特用於指示報文段裏存在着被髮送端的上層實體置爲“緊急”的數據。緊急數據的最後一個字節由16比特的緊急數據指針字段指出。當緊急數據存在並給出指向緊急數據尾的指針的時候,TCP必須通知接收端的上層實體。在實踐中,PSH、URG和緊急數據指針並沒有使用。

在TCP通訊中,無論是建立連接,數據傳輸,友好斷開,強制斷開,都離不開Seq值和Ack值,它們是TCP傳輸的可靠保證。

序號字段seq和確認號字段ack:
  • 序列號seq
    TCP把數據看成一個無結構的、有序的字節流。一個報文段的序號因此是該報文段的首字節的字節流編號。
    比如數據流由一個包含100000字節的文件組成,其MSS是1000字節,數據流的首字節編號是0。該TCP將爲該數據流構建100個報文段。給第一個報文段分配序號0,第二個則是1000,第三個是2000,以此類推。每一個序號被填入到相應TCP報文段首部的序號字段seq中。
  • 確認號ack
    TCP是全雙工服務的,因此主機A在向主機B發送數據的同時,也許也在接收主機B的數據。
    主機A填充進報文段的確認號是主機A期望從主機B收到的下一個字節的序號。
    在上個例子中,假如服務端已經接收包含字節0-999的報文段和包含字節2000-2999的報文段,但由於某種原因,還未收到包含字節1000-1999的報文段,那麼將仍會等待字節1000(及其後的字節)。因此服務端發給客戶端的下一個報文段將在確認號ack字段中包含1000
    因爲TCP只確認該流中至第一個丟失字節爲止的字節,所以TCP被稱爲累積確認

總結:以上闡述了TCP和UDP的報文結構以及字段含義,TCP中的SEQ,seq,和ack,ACK將會在下文講述的三次握手中用到,所以,先了解概念

7.DNS解析

首先來說一說域名解析的由來,我們爲什麼要進行域名解析?
我們要對一個服務器發送請求,那麼我們就得知道對方的地址,比如說你要想拜訪你的朋友,你先得知道他住在哪裏。表示他住在哪裏有兩種方式

  1. 他直接告訴你他在哪裏,比如說他住在朝陽區東四環朝陽公園橋外的東山墅,這是個地名,很好記,當你需要把這個位置告訴導航的時候,你只需要輸入地名,可是導航地圖不喜歡啊,它自己得解析這個地名得到經緯度,因爲經緯度是它喜歡的表達方式
  2. 你的朋友腦子抽風,告訴你說,我的地址在經度:xxx, 緯度:xxx的地方,你瞬間就裂開了…這是人說的話嗎?但是導航軟件內部卻更中意這樣的表達方式

基於平衡這兩種情況,我們就需要域名解析:
因特網上的主機,可以使用主機名或者IP地址標識他的位置
例如 www.baidu.com、www.google.com,這種屬於主機名,很好記,但是長度不統一,沒有規律,路由器處理起來不太方便,還有一種就是直接上ip,比如220.xxx.xxx.xxx,是一個定長的ip,這樣路由器處理起來就比較方便了
那麼給出DNS概念:

  • 一個由分層的DNS服務器實現的分佈式數據庫
  • 一個使得主機能夠查詢分佈式數據庫的應用層協議

而DNS服務器通常是運行BIND軟件的UNIX機器,DNS協議運行在UDP上,使用53號端口
DNS通常是由其他應用層協議所使用的,包括HTTP、SMTP等。其作用則是:將用戶提供的主機名解析爲IP地址
目前的DNS服務器大致分爲3種類型的DNS服務器:根DNS服務器頂級域DNS服務器權威DNS服務器

DNS解析過程
  • 遞歸查詢
    在這裏插入圖片描述
  • 迭代查詢

在這裏插入圖片描述

這種利用了迭代查詢和遞歸查詢,從Client與本地DNS之間是遞歸查詢,其餘則是迭代查詢。
所謂 遞歸查詢過程 就是 “查詢的遞交者” 更替, 而 迭代查詢過程 則是 “查詢的遞交者”不變。
從理論上講,任何DNS查詢既可以是迭代的也能是遞歸的。
在實際應用的過程中:
從請求主機到本地DNS服務器的查詢是遞歸,其餘查詢是迭代的
DNS解析的過程:

  1. 發起基於域名的請求後,首先檢查本地緩存(瀏覽器緩存–>操作系統的hosts文件)
  2. 如果本地緩存中有,直接返回目標IP地址,否則將域名解析請求發送給本地DNS服務器
  3. 如果本地DNS服務器中有,直接返回目標IP地址,到這一步基本能解析80%的域名。如果沒有,本地DNS服務器將解析請求發送給根DNS服務器
  4. 根DNS服務器會返回給本地DNS服務器一個所查詢的TLD服務器地址列表
  5. 本地DNS服務器再向上一步返回的TLD服務器發送請求,TLD服務器查詢並返回域名對應的權威域名服務器的地址
  6. 本地DNS服務器再向上一步返回的權威域名服務器發送請求,權威域名服務器會查詢存儲的域名和IP的映射關係表,將IP連同一個TTL(過期時間)值返回給本地DNS服務器
  7. 本地DNS服務器會將IP和主機名的映射保存起來,保存時間由TTL來控制
  8. 本地DNS服務器把解析的結果返回給用戶,用戶根據TTL值緩存在本地系統緩存中,域名解析過程結束
DNS劫持問題

在這裏插入圖片描述
一種可能的域名劫持方式即黑客侵入了寬帶路由器並對終端用戶的本地DNS服務器進行篡改,指向黑客自己僞造的本地DNS服務器,進而通過控制本地DNS服務器的邏輯返回錯誤的IP信息進行域名劫持。

另一方面,由於DNS解析主要是基於UDP協議,除了上述攻擊行爲外,攻擊者還可以監聽終端用戶的域名解析請求,並在本地DNS服務器返回正確結果之前將僞造的DNS解析響應傳遞給終端用戶,進而控制終端用戶的域名訪問行爲。

如何解決DNS劫持

DNS解析發生在HTTP協議之前,DNS解析和DNS劫持和HTTP沒有關係,DNS協議使用的是UDP協議向服務器的53端口進行請求。
所以,可以使用HttpDNS的方案:使用 HTTP協議向DNS服務器的80端口進行請求,來規避DNS劫持
比如:http://119.29.29.29/d?dn=domain&ip=clientIp

8. TCP三次握手與四次揮手

在建立請求後,DNS解析完成後,就找到了服務器相應的地址,接下來要做的,就是要對服務器進行連接
在連接之前,首先要進行3次握手

在這裏插入圖片描述

三次握手

在這裏插入圖片描述
首先我不認爲該圖很準確,因爲seq與SEQ,ackACK不是同一個東西,大寫的是個標誌位,而小寫的是存放信息的,看我下面的敘述
第一步

  1. 客戶端的TCP首先向服務端的TCP發送一條特殊的TCP報文段。該報文段不包含應用層數據,該報文段首部中的一個標誌位(SYN比特)被置爲1,所以該報文段被稱爲SYN報文段,另外,客戶會隨機選擇一個初始序號client_isn,並將該序號放置於該起始的TCP seq報文段的序號字段中。
  2. 客戶端和服務端最開始都處於CLOSED狀態,發送過該 SYN報文段後,客戶端TCP進入SYN_SENT狀態,等待服務端確認並將SYN比特置爲1的報文段。

第二步

  1. 收到SYN報文段後,服務端會爲該TCP連接分配TCP緩存和變量,服務端TCP會進入SYN_RCVD狀態,等待客戶端TCP發送確認報文段。
  2. 並向該客戶端TCP發送允許連接的報文段,該報文段同樣不包含應用層數據。該報文段首部的SYN比特被置爲1,確認號字段被置爲client_isn+1。服務端還會選擇自己的初始序號server_isn,放到報文段首部的序號段中。該連接被稱爲SYNACK報文段。

第三步

  1. 收到SYNACK報文段後,客戶端也要爲該TCP連接分配緩存和變量,客戶端TCP進入ESTABLISHED狀態,在此狀態,客戶端就能發送和接收包含有效載荷數據的報文段了。
  2. 並向服務端TCP發送一個報文段:這最後一個報文段對服務端的允許連接的報文表示了確認(將server_isn + 1放到報文段首部的確認字段中)。因爲連接已經建立了,所以該SYN比特被置爲0。這個階段,可以在報文段負載中攜帶應用層數據。
  3. 收到客戶端該報文段後,服務端TCP也會進入ESTABLISHED狀態,可以發送和接收包含有效載荷數據的報文段。
四次揮手

在這裏插入圖片描述
參與TCP連接的兩個進程中的任何一個都能終止該連接,當連接結束後,主機中的資源(緩存和變量)會被釋放。上邊說到,SYNFIN標誌位分別對應着TCP連接的建立和拆除。
第一步

  1. 客戶應用進程發出一個關閉連接的指令。會引起客戶端TCP向服務端發送一個特殊的TCP報文段。該報文段即是將首部的一個標誌位FIN比特置爲1
  2. 同時,客戶端進入FIN_WAIT_1狀態,等待服務端的帶有確認的TCP報文段。

第二步

  1. 收到該報文段後會向客戶端發送一個確認報文段。
  2. 服務端TCP進入CLOSE_WAIT狀態,對應客戶端的TIME_WAIT,表示被動關閉
  3. 客戶端收到該報文段後,進入FIN_WAIT_2狀態,等待服務端的FIN比特置爲1的報文段。

第三步

  1. 服務端發送自己的終止報文段,同樣是把報文段首部的標誌位FIN比特置爲1。
  2. 服務端TCP進入LAST_ACK狀態,等待服務端最後的確認報文段。

第四步
8. 客戶端收到服務端的終止報文段後,向服務端發送一個確認報文段。同時,客戶端進入TIME_WAIT狀態。
9. 假如ACK丟失,TIME_WAIT狀態使TCP客戶重傳最後的確認報文,TIME_WAIT通常會等待2MSL(Maximum Segment Lifetime 最長報文段壽命)。經過等待後,連接就正式關閉,重新進入CLOSED狀態,客戶端所有資源將被釋放。
10. 服務端收到該報文段後,同樣也會關閉,重新進入CLOSED狀態,釋放所有服務端TCP資源。

在這裏,或許有些讀者會問了

爲什麼要經歷3次握手與4次揮手呢?

2次握手
就好比如果是2次握手,比如你給要給小白兔發短信了你說,
大灰狼:“你是小白兔嗎?收到請回復”
(由於信號不好,延遲了,讓大灰狼重發)
大灰狼:“你是小白兔嗎?收到請回復”
小白兔:“我是小白兔呀”
2次握手連接就已經建立了
大灰狼和小白兔暢聊到天亮
天快亮的時候,大灰狼那條延遲短信到達了小白兔手機上,小白兔誤認爲大灰狼還想找他,並給大灰狼發短信:
小白兔:我是小白兔啊,怎麼了老鐵
然而大灰狼並沒有給小白兔發送什麼信息,大灰狼早就洗洗睡了,小白兔等啊等,一直等到老死了都沒等到渣狼,唉…這一輩子的等待,終究還是錯付了。
放在這裏呢:
客戶端發出的第一個連接請求SYN報文段並沒有丟失,而是在某個網絡結點長時間的滯留了,以致延誤到連接釋放以後的某個時間纔到達服務端。本來這是一個早已失效的報文段。但服務端收到此失效的連接請求SYN報文段後,就誤認爲是客戶端再次發出的一個新的連接請求SYN報文段。於是就向客戶端發出ACK確認報文段,同意建立連接。假設不採用三次握手,那麼只要服務端發出確認,新的連接就建立了。
由於現在客戶端並沒有發出建立連接的SYN請求,因此不會理睬服務端的確認,也不會向服務端發送數據。但服務端卻以爲新的運輸連接已經建立,並一直等待客戶端發來數據。這樣,服務端的很多資源就白白浪費掉了。
事實上:TCP對有數據的TCP報文段必須確認的原則,所以,客戶端對服務端的SYN報文段必須回覆一個ACK報文段表示確認。並且,TCP不會爲沒有數據的ACK超時重傳,那麼當服務端沒收到客戶端的ACK確認報文段時,會超時重傳自己的SYN報文段,一直到收到客戶端的ACK爲止。

4次握手
大灰狼:“你是小白兔嗎?你今天拉屎了麼?”
小白兔:“我是小白兔呀”
過了好長時間…
小白兔:“我今天拉屎了”
大灰狼:“這傻逼,不能一氣兒說完嗎”?

那麼其實在實際過程中,本來服務端的確認ack 可以與syn一起發送的,沒有必要單獨分開發送,浪費資源

四次揮手

  1. 首先,當客戶端數據已發送完畢,且知道服務端也全部接收到了時,就會去斷開連接即向服務端發送FIN
  2. 服務端接收到客戶端的FIN,爲了表示接收到了,就會向客戶端發送ACK
  3. 但此時,服務端可能還在發送數據,並沒有關閉TCP窗口的意思,所以服務端的FINACK並不是同步發的,只有當數據發送完了,纔會發送FIN

所以要進行4次揮手

在四次揮手中,客戶端爲什麼在TIME_WAIT後必須等待2MSL時間呢

最後服務器到客戶端的ACK報文段有可能丟失,因而使處在LAST_ACK端的服務端收不到對已發送的FIN報文段的ACK報文段,從而服務端會去不斷重傳FIN報文段。
而客戶端就能在2MSL時間內收到重傳的FIN報文段。接着客戶端重傳一次確認,重新啓動2MSL計時器。直至服務端收到後,客戶端和服務端就都會進入CLOSED狀態,關閉TCP連接。
而如果客戶端不等待2MSL時間,而是在發送完ACK確認後立即釋放資源,關閉連接,那麼就無法收到服務端重傳的FIN報文段,因而也不會再發送一次ACK確認報文段,這樣,服務端就無法正常進入CLOSED狀態,資源就一直無法釋放了。

9.TCP流量控制,擁塞控制,可靠傳輸

其實傳輸層下的網絡層IP協議,是個不靠譜的東西,不負責任,不能保證可靠傳輸,不能保證按序交付,也不能保證數據報的完整性
針對於這個不靠譜的東西:TCP只能自己彌補

超時重傳

而發送端超時有兩種情況:

  1. 發送數據超時
  2. 接收端發送ACK超時。
    這兩種情況都會導致發送端在TimeoutInterval內接收不到ACK確認報文段。
    解決方案:
    1.如果發送端超時,那麼直接重傳
    在這裏插入圖片描述
    2.而如果是接收端發送ACK超時,這種情況接收端實際上已經接收到發送端的數據了。那麼當發送端超時重傳時,接收端會丟棄重傳的數據,同時再次發送ACK
    在這裏插入圖片描述
流量控制

TCP連接的雙方主機都會爲該TCP連接分配緩存和變量。當該TCP連接收到正確、按序的字節後,就將數據放入接收緩存。上層的應用進程會從該緩存中讀取數據,但不必是數據一到達就立即讀取,因爲此時應用程序可能在做其他事務。而如果應用層讀取數據相對緩慢,而發送方發送得太多、太快,發送的數據就會很容易地使該連接的接收緩存溢出。
流量控制服務(flow-control service),是解決發送方發送數據太快而導致收方緩存溢出。
流量控制是一個速度匹配服務,即發送方的發送速率與接收方應用程序的讀取速率相匹配。
作爲全雙工協議,TCP會話的雙方都各自維護一個發送窗口和一個接收窗口(receive window)的變量來提供流量控制。而發送窗口的大小是由對方接收窗口來決定的,接收窗口用於給發送方一個指示–該接收方還有多少可用的緩存空間。
在這裏插入圖片描述
1.發送窗口
發送方的發送緩存內的數據都可以被分爲4類:

  • 已發送,已收到ACK
  • 已發送,未收到ACK
  • 未發送,但允許發送
  • 未發送,但不允許發送

發送窗口只有收到發送窗口內字節的ACK確認,纔會移動發送窗口的左邊界

發送窗口裏包含已發送,未收到ACK未發送,但允許發送
2.接收窗口
接收方的緩存數據分爲3類:

  • 已接收
  • 未接收但準備接收
  • 未接收而且不準備接收

接收窗口包含未接收但準備接收

接收窗口只有在前面所有的報文段都確認的情況下才會移動左邊界。當在前面還有字節未接收但收到後面字節的情況下,會先接收下來,接收窗口不會移動,並不對後續字節發送ACK確認報文,以此確保發送端會對這些數據重傳。

擁塞控制

我們這裏簡單的說一下擁塞控制,首先來一張很屌的圖
在這裏插入圖片描述

  1. 慢開始:首先,在發送數據的時候,並不是一下子就到達了門限值,而是通過一些條件的限制,讓發送的數據報呈現指數級的增長
  2. 一旦這個增長增加到了某一個限制值,那麼就會進入擁塞避免算法加法增大,擁塞避免算法是線性增長的,當然,發送的數據報也會達到另外一個門限值,如果達到另外一個門限值的時候,就證明此時網絡已經到達峯值,將進慢啓動狀態,同時,降低慢啓動的門限值,同時新一輪的閾值變爲原來的一半

這裏推薦一篇寫的很好的文章:
這個是關於TCP的擁塞控制

結束語

如果大家在閱讀過程中發現有誤的地方,還歡迎留言批評指正,同時也希望所有的猿猿們前程似錦

參考鏈接:
計算機網絡中的七層模型
網絡相關協議之HTTP
HTTP/HTTPS詳解,對稱加密已經非對稱加密
網絡相關之TCP
TCP如何保證可靠性
參考資料:
MJ底層原理逆向班:iOS簽過程
《計算機網絡》謝希任 第6版 電子工業出版社
《詳解TCP/IP》電子工業出版社

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