天天看點

Netty系列(四)之Netty 編解碼器和粘包拆包Netty 編解碼器和 handler 的調用機制TCP 粘包和拆包 及解決方案

目錄

Netty 編解碼器和 handler 的調用機制

基本說明

編碼解碼器 

解碼器-ByteToMessageDecoder

TCP 粘包和拆包 及解決方案

基本介紹

TCP 粘包和拆包解決方案

Netty 編解碼器和 handler 的調用機制

基本說明

1) netty 的元件設計:Netty 的主要元件有 Channel、EventLoop、ChannelFuture、ChannelHandler、ChannelPipe 等。

2) ChannelHandler 充當了處理入站和出站資料的應用程式邏輯的容器。例如,實作 ChannelInboundHandler 接口(或ChannelInboundHandlerAdapter),你就可以接收入站事件和資料,這些資料會被業務邏輯處理。當要給用戶端發 送 響 應 時 , 也 可 ChannelInboundHandler 沖 刷 數 據 。 業 務 邏 輯 通 常 寫 在 一 個 或 者 多 個ChannelInboundHandler 中。ChannelOutboundHandler 原理一樣,隻不過它是用來處理出站資料的。

3) ChannelPipeline 提供了 ChannelHandler 鍊的容器。以用戶端應用程式為例,如果事件的運動方向是從用戶端到服務端的,那麼我們稱這些事件為出站的,即用戶端發送給服務端的資料會通過 pipeline 中的一系列ChannelOutboundHandler,并被這些 Handler 處理,反之則稱為入站的。

Netty系列(四)之Netty 編解碼器和粘包拆包Netty 編解碼器和 handler 的調用機制TCP 粘包和拆包 及解決方案

編碼解碼器 

1) 當 Netty 發送或者接受一個消息的時候,就将會發生一次資料轉換。入站消息會被解碼:從位元組轉換為另一種格式(比如 java 對象);如果是出站消息,它會被編碼成位元組。

2) Netty 提供一系列實用的編解碼器,他們都實作了 ChannelInboundHadnler 或者 ChannelOutboundHandler 接口。在這些類中,channelRead 方法已經被重寫了。以入站為例,對于每個從入站 Channel 讀取的消息,這個方法會被調用。随後,它将調用由解碼器所提供的 decode()方法進行解碼,并将已經解碼的位元組轉發給 ChannelPipeline中的下一個 ChannelInboundHandler

解碼器-ByteToMessageDecoder

關系繼承圖

Netty系列(四)之Netty 編解碼器和粘包拆包Netty 編解碼器和 handler 的調用機制TCP 粘包和拆包 及解決方案

2) 由于不可能知道遠端節點是否會一次性發送一個完整的資訊,tcp 有可能出現粘包拆包的問題,這個類會對入站資料進行緩沖,直到它準備好被處理. 

3) 一個關于 ByteToMessageDecoder 執行個體分析

Netty系列(四)之Netty 編解碼器和粘包拆包Netty 編解碼器和 handler 的調用機制TCP 粘包和拆包 及解決方案
Netty系列(四)之Netty 編解碼器和粘包拆包Netty 編解碼器和 handler 的調用機制TCP 粘包和拆包 及解決方案

TCP 粘包和拆包 及解決方案

基本介紹

1) TCP 是面向連接配接的,面向流的,提供高可靠性服務。收發兩端(用戶端和伺服器端)都要有一一成對的 socket,是以,發送端為了将多個發給接收端的包,更有效的發給對方,使用了優化方法(Nagle 算法),将多次間隔較小且資料量小的資料,合并成一個大的資料塊,然後進行封包。這樣做雖然提高了效率,但是接收端就難于分辨出完整的資料包了,因為面向流的通信是無消息保護邊界的。

2)粘包和拆包發送了兩個資料包給服務端,服務端兩次讀到到的位元組數是不一樣的。粘包是兩個包粘合在了一起,拆包是讀到了不同的資料。

TCP 粘包和拆包解決方案

1) 使用自定義協定 + 編解碼器 來解決。

2) 關鍵就是要解決 伺服器端每次讀取資料長度的問題, 這個問題解決,就不會出現伺服器多讀或少讀資料的問題,進而避免的 TCP 粘包、拆包 。