本系列文章對整個Android網絡編程進行了總結,包括基本的TCP/IP協議,HTTP協議,HTTPS協議,HttpClient,UrlConnection,一些網絡通訊的庫到棉花糖新加入的OKHTTP。算法
本文主要對TCP協議的鏈接管理和擁塞控制兩部分知識進行總結。編程
TCP協議是傳輸層的重要協議,負責端到端的通訊。爲了實現面向鏈接的可靠傳輸,TCP協議使用「三次握手」和「四次揮手」的方式來建立鏈接,結束鏈接。緩存
三次握手:服務器
這裏須要提一下的是確認號數值ACK=指望對方下次發來的字節序號。網絡
當須要斷開鏈接時候,採用「四次揮手」的方式:socket
關於鏈接創建和釋放過程當中,有兩個狀態須要說明一下:spa
擁塞控制就是防止過多數據注入到網絡中,這樣可使網絡中的路由器和鏈路不至於過載。它是一個全局性的過程,涉及到鏈路上全部的主機和路由器。而流量控制是點對點通訊量的控制,是爲了防止發送端數據發送過快接收端來不及接收。TCP協議採用慢開始、擁塞避免、快重傳以及快恢復的算法進行擁塞控制。發送端維持了一個稱爲「擁塞窗口」的狀態變量cwnd,它隨着網絡擁塞程度動態變化,這裏咱們先不去考慮流量控制以及接收方的接收能力,而是讓發送方的發送窗口等於擁塞窗口。server
當主機開始發送數據的時候並不知道網絡負荷情況,因此由小到大逐漸增大發送窗口,即由小到大增大擁塞窗口cwnd。初始設置cwnd=1MSS,發送一個報文給接收方。接收方收到該報文後,會返回確認。發送方每次收到一個對新報文段的確認,就將cwnd增長1.所以,慢開始算法每通過一個傳輸輪次RTT,擁塞窗口加倍:1,2,4…因此說「慢開始」不是說cwnd增加速度慢,而是說在開始發送的時候cwnd=1進行網絡試探。blog
爲了防止cwnd過速增加,須要設置一個慢開始閾值ssthresh狀態變量:隊列
這裏擁塞避免算法與慢開始算法不一樣,每通過一個傳輸輪次RTT發送方的擁塞窗口cwnd增長1,而不是加倍,同時ssthresh的值也加1.不管是在慢開始算法仍是在擁塞避免算法階段,一旦發生擁塞(是否按時收到確認報文),則把ssthresh值設置爲擁塞時cwnd值的1/2,而後cwnd設置爲1,從新開始慢開始算法。(這是不使用快重傳的思路)
在傳輸過程當中,若是發送方在計時器時限已到仍未收到確認,則可能出現了擁塞。對於這種可能出現的擁塞,上面所述狀況未使用快重傳算法。而對於快重傳算法,首先要求接收方在每收到一個失序報文,都會發出重複確認,而不是等本身發數據時候才捎帶發送ack。當接收方連續收到3個重複確認,應當當即重傳該報文而沒必要等待計時器時間到。
快重傳算法須要和快恢復算法配合使用。在連續收到3個確認報文並重發該報文的同時,爲了預防擁塞發生,把慢開始閾值ssthresh減半。此時並不去執行慢開始算法(cwnd=1),而是把cwnd設置爲ssthresh減半後的數值,而後執行擁塞避免算法。在採用快恢復的算法時候,慢開始算法只是在TCP鏈接創建時和網絡出現超時時才使用。
咱們在談論上面四種算法的時候,假設接收方擁有足夠大的緩存來接收數據。可是實際上接收方緩存有限,因此須要設定一個接收窗口rwnd,在每次向發送方返回確認的時候傳送給發送方。這個接收窗口又稱爲通知窗口,從流量控制的角度發送方的發送窗口不能超過接收方的rwnd值。
綜合擁塞控制和流量控制兩方面考慮,發送窗口值=min{rwnd,cwnd}。
下一篇文章中將對http協議和HTTPS協議進行總結。