1 網絡協議背景概念
4層網絡傳輸是基於udp基於端口
7層網絡協議傳輸是基於tcp基於端口(tcp的復雜度很高很高..),並在tcp之上添加了會話層表示層應用層
upd協議面向報文,tcp協議 面上字節流。
啥是面向字節流呢?
2 TCP傳輸通信過程
tcp面向字節流,udp面向報文。那tcp的字節流是怎樣的呢?
tcp是點到點的通信,建立tcp鏈接的兩個端點,傳輸的數據不是報文,是一段數據中的一部分,並不知道一次讀的數據是多少和發送次數。
數據交給tcp層,由tcp決定一次發送多少數據,判斷條件有很多,發送窗口、擁塞窗口、路徑上的最大傳輸單元(MTU),輸出隊列數據總量等。

如圖在tcp發送數據之前,應用程序和tcp協議之間有一個tcp緩存隊列,這個隊列不固定字節大小,tcp要發送的數據也不固定字節大小,
tcp是去發送數據的一部分字節流,
並在這個傳輸中一直單向的進行。 ???????
所以在網絡傳輸中可以看到的是數據片段,然后是一組一組的數據交付給接收方。
3 傳輸報錯重傳機制
如果發送方發送 1 2 3 4 接收方只收到 1 2 回復確認 ack 3,然后發送方發來了 4,不能回復確認ack 5,因為不能跳躍確認。
於是,采用重傳機制,有2種:
3.1 超時重傳
發送方不知道3 4 5 的接收情況,接收方一直在等 3,這中方式會有比較嚴重的問題。
發送方有兩種選擇:
a , 默認 3 發送失敗,重新發送3
b ,默認 3 4 5 發送失敗,重傳 3 4 5
a的方式,只傳 3可能會慢,b的方式傳 3 4 5 很快但是占用帶寬,timeout也可能很長,這兩個都不是最后的方法。
3.2 快速重傳
tcp還有一種 快速重傳 的算法,Fast-Retransmit,是以數據驅動重傳,不是timeout時間驅動。
怎么是以數據驅動呢?
就是 如果只收到 1 2 ,回復ack 3 ,隨后收到了 4 5 但是還沒收到 3, 4 5的ack也回復 3 3,這樣發送方會收到3個一樣的ack,會知道傳輸出了問題
這就是大部分tcp數據驅動重傳機制(什么?大部分tcp,總共是有幾個版本的..)。
這種方式還不是最好的,只是解決了timeout的問題,回傳的個數還是沒解決,比如一次發了20條,就不知道是哪3個發的ack了,需要回傳這20條。。
3.3 sack 重傳
選擇性重傳,Selective Acknowledgement(sack),tcp的頭會多一個SACK,快速重傳的ACK還在。
sack只回復已經到達的碎片,這樣發送端就能准確知道是重傳那部分字節流。在Linux可以用tcp_sack這個字段開啟這個功能,2.4版之后的Linux默認開啟。
參考:https://tools.ietf.org/html/rfc2018 https://www.jianshu.com/p/69695f332a71
遺留問題
tcp重傳還有一些問題,sack也不能完全相信:
如果有接收端會將數據保存直到失敗的分組重傳,就會有接受方內存擁擠把收到的數據丟棄了,可能有。
