【T06】記住TCP是一種流協議

Andy Niu發表於2017-02-11
1、TCP是一種流協議(stream protocol),這意味著資料是以位元組流的形式發給接收者的,沒有固定的報文和報文邊界的概念。
    接收端讀取tcp資料,無法預知在這一次讀操作中會返回多少個位元組。
2、假設主機A向主機B傳送兩條報文M1和M2,呼叫兩次send傳送兩條獨立的報文,但是資料在傳輸過程中並不會遵循這個方式。
    在傳送端,send操作只是將資料複製到主機A的TCP/IP協議棧,由TCP決定怎麼傳送和每次傳送多少。
    決定過程很複雜,取決於很多因素。如:傳送視窗,擁塞視窗,路徑上的最大傳輸單元等。
    也就是說,主機A真正傳送資料的情況有很多種:
    M1和M2分開傳送,M1和M2合併起來傳送,M1先傳送一部分,剩下的和M2一起傳送,傳送M1和M2的一部分,再傳送M2剩下的一部分。
    注意:傳送視窗由對端控制,防止傳送過多資料,導致接收端的緩衝區溢位。
    擁塞視窗自己控制,tcp要提供可靠的傳輸服務,因此具備超時重傳功能。
    考慮,現在網路比較擁堵,超時沒有收到回覆,認為丟失,重傳。導致越重傳,越擁堵,越擁堵,越重傳的的惡性迴圈。
    tcp傳送策略的一個主要目標是:儘可能高效地利用網路頻寬。因此,對於上述的惡性迴圈,
    更好的策略是:不要再傳送資料了,等到網路緩解的時候在傳送。
    擁塞視窗就是,記錄當前網路能夠容納的流量。當前tcp能夠傳送的資料量是傳送視窗和擁塞視窗的最小值。
    也就是說,傳送視窗允許傳送很多資料,但是網路環境比較差,你也必須少發一些。
3、因此,接收端主機B不能對讀取資料做任何假設,需要讀幾次,每次讀多少,都是不可預測的。
4、對於定長報文來說,接收端讀取到一定長度就認為是一個完整報文,那麼問題來了,對於不定長的報文,每個報文的長度是不確定的,主機B怎麼才能知道讀取了一個完整的報文?
5、解決辦法有兩個:
    辦法一:報文的前面加一個首部,在固定位置標識這個報文的長度,接收端就能知道讀取多少,就是一個完整的報文了。
    辦法二:在報文中增加結束標記來分割報文,這個結束標記是一個特殊欄位。
    那麼問題來,如何表示結束標記本身呢? 
    需要使用轉義字元。

相關文章