1. 程式人生 > 其它 >Netty中的粘包與半包問題

Netty中的粘包與半包問題

目錄

問題引入,在Netty網路通訊中常常遇見在接收端接受訊息的時候會出現三中型別的輸出:

  • 讀到一個完整的客戶端輸入的ByteBuf
  • 讀到多個客戶端發過來的ByteBuf
  • 讀到一個客戶端不完整的ByteBuf

1.1 問題

出現以上三個問題的原因是我們沒有在應用層對傳輸層的TCP包進行包的拆分與分發。
讓我們回顧一下Netty中一個網路通訊的完整過程:

  • 客戶端的處於應用層的資料首先要傳送到他自己的核心緩衝區中。
  • 但是到了作業系統的核心緩衝區之後,底層會按照協議對資料包進行二次封裝,封裝成傳輸層的TCP報文。
  • 之後經過傳輸層的一系列傳輸之後資料包首先發送到伺服器的核心緩衝區,Netty應用程式要讀取資料的時候才會將核心緩衝區的資料複製到使用者態的使用者緩衝區。

那麼根據以上過程便產生了粘包和半包的問題:
1.每次讀取底層資料緩衝區的容量是有限的,當TCP核心緩衝區中的資料比較大的時候,可能會將一個數據包分成好幾塊進行復制。從而導致使用者程序緩衝區讀到的是不完整的資料。這就導致了半包問題
2.當核心緩衝區中的資料是比較小的時候,一次複製的可能不止一個TCP的資料量。這就導致了粘包問題。

2.1 解決方案

總體來說在接受的時候Netty程式根據自定義協議將讀取到程序緩衝區的資料在應用層進行二次拆分,重新組裝成應用層的資料包,這個過程一般叫做分包或者拆包。

Netty中一般有兩種解決方案:

  • 可以自定義解碼器分包器,基於ByteToMessageDecode,定義自己的使用者緩衝區分包器。
  • 使用Netty內建的解碼器對使用者緩衝區ByteBuf進行正確的分包。

以上就是Netty網路通訊中的粘包和半包問題以及相應的解決方案。