成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

使用 LineBasedFrameDecoder 和 StringDecoder 解決半包粘包問(wèn)題

HollisChuang / 2573人閱讀

摘要:修改之前的服務(wù)端開(kāi)發(fā)代碼修改為下面代碼綁定端口同步等待成功等待服務(wù)端監(jiān)聽(tīng)端口關(guān)閉主要修改了和方法和原理分析的工作原理是它依次遍歷中的可讀字節(jié)判斷看是否有或如果有就以此位置為結(jié)束位置從可讀索引到結(jié)束位置區(qū)間的字節(jié)就組成了一行它是以換行符為結(jié)束

修改之前的 Netty 服務(wù)端開(kāi)發(fā) 代碼, 修改為下面代碼

public class TimeServer {

    public void bind(int port) throws Exception {

        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .option(ChannelOption.SO_BACKLOG, 1024)
                    .childHandler(new ChildChannelHandler());

            // 綁定端口, 同步等待成功
            ChannelFuture f = b.bind(port).sync();

            // 等待服務(wù)端監(jiān)聽(tīng)端口關(guān)閉
            f.channel().closeFuture().sync();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }

    private class ChildChannelHandler extends ChannelInitializer {

        @Override
        protected void initChannel(SocketChannel ch) throws Exception {
            ch.pipeline().addLast(new LineBasedFrameDecoder(1024));
            ch.pipeline().addLast(new StringDecoder());
            ch.pipeline().addLast(new TimeServerHandler());
        }
    }

    private class TimeServerHandler extends ChannelHandlerAdapter {
        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
            ctx.close();
        }

        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
            String body = (String) msg;
            System.out.println(body);

            ByteBuf resp = Unpooled.copiedBuffer("6666".getBytes());
            ctx.write(resp);
        }

        @Override
        public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
            ctx.flush();
        }
    }

}

主要修改了 initChannelchannelRead 方法.

LineBasedFrameDecoder 和 StringDecoder 原理分析

LineBasedFrameDecoder 的工作原理是它依次遍歷 ByteBuf 中的可讀字節(jié), 判斷看是否有 , 如果有, 就以此位置為結(jié)束位置, 從可讀索引到結(jié)束位置區(qū)間的字節(jié)就組成了一行.

它是以換行符為結(jié)束標(biāo)志的解碼器, 支持?jǐn)y帶結(jié)束符或者不攜帶結(jié)束符兩種解碼方式, 同時(shí)支持配置單行的最大長(zhǎng)度. 如果連續(xù)讀取到最大長(zhǎng)度后仍然沒(méi)有發(fā)現(xiàn)換行符, 就會(huì)拋出異常, 同時(shí)忽略之前讀到的異常碼流.

StringDecoder 的功能非常簡(jiǎn)單, 就是將收到的對(duì)象轉(zhuǎn)換成字符串, 然后繼續(xù)調(diào)用后面Handler.

LineBasedFrameDecoder + StringDecoder 組合就是按行切換的文本解碼器, 它被設(shè)計(jì)用來(lái)支持 TCP 的粘包和拆包.

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/72740.html

相關(guān)文章

  • 基于定長(zhǎng)消息的java nio半包粘包處理

    摘要:接收方只需要等待,直到讀到確定數(shù)量的字節(jié),然后處理即可。而這個(gè)字節(jié)流的前個(gè)字節(jié)用于表示對(duì)象的長(zhǎng)度,接下來(lái)的字節(jié)就是傳輸?shù)膶?duì)象的字節(jié)流,最后不夠最大長(zhǎng)度的用任意字節(jié)進(jìn)行填充即可。 什么是tcp半包粘包?簡(jiǎn)單來(lái)講就是接收到的tcp包并不一定是一個(gè)完整的包。它可能是1個(gè)包的一部分,也可能是多個(gè)完整包加上1個(gè)包的一部分。為什么?因?yàn)閠cp的定義是面向字節(jié)流的傳輸協(xié)議,所以操作系統(tǒng)實(shí)現(xiàn)這個(gè)協(xié)議的...

    Loong_T 評(píng)論0 收藏0
  • Netty(三) 什么是 TCP 拆、粘包?如何解決?

    摘要:是一個(gè)面向字節(jié)流的協(xié)議,它是性質(zhì)是流式的,所以它并沒(méi)有分段??苫诜指舴鉀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)邏輯非常簡(jiǎn)單,就是接收客戶端的請(qǐng)求然后解析報(bào)文最后發(fā)送...

    YanceyOfficial 評(píng)論0 收藏0
  • 分隔符定長(zhǎng)解碼器的應(yīng)用

    摘要:以流的方式進(jìn)行數(shù)據(jù)傳輸上層的應(yīng)用協(xié)議為了對(duì)消息進(jìn)行區(qū)分往往采用如下中方式消息長(zhǎng)度固定累計(jì)讀取到長(zhǎng)度總和為定長(zhǎng)的報(bào)文后就認(rèn)為讀到了一個(gè)完整的消息將計(jì)數(shù)器置位重新開(kāi)始讀取下一個(gè)數(shù)據(jù)報(bào)將回車換行符作為消息結(jié)束符例如協(xié)議這種方式在文本協(xié)議中應(yīng)用比較 TCP 以流的方式進(jìn)行數(shù)據(jù)傳輸, 上層的應(yīng)用協(xié)議為了對(duì)消息進(jìn)行區(qū)分, 往往采用如下 4 中方式. 消息長(zhǎng)度固定, 累計(jì)讀取到長(zhǎng)度總和為定長(zhǎng) LE...

    lemon 評(píng)論0 收藏0
  • netty

    摘要:設(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開(kāi)源框架。Netty提供異步的、事件驅(qū)動(dòng)的網(wǎng)絡(luò)應(yīng)用程序框架和工具,用以快速開(kāi)發(fā)高性能、高可靠...

    cfanr 評(píng)論0 收藏0
  • 徹底理解Netty,這一篇文章就夠了

    摘要:如果什么事都沒(méi)得做,它也不會(huì)死循環(huán),它會(huì)將線程休眠起來(lái),直到下一個(gè)事件來(lái)了再繼續(xù)干活,這樣的一個(gè)線程稱之為線程。而請(qǐng)求處理邏輯既可以使用單獨(dú)的線程池進(jìn)行處理,也可以跟放在讀寫(xiě)線程一塊處理。 Netty到底是什么 從HTTP說(shuō)起 有了Netty,你可以實(shí)現(xiàn)自己的HTTP服務(wù)器,F(xiàn)TP服務(wù)器,UDP服務(wù)器,RPC服務(wù)器,WebSocket服務(wù)器,Redis的Proxy服務(wù)器,MySQL的P...

    yy13818512006 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<