摘要:以流的方式進(jìn)行數(shù)據(jù)傳輸上層的應(yīng)用協(xié)議為了對(duì)消息進(jìn)行區(qū)分往往采用如下中方式消息長度固定累計(jì)讀取到長度總和為定長的報(bào)文后就認(rèn)為讀到了一個(gè)完整的消息將計(jì)數(shù)器置位重新開始讀取下一個(gè)數(shù)據(jù)報(bào)將回車換行符作為消息結(jié)束符例如協(xié)議這種方式在文本協(xié)議中應(yīng)用比較
TCP 以流的方式進(jìn)行數(shù)據(jù)傳輸, 上層的應(yīng)用協(xié)議為了對(duì)消息進(jìn)行區(qū)分, 往往采用如下 4 中方式.
消息長度固定, 累計(jì)讀取到長度總和為定長 LEN 的報(bào)文后, 就認(rèn)為讀到了一個(gè)完整的消息; 將計(jì)數(shù)器置位, 重新開始讀取下一個(gè)數(shù)據(jù)報(bào);
將回車換行符作為消息結(jié)束符, 例如 FTP 協(xié)議, 這種方式在文本協(xié)議中應(yīng)用比較廣泛.
將特殊的分隔符最為消息的結(jié)束標(biāo)志, 回車換行符就是一種特殊的結(jié)束分隔符;
通過在消息頭中定義長度字段來標(biāo)識(shí)消息的總長度.
Netty 對(duì)上面 4 種應(yīng)用做了統(tǒng)一的抽象, 提供了 4 種解碼器來解決對(duì)應(yīng)用的問題.
之前我寫了 LineBasedFrameDecoder 解碼器的使用, 今天開始學(xué)習(xí)如何使用 DelimiterBasedFrameDecoder 和 FixedLengthFrameDecoder.
DelimiterBasedFrameDecoder 應(yīng)用開發(fā)通過對(duì) DelimiterBasedFrameDecoder 的使用, 我們可以自動(dòng)完成以分隔符作為碼流結(jié)束標(biāo)識(shí)的消息的解碼.
還是修改 initChannel 方法
ByteBuf delimiter = Unpooled.copiedBuffer("$_".getBytes()); ch.pipeline().addLast(new DelimiterBasedFrameDecoder(1024, delimiter)); ch.pipeline().addLast(new StringDecoder()); ch.pipeline().addLast(new TimeServerHandler());
我們使用 $_ 作為分隔符, 創(chuàng)建 DelimiterBasedFrameDecoder 對(duì)象, 將其加入到 ChannelPipeline 中. DelimiterBasedFrameDecoder 有多個(gè)構(gòu)造方法, 這里我們傳遞兩個(gè)參數(shù): 第一個(gè) 1024 表示單條消息的最大長度, 當(dāng)達(dá)到該長度后仍然沒有檢查到分隔符, 將拋出 TooLongFrameException 異常, 防止由于異常碼流缺失分隔符導(dǎo)致的內(nèi)存溢出, 這是 Netty 解碼器的可靠性保護(hù); 第二個(gè)參數(shù)就是分隔符緩沖對(duì)象.
由于我們?cè)O(shè)置 DelimiterBasedFrameDecoder 過濾掉了分隔符, 所以返回給客戶端時(shí)需要在請(qǐng)求消息尾部拼接分隔符 $_.FixedLengthFrameDecoder 應(yīng)用開發(fā)
FixedLengthFrameDecoder 是固定長度解碼器, 它能夠按照指定的長度對(duì)消息進(jìn)行自動(dòng)解碼.
ch.pipeline().addLast(new FixedLengthFrameDecoder(10)); ch.pipeline().addLast(new StringDecoder()); ch.pipeline().addLast(new TimeServerHandler());
利用 FixedLengthFrameDecoder 解碼器, 無論一次接收到多少數(shù)據(jù)報(bào), 他都會(huì)按照構(gòu)造函數(shù)中設(shè)置的固定長度進(jìn)行解碼, 如果是半包消息, FixedLengthFrameDecoder 會(huì)緩存半包消息并等待下個(gè)包到達(dá)后進(jìn)行拼包, 直到讀取到一個(gè)完整的包.
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/72767.html
摘要:接收方只需要等待,直到讀到確定數(shù)量的字節(jié),然后處理即可。而這個(gè)字節(jié)流的前個(gè)字節(jié)用于表示對(duì)象的長度,接下來的字節(jié)就是傳輸?shù)膶?duì)象的字節(jié)流,最后不夠最大長度的用任意字節(jié)進(jìn)行填充即可。 什么是tcp半包粘包?簡單來講就是接收到的tcp包并不一定是一個(gè)完整的包。它可能是1個(gè)包的一部分,也可能是多個(gè)完整包加上1個(gè)包的一部分。為什么?因?yàn)閠cp的定義是面向字節(jié)流的傳輸協(xié)議,所以操作系統(tǒng)實(shí)現(xiàn)這個(gè)協(xié)議的...
摘要:設(shè)置每個(gè)數(shù)據(jù)包的大小如個(gè)字節(jié),如果某個(gè)數(shù)據(jù)包不足個(gè)字節(jié)可能會(huì)出現(xiàn)丟包的情況,即該數(shù)據(jù)包未從一個(gè)端到另一個(gè)端,此時(shí)需要用空格或者既定的符號(hào)補(bǔ)充在數(shù)據(jù)包之間使用一些字符進(jìn)行分割如號(hào)之類的,解析的時(shí)候先處理掉分隔符再拿到各個(gè)數(shù)據(jù)包就好了。 netty 概念: Netty是由JBOSS提供的一個(gè)java開源框架。Netty提供異步的、事件驅(qū)動(dòng)的網(wǎng)絡(luò)應(yīng)用程序框架和工具,用以快速開發(fā)高性能、高可靠...
摘要:其他編碼的可以參考,,的選擇不考慮隨機(jī)訪問,,查找第個(gè)字符時(shí)間復(fù)雜度隨機(jī)訪問,只用之內(nèi)的字符,,時(shí)間復(fù)雜度隨機(jī)訪問,超過了,詳解編碼 1.字符集vs字符編碼,編碼&解碼 Character----->code point----->bytes 前兩者字符集的關(guān)系,可以統(tǒng)稱為codepoint;從codepoint到在計(jì)算機(jī)上的存儲(chǔ)形式,稱為編碼,反過來稱為解碼; 字符集:單個(gè)符號(hào)(ch...
摘要:是一個(gè)面向字節(jié)流的協(xié)議,它是性質(zhì)是流式的,所以它并沒有分段??苫诜指舴鉀Q。編解碼的主要目的就是為了可以編碼成字節(jié)流用于在網(wǎng)絡(luò)中傳輸持久化存儲(chǔ)。 showImg(https://segmentfault.com/img/remote/1460000015895049); 前言 記得前段時(shí)間我們生產(chǎn)上的一個(gè)網(wǎng)關(guān)出現(xiàn)了故障。 這個(gè)網(wǎng)關(guān)邏輯非常簡單,就是接收客戶端的請(qǐng)求然后解析報(bào)文最后發(fā)送...
閱讀 2285·2021-11-25 09:43
閱讀 1233·2021-11-23 09:51
閱讀 3574·2021-11-23 09:51
閱讀 3701·2021-11-22 09:34
閱讀 1676·2021-10-09 09:43
閱讀 2189·2019-08-30 15:53
閱讀 3219·2019-08-30 14:07
閱讀 644·2019-08-28 18:14