溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

netty server怎樣解決粘包問題

發(fā)布時(shí)間:2021-12-06 16:55:27 來源:億速云 閱讀:202 作者:柒染 欄目:大數(shù)據(jù)

netty server怎樣解決粘包問題,很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。

1、什么是粘包/拆包

一般所謂的TCP粘包是在一次接收數(shù)據(jù)不能完全地體現(xiàn)一個(gè)完整的消息數(shù)據(jù)。TCP通訊為何存在粘包呢?主要原因是TCP是以流的方式來處理數(shù)據(jù),再加上網(wǎng)絡(luò)上MTU的往往小于在應(yīng)用處理的消息數(shù)據(jù),所以就會(huì)引發(fā)一次接收的數(shù)據(jù)無法滿足消息的需要,導(dǎo)致粘包的存在。處理粘包的唯一方法就是制定應(yīng)用層的數(shù)據(jù)通訊協(xié)議,通過協(xié)議來規(guī)范現(xiàn)有接收的數(shù)據(jù)是否滿足消息數(shù)據(jù)的需要。

2、解決辦法

2.1、消息定長(zhǎng),報(bào)文大小固定長(zhǎng)度,不夠空格補(bǔ)全,發(fā)送和接收方遵循相同的約定,這樣即使粘包了通過接收方編程實(shí)現(xiàn)獲取定長(zhǎng)報(bào)文也能區(qū)分。

2.2、包尾添加特殊分隔符,例如每條報(bào)文結(jié)束都添加回車換行符(例如FTP協(xié)議)或者指定特殊字符作為報(bào)文分隔符,接收方通過特殊分隔符切分報(bào)文區(qū)分。

2.3、將消息分為消息頭和消息體,消息頭中包含表示信息的總長(zhǎng)度(或者消息體長(zhǎng)度)的字段

3、netty server端設(shè)置特殊分隔符

  • 注意:分隔符一定要在數(shù)據(jù)處理的handler之前指定

@Component
public class NettyServer {
    @Value("${netty.server.port}")
    private int port;
    /**
     * 啟動(dòng) netty server
     * @throws InterruptedException
     */
    public void start() {
        EventLoopGroup parentGroup = new NioEventLoopGroup();
        EventLoopGroup childGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(parentGroup, childGroup)
                    .channel(NioServerSocketChannel.class)
                    .option(ChannelOption.SO_BACKLOG, Integer.parseInt(CommonUtils.getConfig("ChannelOption.SO_BACKLOG")))     // 設(shè)置線程隊(duì)列得到連接個(gè)數(shù)
                    .option(ChannelOption.SO_KEEPALIVE, true)  // 設(shè)置保持連接的活動(dòng)狀態(tài)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) {
                            // 注意消息分隔符處理的handler一定要在消息處理邏輯前面
                            ByteBuf buf = Unpooled.copiedBuffer("\t", Charset.defaultCharset());//自定義拆包字符
                            //(1024)解碼的幀的最大長(zhǎng)度,false(拆包是否去掉指定字符),buf(拆包字符)
                            DelimiterBasedFrameDecoder delimiterBasedFrameDecoder = new DelimiterBasedFrameDecoder(1400, true, buf);
                            ch.pipeline().addLast(delimiterBasedFrameDecoder);
                            ch.pipeline().addLast(new NettyServerHandler2());
                        }
                    });
            ChannelFuture channelFuture = serverBootstrap.bind(port).sync();
            channelFuture.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            try {
                parentGroup.shutdownGracefully().sync();
                childGroup.shutdownGracefully().sync();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝您對(duì)億速云的支持。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI