本文主要講的是傳輸層的兩大重要協議TCP和UDP,雖然在Android開發中,並不須要瞭解到這麼底層,但有理論的支撐,寫代碼老是很自信的啦。理論指導着實踐,實踐是理論檢驗的惟一標準。站在巨人的肩膀窺伺網絡世界。git
用戶數據報協議UDP只在IP的數據報服務至上增長了複用和分用的功能以及差錯檢測的功能。只有面向無鏈接的報文,不可靠傳輸的特色。UDP對應用層交下來的數據只添加首部,並進行特別的處理,就交給網絡層;對網絡層傳遞上來的用戶數據報拆封首部後,原封不動的交給應用層。github
用戶數據報UDP分爲兩個字段:數據字段和首部字段,從圖來分析用戶數據報UDP的首部格式。 算法
在傳輸的過程當中,若是接收方UDP發現收到的報文中的目的端口不存在,會直接丟棄,而後由網際控制報文協議ICMP給發送方發送「端口不可達」差錯報文。緩存
計算校驗和時,須要在UDP以前增長12個字節的僞首部。這種首部並非用戶數據報的真正首部。僞首部並不在網絡中傳輸,只是在計算檢驗和,臨時添加在UDP用戶數據報前,獲得一個臨時的用戶數據報。網絡
UDP的校驗和是把首部和數據部分一塊兒校驗,發送方計算校驗和的通常步驟:性能
接收方收到用戶數據報後,連同僞首部一塊兒,按二進制反碼求這些16位字的和,無差錯結果是應全爲1.不然出錯,直接丟棄該報文。線程
TCP協議做爲傳輸層主要協議之一,具備面向鏈接,端到端,可靠的全雙工通訊,面向字節流的數據傳輸協議。3d
雖然TCP面向字節流,但TCP傳輸的數據單元倒是報文段。TCP報文段分爲TCP首部和數據部分,TCP報文段首部的前20個字節是固定的,後面有4*n字節根據須要動態添加的選項,最大長度爲40字節。 指針
三次握手圖例以下,與文字解釋配合使用效果更佳。code
第二次:服務端接收到報文後,發回確認報文,其中ACK=1,ack=x+1,由於須要客戶端確認,因此報文中也有SYN=1,seq=y的信息。發送完後進入SYN_RCVD狀態。
第三次:客戶端接收到報文後,發送確認報文,其中ACK=1,ack=y+1。發送完客戶端進入ESTABLISHED
狀態,服務端接收到報文後,進入ESTABLISHED
狀態。到此,鏈接創建完成。
三次握手緣由
避免資源被浪費掉。若是在第二步握手時,因爲網絡延遲致使確認包不能及時到達客戶端,那麼客戶端會認爲第一次握手失敗,再次發送鏈接請求,服務端收到後再次發送確認包。在這種狀況下,服務端已經建立了兩次鏈接,等待兩個客戶端發送數據,而實際卻只有一個客戶端發送數據。
四次揮手指客戶端和服務端各發送一次請求終止鏈接的報文,同時雙方響應彼此的請求。 四次揮手圖例以下,請配置文字解釋使用哦。
FIN_WAIT_1
狀態。
第二次揮手:服務端收到請求包後,發回ACK=1,ack=x+1的確認包,表示確認斷開鏈接。服務端進入CLOSE_WAIT
狀態。客戶端收到該包後,進入FIN_WAIT_2
狀態。此時客戶端到服務端的數據鏈接已斷開。
第三次揮手:服務端發送FIN=1,seq=y的包給客戶端,表示本身沒有數據要給客戶端了。發送完後進入LAST_ACK
狀態,等待客戶端的確認包。
第四次揮手:客戶端收到請求包後,發送ACK=1,ack=y+1的確認包給服務端,並進入TIME_WAIT
狀態,有可能要重傳確認包。服務端收到確認包後,進入CLOSED
狀態,服務端到客戶端的鏈接已斷開。客戶端等到一段時間後也會進入CLOSED
狀態。
四次揮手緣由 因爲TCP的鏈接是全雙工,雙方均可以主動傳輸數據,一方的斷開須要告知對方,讓對方能夠相關操做,負責任的表現。
使用TCP協議有:FTP(文件傳輸協議)、Telnet(遠程登陸協議)、SMTP(簡單郵件傳輸協議)、POP3(和SMTP相對,用於接收郵件)、HTTP協議等
TCP滑動窗口協議主要爲了解決在網絡傳輸數據的過程當中,發送方和接收方傳輸數據速率不一致的問題,從而保證數據傳輸的可靠性,達到流量控制的效果。 發送方中的數據分爲三種:
接收方數據分爲三種:
在發送方的滑動窗口中,可分爲發送窗口和可用窗口。發送窗口中的數據已發送接收方,但未接到接收方的確認;可用窗口則表示發送方還能夠發送多少數據。發送方的窗口大小會受到接收方窗口的改變而改變。
接收方數據被上層讀取後,又能夠接收序號爲501-600共100個字節,因此通知A,接收窗口大小爲100,序號爲501開頭....在上圖的整個過程當中,A共收到B三次流量控制。
應用層把數據傳遞給傳輸層的TCP的發送緩存後,TCP經過不一樣的機制來控制報文段的發送時機。 主要有下面三種機制:
不一樣的發送機制都會帶來必定的效率問題,例如用戶發送一個字符,加上20字節首部,獲得21字節長的TCP報文段,再加上21字節的IP首部,就變成41字節長的IP數據報。發送一個字節,線路上就須要發送41字節長的IP數據報,若等待接收方確認,線程就又多了40字節長的數據報。因此在線程帶寬不富裕時,這種傳輸效率很是不高。所以應當推遲發回確認報文,並儘可能使用捎帶確認的方法。
Negle算法主要爲了解決TCP的傳輸效率問題。Negle算法規定:若要把發送的數據逐個字節緩存起來,則發送方須要把第一個字節發送出去,而後緩存後面的字節,在收到接收方第一個字節的確認,再將現有緩存中全部字節組成一個報文段發送出去,繼續緩存後續數據。只有在收到前一個報文的確認以後發送後面的數據。這是爲了減小所用帶寬。當發送數據到達TCP發送窗口的一半或已達到報文段的最大長度也會當即發送報文段,而不是等待接收方確認。這是爲了提升網絡吞吐量。
TCP接收方的緩存已滿,若上層一次從緩存中讀取一個字節,這樣接收方就能夠繼續接納一個字節的窗口,而後向發送方發送確認,把窗口設爲1個字節(上文所講,IP數據報爲41字節長)。若是這樣持續下去,那麼網絡效率很是低。
因此有效的解決方法,就是讓接收方等待必定時間,讓緩存空間可以接納一個最長的報文段,或者等待接收緩存已有一半的空閒空間,再發出確認報文和通知當前窗口大小。
什麼是擁塞呢,在某段時間,若對網絡中某一資源的需求超過了該資源所能提供的可用部分,網絡性能就會變壞了,這種狀況就叫擁塞。網絡資源常指網絡鏈路容量(帶寬)、交換結點中的緩存和交換處理機。
當出現擁塞,條件容許通常都是經過添加網絡資源,例如帶寬換成更大的,但這治標不治本,並且不必定老是有用。網絡擁塞每每是有許多因素引發的,所以就須要擁塞控制了。
擁塞控制指防止過多的的數據注入到網絡中,這樣可使網絡中的路由器或鏈路不過載。擁塞機制是一個全局性的過程,涉及到全部主機、全部路由器,以及與下降網絡傳輸性能有光的全部因素。
而滑動窗口協議的流量控制,是指點到點的通訊量控制,是端到端的問題。
TCP進行擁塞控制的算法有四種:慢開始、擁塞避免、快重傳、快恢復。
擁塞控制是基於擁塞窗口的,發送方維持一個擁塞窗口 cwnd的狀態變量。窗口大小取決網絡的擁塞程度,而且動態變化,發送方會讓本身的發送窗口等於擁塞窗口。判斷網絡擁塞的依據就是發送方接收接收方的確認報文是否超時。
慢開始指主機由小到大逐漸增大發送窗口,即增大擁塞窗口的數值。初始擁塞窗口cwnd設置爲不超過2到4個最大報文段SMSS的數值,具體規定:
從上面的規定限制了初始擁塞窗口的大小。
慢開始在每收到一個對新的報文段的確認後,cwnd就能夠增長最多一個SMSS的數值。
擁塞避免算法就是讓cwnd緩慢增大,每個輪次把擁cwnd增長1,而不是像慢開始算法那樣翻倍增長。須要注意的是,擁塞避免算法只是讓網絡不那麼快出現擁塞,而不是避免擁塞出現。
上文已經說到,判斷網絡是否擁塞以報文是否超時爲準,當網絡出現擁塞時,會把ssthresh設爲原有的一半,而後開始慢開始算法。以下圖所示:
快重傳算法是讓發送方今早知道發生了個別報文段的丟失。快重傳算法要求接收方不要等待本身發送數據時才進行捎帶確認,而是當即發送確認。也就是說,但出現丟包狀況,接收方在接收新數據時會重複發送對丟失包的前一個報文段的確認號。發送方接收到三次確認號後,就判斷該丟失報文段確實丟失,會當即進行重傳(快重傳)。
在上文,知道只是報文段丟失,而不是網絡出現擁塞後,發送方會調整ssthresh爲原來的一半,而後繼續進行擁塞避免算法,這個過程就叫快開恢復算法。
可見,TCP擁塞控制四個算法是相輔相成,少了誰都不行,共同維護這擁塞控制機制。下面是整體的流程圖。
點個贊收藏吧