傳輸層
TCP協議
TCP報文格式
標誌位
URG(URGENT POINTER):指示報文中有緊急數據,應儘快傳送(相當於高優先級的數據)。
PSH (PUSH):爲1表示是帶有push標誌的數據,指示接收方在接收到該報文段以後,應儘快將這個報文段交給應用程序,而不是在緩衝區排隊。
RST (RESET): TCP連接中出現嚴重差錯(如主機崩潰),必須釋放連接,在重新建立連接。
FIN (FINAL):發送端已完成數據傳輸,請求釋放連接。
SYN (SYNCHRONISATION):處於TCP連接建立過程。 (Synchronize Sequence Numbers)
ACK (ACKNOWLEDGEMENT):確認序號標誌,爲1時表示確認號有效,爲0表示報文中不含確認信息,忽略確認號字段。
三次握手
爲什麼需要三次握手?
三次握手主要目的是:信息對等和防止超時。
防止超時導致髒連接。如果使用的是兩次握手建立連接,假設有這樣一種場景,客戶端發送了第一個請求連接並且沒有丟失,只是因爲在網絡結點中滯留的時間太長了,由於TCP的客戶端遲遲沒有收到確認報文,以爲服務器沒有收到,此時重新向服務器發送這條報文,此後客戶端和服務器經過兩次握手完成連接,傳輸數據,然後關閉連接。此時此前滯留的那一次請求連接,網絡通暢了到達了服務器,這個報文本該是失效的,但是,兩次握手的機制將會讓客戶端和服務器再次建立連接,這將導致不必要的錯誤和資源的浪費。如果採用的是三次握手,就算是那一次失效的報文傳送過來了,服務端接受到了那條失效報文並且回覆了確認報文,但是客戶端不會再次發出確認。由於服務器收不到確認,就知道客戶端並沒有請求連接。
第三次握手失敗會發生什麼?
當失敗時,服務器並不會重傳 ack 報文,而是直接發送 RTS(注意區分 RST)報文段,進入 CLOSED 狀態,防止 SYN 洪泛攻擊。
四次揮手
爲什麼建立連接是三次握手,關閉連接確是四次揮手呢?
建立連接的時候, 服務器在LISTEN狀態下,收到建立連接請求的SYN報文後,把ACK和SYN放在一個報文裏發送給客戶端。 而關閉連接時,服務器收到對方的FIN報文時,僅僅表示對方不再發送數據了但是還能接收數據,而自己也未必全部數據都發送給對方了,所以己方可以立即關閉,也可以發送一些數據給對方後,再發送FIN報文給對方來表示同意現在關閉連接,因此,己方ACK和FIN一般都會分開發送,從而導致多了一次。
2MSL意義:
1、保證最後一次握手報文能到B,能進行超時重傳。
2、2MSL後,這次連接的所有報文都會消失,不會影響下一次連接。
流量控制
接收端在接收到數據後,對其進行處理。如果發送端的發送速度太快,導致接收端的結束緩衝區很快的填充滿了。此時如果發送端仍舊發送數據,那麼接下來發送的數據都會丟包, 繼而導致丟包的一系列連鎖反應,超時重傳呀什麼的。而 TCP 根據接收端對數據的處理能力,決定發送端的發送速度,這個機制就是流量控制。
擁塞控制
AIMD(加法增大乘法減小)
乘法減小:無論在慢啓動階段還是在擁塞控制階段,只要網絡出現超時,就是將cwnd 置爲 1,ssthresh 置爲 cwnd 的一半,然後開始執行慢啓動算法(cwnd<ssthresh)。
加法增大:當網絡頻發出現超時情況時,ssthresh 就下降的很快,爲了減少注入到網絡中的分組數,而加法增大是指執行擁塞避免算法後,是擁塞窗口緩慢的增大,以防止網絡過早出現擁塞。
這兩個結合起來就是 AIMD 算法,是使用最廣泛的算法。擁塞避免算法不能夠完全的避免網絡擁塞,通過控制擁塞窗口的大小隻能使網絡不易出現擁塞。
快重傳
快重傳算法要求首先接收方收到一個失序的報文段後就立刻發出重複確認,而不要等待自己發送數據時才進行捎帶確認。接收方成功的接受了發送方發送來的 M1,M2 並且分 別給發送了 ACK,現在接收方沒有收到 M3,而接收到了 M4,顯然接收方不能確認 M4,因爲 M4 是失序的報文段。如果根據可靠性傳輸原理接收方什麼都不做,但是按照快速重傳算法,在收到 M4、M5 等報文段的時候,不斷重複的向發送方發送 M2 的 ACK,如果接收方一連收到三個重複的 ACK,那麼發送方不必等待重傳計時器到期,由發送方儘早重傳未被確認的報文段。
TCP粘包問題
UDP 是基於報文發送的,從 UDP 的幀結構可以看出,在 UDP 首部採用了 16bit 來指示 UDP 數據報文的長度,因此在應用層能
很好的將不同的數據報文區分開,從而避免粘包和拆包的問題。而 TCP 是基於字節流的,雖然應用層和 TCP 傳輸層之間的數據交互是大小不等的數據塊,但是 TCP 把這些數據塊僅僅看成一連串無結構的字節流,沒有邊界;另外從 TCP 的幀結構也可以看出,在 TCP 的首部沒有表示數據長度的字段,基於上面兩點,在使用 TCP 傳輸數據時,纔有粘包或者拆包現象發生的可能。
發生 TCP 粘包或拆包有很多原因,現列出常見的幾點:
1:要發送的數據大於 TCP 發送緩衝區剩餘空間大小,將會發生拆包。
2:待發送數據大於 MSS(最大報文長度),TCP 在傳輸前將進行拆包。
3:要發送的數據小於 TCP 發送緩衝區的大小,TCP 將多次寫入緩衝區的數據一次發送出去,將會發生粘包。
4:接收數據端的應用層沒有及時讀取接收緩衝區中的數據,將發生粘包。