TCP的粘包現象

  看面經時,看到有面試官問TCP的粘包問題。想起來研一作購物車處理數據更新時遇到粘包問題,就總結一下吧。面試

1 什麼是粘包現象

  TCP粘包是指發送方發送的若干包數據到接收方接收時粘成一包,從接收緩衝區看,後一包數據的頭緊接着前一包數據的尾。算法

2 爲何出現粘包現象

  (1)發送方緣由緩存

  咱們知道,TCP默認會使用Nagle算法。而Nagle算法主要作兩件事:1)只有上一個分組獲得確認,纔會發送下一個分組;2)收集多個小分組,在一個確認到來時一塊兒發送。併發

  因此,正是Nagle算法形成了發送方有可能形成粘包現象。測試

  (2)接收方緣由調試

  TCP接收到分組時,並不會馬上送至應用層處理,或者說,應用層並不必定會當即處理;實際上,TCP將收到的分組保存至接收緩存裏,而後應用程序主動從緩存裏讀收到的分組。這樣一來,若是TCP接收分組的速度大於應用程序讀分組的速度,多個包就會被存至緩存,應用程序讀時,就會讀到多個首尾相接粘到一塊兒的包。循環

3 何時須要處理粘包現象

  (1)若是發送方發送的多個分組原本就是同一個數據的不一樣部分,好比一個很大的文件被分紅多個分組發送,這時,固然不須要處理粘包的現象;程序

  (2)但若是多個分組本絕不相干,甚至是並列的關係,咱們就必定要處理粘包問題了。好比,我當時要接收的每一個分組都是一個有固定格式的商品信息,若是不處理粘包問題,每一個讀進來的分組我只會處理最前邊的那個商品,後邊的就會被丟棄。這顯然不是我要的結果。方法

4 如何處理粘包現象

  (1)發送方總結

  對於發送方形成的粘包現象,咱們能夠經過關閉Nagle算法來解決,使用TCP_NODELAY選項來關閉Nagle算法。

  (2)接收方

  遺憾的是TCP並無處理接收方粘包現象的機制,咱們只能在應用層進行處理。

  (3)應用層處理

  應用層的處理簡單易行!而且不只能夠解決接收方形成的粘包問題,還能解決發送方形成的粘包問題。

  解決方法就是循環處理:應用程序在處理從緩存讀來的分組時,讀完一條數據時,就應該循環讀下一條數據,直到全部的數據都被處理;可是如何判斷每條數據的長度呢?

  兩種途徑:

    1)格式化數據:每條數據有固定的格式(開始符、結束符),這種方法簡單易行,但選擇開始符和結束符的時候必定要注意每條數據的內部必定不能出現開始符或結束符;

    2)發送長度:發送每條數據的時候,將數據的長度一併發送,好比能夠選擇每條數據的前4位是數據的長度,應用層處理時能夠根據長度來判斷每條數據的開始和結束。

  當時在作購物車的時候,我最開始的作法是設置開始符(0x7e)和結束符(0xe7),但在測試大量數據的時候,發現了數據異常。正如我所猜想,在調試過程當中發現某些數據內部包含了它們。由於要處理的數據是量很是龐大,爲作到萬無一失,最後我採用了發送長度的方式。再也沒有由於粘包而出過問題。

  I Am So Brilliant !

相關文章
相關標籤/搜索