Android技能樹 — 網路小結(2)之TCP/UDP

青蛙要fly發表於2018-08-03

介於自己的網路方面知識爛的一塌糊塗,所以準備寫相關網路的文章,但是考慮全部寫在一篇太長了,所以分開寫,希望大家能仔細看,最好可以指出我的錯誤,讓我也能糾正。

Android技能樹 — 網路小結(2)之TCP/UDP

1.講解相關的整個網路體系結構:

Android技能樹 — 網路小結(1)之網路體系結構

2.講解相關網路的重要知識點,比如很多人都聽過相關網路方面的名詞,但是僅限於聽過而已,什麼tcp ,udp ,socket ,websocket, http ,https ,然後webservice是啥,跟websocket很像,socket和websocket啥關係長的也很像,session,token,cookie又是啥。

Android技能樹 — 網路小結(2)之TCP/UDP

Android技能樹 — 網路小結(3)之HTTP/HTTPS

Android技能樹 — 網路小結(4)之socket/websocket/webservice

相關網路知識點小結- cookie/session/token(待寫)

3.相關的第三方框架的原始碼解析,畢竟現在面試個大點的公司,okhttp和retrofit原始碼是必問的。

Android技能樹 — 網路小結(6)之 OkHttp超超超超超超超詳細解析

Android技能樹 — 網路小結(7)之 Retrofit原始碼詳細解析


正文

網路體系結構小結中我們知道了大概的網路結構層級,這篇文章側重的講一些平時大家聽到的熟悉的詞彙TCP 與 UDP

1. TCP與UDP:

網路體系結構小結中我們提過TCP/IP的四層網路層級:

Android技能樹 — 網路小結(2)之TCP/UDP

而TCP (Transmission Control Protocol,即 傳輸控制協議)和 UPD (User Datagram Protocol,即使用者資料包協議)是在傳輸層的,所以我們知道UDP和TCP是用來傳輸資料的一種協議,為主機中不同的程式提供通訊,那既然是傳輸資料,我們舉例以快遞寄信的邏輯來說明(反正都是某個東西從一個地方到另外一個地方)。

TCP像快遞,因為我們現在寄快遞都能看到具體快遞到哪裡了,某個中轉站是否已經收到了我的快遞,最後的目的地是否收到了我的快遞,如果快遞丟了也會給你反饋等,幫你重新補寄等。而UDP更像寄信,我反正寄出去了,收不收得到我也不管。(emmm....可能這個例子不太恰當。。。)

所以我們初步感覺:對比於UDP,TCP的傳輸是可靠的、無差錯的。

1.1 TCP通道的連線及斷開

既然是資料從一個地方到另外一個地方,我們要先建立一個通道,這樣後面資料才能傳輸流動。(PS:這個比喻可能不恰當。如果有更好的比喻,可以留言。謝謝)

TCP三次握手,四次揮手聽到的是不是很多,沒錯,這個就是用來建立這個通道及斷開通道,我面試的別人的時候,三次建立,四次斷開基本都知道,但是我問他們為什麼要三次,很多都答不上來。為了更好的記憶,我們還是用具體的例子來說明:

三次握手:

1. A發資訊給B:你在不在啊?急事!!
2. B發資訊給A:我在啊,急事?那你快告訴我,我這邊時刻聽著你說。
複製程式碼

不幸的是A這時候拉肚子,只能馬上跑去廁所了,然後一拉就是半個小時,然後B就一直等了半個小時。

這時候你是不是發現了二次握手的問題了,如果第二次B傳送給A的話後,A沒有馬上回相應的資訊給B,B就可以認為A已經不在了,從而不再等它,也不建立通道。

所以應該是這樣:

1. A發資訊給B:你在不在啊?急事!!
2. B發資訊給A:我在啊,急事?那你快告訴我,我這邊時刻聽著你說。
3. A發資訊給B:事情是這樣的。你聽我慢慢道來。
balabala.......
balabala.......
balabala.......
複製程式碼

然後A和B之間的通道就通了,然後A這時候可以給B不停的發資訊了。

然後有人會問,TCP 又不會拉肚子,那TCP為啥要三次,因為如果規定二次的話: A 發給B資訊,申請建立通道,因為網路延遲,B一直沒收到,這時候A等的不耐煩了,直接就退出了,但是過了一會兒B收到了這個資訊,B以為A是剛發的請求,所以建立了通道,但是A其實早就已經不在了。這樣防止B形成死鎖、浪費資源等。

Android技能樹 — 網路小結(2)之TCP/UDP

當然上面是我們舉得例子,具體肯定是通過一些值來傳遞:具體的圖是這樣的:

Android技能樹 — 網路小結(2)之TCP/UDP
Android技能樹 — 網路小結(2)之TCP/UDP

四次揮手:

我們知道TCP連線之後我們可以相互之間發訊息了,這裡我們假設這個通道里面其實包含了二個小通道,一個通道是用來A發給B的,一個通道用來是B發給A的,這樣當我們要斷開連線的時候有二大步:

  1. 斷開A發給B資訊的通道
  2. 斷開B發給A資訊的通道

我們先看斷開A發給B資訊的通道:

A發資訊給B:我累了,我先睡了,88.

B發資訊給A:好的,那你先睡吧。
複製程式碼

這時候A就睡覺了,A也不會發資訊給B了。但是這時候B還是可以繼續給A發資訊,B可能深夜突然來個深情告白

B發資訊給A: 其實我XXXXXXXX。
複製程式碼

所以我們單純二次揮手是不夠的,還要斷開B發給A資訊的通道

B發資訊給A:不過你說你要睡了,我覺得是比較晚了,我也要睡了,晚安。

A發資訊給B: 那你也早點睡。晚安
複製程式碼

所以連在一起是:

A發資訊給B:我累了,我先睡了,88.

B發資訊給A:好的,那你先睡吧

B發資訊給A:不過你說你要睡了,我覺得是比較晚了,我也要睡了,晚安。

A發資訊給B: 那你也早點睡。晚安
複製程式碼

Android技能樹 — 網路小結(2)之TCP/UDP

那實際的四次揮手肯定也是傳值通知,具體的圖是這樣的:

剛開始是雙向通訊,然後二次揮手後,A到B的斷了,所以這時候變成單向的資料傳輸,然後再二次揮手,把這個單向資料傳輸也關閉。

Android技能樹 — 網路小結(2)之TCP/UDP

Android技能樹 — 網路小結(2)之TCP/UDP

所以我們看到了TCP的連線和斷開都這麼多步,多次確認等操作,但是UDP是不需要先建立一個穩定的通道,直接就把資料發過去了。所以UDP更快,因為不用先去建立連線。

1.2 TCP的無差錯傳輸

我們平時肯定聽到過TCP傳輸安全,UDP傳輸不安全等說法,TCP傳輸保證了資料最終能穩定安全的到達目的地,而UDP只管傳送過去,不負責最終是否收到,具體原因是為啥呢???

我還是以下載工具 《迅雷》來進行說明(可能迅雷的功能實現更復雜,我就單純用來說明TCP例子了,如果例子寫的不對,歡迎大家指出):

問題1: 迅雷下載用的是TCP還是UDP?

下載東西我們肯定經歷過下載的內容下載到百分之99,可能這個檔案都是沒用的,說明傳輸中我們對下載的檔案要求百分百都收到。這樣肯定是使用TCP來控制,因為UDP傳送後不管你有沒有收到。

問題2:用它下載東西的時候,突然中間一段時間網路很差,那時候伺服器的傳送的包都收不到了,但是最終還是下載了一個完整的包(有點類似迅雷的繼續下載的感覺)

其實這個問題我說的更詳細點:比如一個檔案被分割成100份,我再收到第3份的時候如果因為網路不好沒收到,它怎麼校驗我沒收到第三份,而不是頭腦發熱直接發第四份第五份給我。應該是發現我第三份沒收到,繼續發一份第三份給我。同時如果控制它不是一股腦兒全部100份發出,而是傳送一些,接收方收到一些,然後再傳送一些。

就像上面說的有100份,但是接收端到第三份的時候就沒收到,這時候傳送端不應該繼續傳送第四份,第五份,說明接收端有給傳送端反饋,就像:

A通過QQ要發給B 100個檔案,但是這些檔案是要有順序的來接受。
這時候A傳送一個檔案,B接受一個檔案,然後的介面就會有相應提示:
複製程式碼

Android技能樹 — 網路小結(2)之TCP/UDP

這時候A就知道了B已經收到了2個檔案了,開始發第三個。
如果過了一段時間都沒有收到這個B成功收到檔案的提示,
則B就繼續傳送一個3.txt檔案。


而對於A來說,如果QQ沒收看到3.txt接受的提示,
而是直接收到了4.txt接受的請求,你肯定就是直接忽略,
而不是去下載4.txt檔案,還是重新等待3.txt檔案,
反正只要B沒收到A成功下載3.txt檔案的提示超時後就會重新傳送3.txt。
複製程式碼

傳送端:

對於傳送端: 每收到一個確認幀,傳送視窗就向前滑動一個幀的距離 當傳送視窗內無可傳送的幀時(即視窗內的幀全部是已傳送但未收到確認的幀),傳送方就會停止傳送,直到收到接收方傳送的確認幀使視窗移動,視窗內有可以傳送的幀,之後才開始繼續傳送 具體如下圖:

Android技能樹 — 網路小結(2)之TCP/UDP

接收端:

對於接收端:當收到資料幀後,將視窗向前移動一個位置,併發回確認幀,若收到的資料幀落在接收視窗之外,則一律丟棄。

Android技能樹 — 網路小結(2)之TCP/UDP

滑動視窗 協議的重要特性:

  • 只有接收視窗向前滑動、接收方傳送了確認幀時,傳送視窗才有可能(只有傳送方收到確認幀才是一定)向前滑動
  • 停止-等待協議、後退N幀協議 & 選擇重傳協議只是在傳送視窗大小和接收視窗大小上有所差別:

1.停止等待協議:傳送視窗大小=1,接收視窗大小=1;即 單幀滑動視窗 等於 停止-等待協議
2.後退N幀協議:傳送視窗大小>1,接收視窗大小=1。
3.選擇重傳協議:傳送視窗大小>1,接收視窗大小>1。

  • 當接收視窗的大小為1時,可保證幀有序接收。
  • 資料鏈路層的滑動視窗協議中,視窗的大小在傳輸過程中是固定的(注意要與TCP的滑動視窗協議區別)

1.3 TCP 與 UDP 區別

角度 TCP UCP
是否連線 面向連線(傳送資料前需要建立連線) 無連線(傳送資料無需連線)
是否丟包重試 實現了資料傳輸時各種控制功能,可以進行丟包的重發控制,還可以對次序亂掉的分包進行順序控制 不會進行丟包重試,也不會糾正到達的順序
模式 流模式(面向位元組流) 資料包模式(面向報文)
對應關係 一對一 支援一對一,一對多,多對一和多對多的互動通訊
頭部開銷 最小20位元組 只有8位元組
可靠性 全雙工非常可靠、無差錯、不丟失、不重複、且按序到達 不保證可靠交付,不保證順序到達
擁塞控制 有控制 有擁塞控制,因此網路出現擁塞不會使源主機的傳送速率降低(對實時應用很有用,如IP電話,實時視訊會議等)
資源要求 TCP程式結構較複雜,較多 UDP程式結構簡單,少

結語:

其實關於TCP有很多很多可以講,比如報文段格式,擁塞控制等,而我本文更多的是講了大家平時聽到的更多的知識點,結合通俗易懂的說明方式講了下。當然我本身網路很差,所以有些地方如果講錯了歡迎大家指出。

關於具體的很細的細節,推薦看:計算機網路:這是一份全面 & 詳細 的TCP協議攻略,部分圖片都是該文引入。

參考文章:

計算機網路:這是一份全面 & 詳細 的TCP協議攻略

相關文章