天天看點

TCP拆包粘包之分隔符解碼器

TCP以流的方式進行資料傳輸,上層的應用協定為了對消息進行區分,往往采用如下4種方式。

(1)消息長度固定,累計讀取到長度總和為定長LEN的封包後,就認為讀取到了一個完整的消息;将計數器置位,重新開始讀取下一個資料報;

(2)将回車換行符作為消息結束符,例如FTP協定,這種方式在文本協定中應用比較廣泛;

(3)将特殊的分隔符作為消息的結束标志,回車換行符就是一種特殊的結束分隔符;

(4)通過在消息頭中定義長度字段來辨別消息的總長度。

Netty對上面四種應用做了統一的抽象,提供了4種解碼器來解決對應的問題,使用起來非常友善。有了這些解碼器,使用者不需要自己對讀取的封包進行人工解碼,也不需要考慮TCP的粘包和拆包。

兩種實用的解碼器——DelimiterBasedFrameDecoder和FixedLengthFrameDecoder,前者可以自動完成以分隔符做結束标志的消息的解碼,後者可以自動完成對定長消息的解碼,它們都能解決TCP粘包/拆包導緻的讀半包問題。

示範程式以經典的Echo服務為例。EchoServer接收到EchoClient的請求消息後,将其列印出來,然後将原始消息傳回給用戶端,消息以“$_”作為分隔符。

服務端示例:

用戶端示例:

運作結果:

服務端

This is 1 times receive client : [Hi, Netty. Welcome to Netty.]

...............................

This is 10 times receive client : [Hi, Netty. Welcome to Netty.]

用戶端

FixedLengthFrameDecoder是固定長度解碼器,它能夠按照指定的長度對消息進行自動解碼,開發者不需要考慮TCP的粘包/拆包問題,非常實用。

利用FixedLengthFrameDecoder解碼器,無論一次接收到多少資料報,它都會按照構造函數中設定的固定長度進行解碼,如果是半包消息,FixedLengthFrameDecoder會緩存半包消息并等待下個包到達後進行拼包,直到讀取到一個完整的包。

在服務端的ChannelPipeline中新增FixedLengthFrameDecoder,長度設定為20,然後再依次增加字元串解碼器和EchoServerHandler

用戶端示例:

telnet localhost 8080

通過set localecho指令打開本地回顯功能

上一篇: HTML DOM 簡介
下一篇: HTML DOM 節點