熟悉TCP編程的讀者可能都知道,不管是服務端仍是客戶端,當咱們讀取或者發送消息的時候,都須要考慮TCP底層的粘包/拆包機制。下面具體介紹下TCP粘包/拆包問題以及解決之道。編程
TCP是個「流」協議,所謂流,就是沒有界限的一串數據。你們能夠想一想河裏的流水,它們是連成一片的,其間並無分界線。網絡
問題:socket
TCP粘包:socket讀取時,讀到了實際意義上的兩個或多個數據包的內容,同時將其做爲一個數據包進行處理。spa
TCP拆包:socket讀取時,沒有完整地讀取一個數據包,只讀取一部分。netty
解決方式:開發
粘包/拆包問題通常的處理方式有四種:變量
一、數據段定長處理,位數不足的空位補齊。請求
二、消息頭+消息體,消息頭中通常會包含消息體的長度,消息類型等信息,消息體爲實際數據體。im
三、特殊字符(如:回車符)做爲消息數據的結尾,以實現消息數據的分段。數據
四、複雜的應用層協議,這種方式使用的相對較少,耦合了網絡層與應用層。
上面的四種方式目的都是爲了將數據在流中精確分開以便進一步解析處理,在自定義的協議中,第二種方式用的比較多,由於它更能知足定製化協議開發需求,好比自定義Netty協議時能夠將具體數據報文放入消息體,消息頭中根據須要放入其餘變量(如:消息類型,此處能夠具體對應到維護netty長連接的心跳消息、客戶端請求消息、服務端處理結果消息等)。