亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

詳解Netty編碼器和解碼器

 更新時(shí)間:2021年06月07日 10:34:06   作者:_tommy  
很多小伙伴對(duì)Netty編解碼器這方面不是很了解,今天這篇文章給大家詳細(xì)介紹了Netty編碼器和解碼器的相關(guān)知識(shí),需要的朋友可以參考下

一、java的編解碼

1.編碼(Encode)稱為序列化, 它將對(duì)象序列化為字節(jié)數(shù)組,用于網(wǎng)絡(luò)傳輸、數(shù)據(jù)持久化或者其它 用途。

2.解碼(Decode)稱為反序列化,它把從網(wǎng)絡(luò)、磁盤等讀取的字節(jié)數(shù)組還原成原始對(duì)象(通常是原 始對(duì)象的拷貝),以方便后續(xù)的業(yè)務(wù)邏輯操作。

image-20210605230045944

java序列化對(duì)象只需要實(shí)現(xiàn)java.io.Serializable接口并生成序列化ID,這個(gè)類就能夠通過(guò) java.io.ObjectInput和java.io.ObjectOutput序列化和反序列化。

java序列化對(duì)象只需要實(shí)現(xiàn)java.io.Serializable接口并生成序列化ID,這個(gè)類就能夠通過(guò) java.io.ObjectInput和java.io.ObjectOutput序列化和反序列化。

Java序列化目的:1.網(wǎng)絡(luò)傳輸。2.對(duì)象持久化。

Java序列化缺點(diǎn):1.無(wú)法跨語(yǔ)言。 2.序列化后碼流太大。3.序列化性能太低。

Java序列化僅僅是Java編解碼技術(shù)的一種,由于它的種種缺陷,衍生出了多種編解碼技術(shù)和框 架,這些編解碼框架實(shí)現(xiàn)消息的高效序列化。

二、Netty編解碼器

概念:在網(wǎng)絡(luò)應(yīng)用中需要實(shí)現(xiàn)某種編解碼器,將原始字節(jié)數(shù)據(jù)與自定義的消息對(duì)象進(jìn)行互相轉(zhuǎn)換。網(wǎng)絡(luò)中都是以字節(jié)碼的數(shù)據(jù)形式來(lái)傳輸數(shù)據(jù)的,服務(wù)器編碼數(shù)據(jù)后發(fā)送到客戶端,客戶端需要對(duì)數(shù)據(jù)進(jìn)行解碼。

對(duì)于Netty而言,編解碼器由兩部分組成:編碼器、解碼器

  • 解碼器:負(fù)責(zé)將消息從字節(jié)或其他序列形式轉(zhuǎn)成指定的消息對(duì)象。
  • 編碼器:將消息對(duì)象轉(zhuǎn)成字節(jié)或其他序列形式在網(wǎng)絡(luò)上傳輸。

Netty 的編(解)碼器實(shí)現(xiàn)了 ChannelHandlerAdapter,也是一種特殊的 ChannelHandler,所 以依賴于 ChannelPipeline,可以將多個(gè)編(解)碼器鏈接在一起,以實(shí)現(xiàn)復(fù)雜的轉(zhuǎn)換邏輯。

Netty里面的編解碼: 解碼器:負(fù)責(zé)處理“入站 InboundHandler”數(shù)據(jù)。 編碼器:負(fù)責(zé)“出站 OutboundHandler” 數(shù)據(jù)。

入棧解碼,出棧編碼:

2.1 解碼器(Decoder)

解碼器負(fù)責(zé) 解碼“入站”數(shù)據(jù)從一種格式到另一種格式,解碼器處理入站數(shù)據(jù)是抽象 ChannelInboundHandler的實(shí)現(xiàn)。需要將解碼器放在ChannelPipeline中。對(duì)于解碼器,Netty中主要提供了抽象基類ByteToMessageDecoder和MessageToMessageDecoder。

image-20210605231024070

抽象解碼器

ByteToMessageDecoder: 用于將字節(jié)轉(zhuǎn)為消息,需要檢查緩沖區(qū)是否有足夠的字節(jié)

ReplayingDecoder: 繼承ByteToMessageDecoder,不需要檢查緩沖區(qū)是否有足夠的字節(jié),但 是 ReplayingDecoder速度略慢于ByteToMessageDecoder,同時(shí)不是所有的ByteBuf都支持。 項(xiàng)目復(fù)雜性高則使用ReplayingDecoder,否則使用ByteToMessageDecoder

MessageToMessageDecoder: 用于從一種消息解碼為另外一種消息(例如POJO到POJO)

核心方法

decode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out)

2.2 代碼實(shí)現(xiàn)

 MessageDecoder

package com.my.codec;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageDecoder;
import io.netty.util.CharsetUtil;

import java.util.List;

/**
 * 消息解碼器
 */
public class MessageDecoder extends MessageToMessageDecoder {
    @Override
    protected void decode(ChannelHandlerContext ctx, Object msg, List out) throws Exception {
        System.out.println("正在進(jìn)行消息解碼....");
        ByteBuf byteBuf = (ByteBuf) msg;
        out.add(byteBuf.toString(CharsetUtil.UTF_8));//傳遞到下一個(gè)handler
    }
}

NettyServerHandler

nettyServerHandler 實(shí)現(xiàn)ChannelInboundHandler, 重新若干方法。

通道讀取方法:

/**
     * 通道讀取事件
     *
     * @param ctx
     * @param msg
     * @throws Exception
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("客戶端發(fā)送過(guò)來(lái)的消息:" + msg);
    }

服務(wù)端在接收客戶端的消息時(shí),首先會(huì)經(jīng)過(guò)MessageDecoder編碼器,將字節(jié)變?yōu)樽址?,因此,在此處可直接輸出?/p>

NettyServer

serverBootstrap.group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .option(ChannelOption.SO_BACKLOG, 128)
                .childOption(ChannelOption.SO_KEEPALIVE, Boolean.TRUE)
                .childHandler(new ChannelInitializer<SocketChannel>() { 
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        //添加解碼器
                        ch.pipeline().addLast("messageDecoder", new MessageDecoder());
                        //向pipeline中添加自定義業(yè)務(wù)處理handler
                        ch.pipeline().addLast(new NettyServerHandler());
                    }
                });

在pipeline中添加解碼器

2.3 編碼器(Encoder)

與ByteToMessageDecoder和MessageToMessageDecoder相對(duì)應(yīng),Netty提供了對(duì)應(yīng)的編碼器 實(shí)現(xiàn)MessageToByteEncoder和MessageToMessageEncoder,二者都實(shí)現(xiàn) ChannelOutboundHandler接口。

image-20210605232231876

抽象編碼器

MessageToByteEncoder: 將消息轉(zhuǎn)化成字節(jié)MessageToMessageEncoder: 用于從一種消息編碼為另外一種消息(例如POJO到POJO)

核心方法:

encode(ChannelHandlerContext ctx, String msg, List<Object> out)

2.4 代碼實(shí)現(xiàn)

MessageEncoder

package com.my.codec;

import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageEncoder;
import io.netty.util.CharsetUtil;

import java.util.List;

/**
 * 消息的編碼器
 */
public class MessageEncoder extends MessageToMessageEncoder {
    @Override
    protected void encode(ChannelHandlerContext ctx, Object msg, List out) throws Exception {
        System.out.println("消息正在進(jìn)行編碼....");
        String str = (String) msg;
        out.add(Unpooled.copiedBuffer(str, CharsetUtil.UTF_8));
    }
}

NettyClientHandler

/**
     * 通道就緒事件
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        ChannelFuture future = ctx.writeAndFlush("你好呀.我是Netty客戶端");
        future.addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture future) throws Exception {
                if (future.isSuccess()) {
                    System.out.println("數(shù)據(jù)發(fā)送成功!");
                } else {
                    System.out.println("數(shù)據(jù)發(fā)送失敗!");
                }
            }
        });
    }

    /**
     * 通道讀就緒事件
     *
     * @param ctx
     * @param msg
     * @throws Exception
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("服務(wù)端發(fā)送的消息:" + msg);
    }

當(dāng)客戶端通道準(zhǔn)備就緒時(shí),會(huì)向服務(wù)端發(fā)送 “你好呀.我是Netty客戶端”,由于出棧是逆序的,因此,直接傳入字符串,當(dāng)出棧時(shí),會(huì)經(jīng)過(guò)編碼器(在nettyclient中添加的)

NettyClient

bootstrap.group(group)
                .channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<SocketChannel>() { 
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        //添加解碼器
                        ch.pipeline().addLast("messageDecoder", new MessageDecoder());
                        //添加編碼器
                        ch.pipeline().addLast("messageEncoder", new MessageEncoder());                  
                        //向pipeline中添加自定義業(yè)務(wù)處理handler
                        ch.pipeline().addLast(new NettyClientHandler());
                    }
                });

同時(shí),在NettyServerHandler 中也添加相同的編解碼器。

因?yàn)槭请p向通信,因此,在服務(wù)端和客戶端的pipeline中均需要添加編解碼器。

2.5 測(cè)試結(jié)果

服務(wù)端打?。?/p>

image-20210605233932707

客戶端打印:

image-20210605233943017

三、編碼解碼器Codec

編碼解碼器:

同時(shí)具有編碼與解碼功能,特點(diǎn)同時(shí)實(shí)現(xiàn)了ChannelInboundHandler和 ChannelOutboundHandler接口,因此在數(shù)據(jù)輸入和輸出時(shí)都能進(jìn)行處理。

image-20210605234135527

Netty提供提供了一個(gè)ChannelDuplexHandler適配器類,編碼解碼器的抽象基類

ByteToMessageCodec ,MessageToMessageCodec都繼承與此類

3.1 代碼實(shí)現(xiàn):

package com.my.codec;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageCodec;
import io.netty.util.CharsetUtil;

import java.util.List;

/**
 * 消息編解碼器
 */
public class MessageCodec extends MessageToMessageCodec {
    /**
     * 編碼
     *
     * @param ctx
     * @param msg
     * @param out
     * @throws Exception
     */
    @Override
    protected void encode(ChannelHandlerContext ctx, Object msg, List out) throws Exception {
        System.out.println("消息正在進(jìn)行編碼....");
        String str = (String) msg;
        out.add(Unpooled.copiedBuffer(str, CharsetUtil.UTF_8));
    }

    /**
     * 解碼
     *
     * @param ctx
     * @param msg
     * @param out
     * @throws Exception
     */
    @Override
    protected void decode(ChannelHandlerContext ctx, Object msg, List out) throws Exception {
        System.out.println("正在進(jìn)行消息解碼....");
        ByteBuf byteBuf = (ByteBuf) msg;
        out.add(byteBuf.toString(CharsetUtil.UTF_8));//傳遞到下一個(gè)handler
    }
}

NettyServer、NettyClient

在NettyServer和NettyClient中添加

ch.pipeline().addLast(new MessageCodec());
//8. 向pipeline中添加自定義業(yè)務(wù)處理handler
ch.pipeline().addLast(new NettyServerHandler());

eBuf = (ByteBuf) msg;
out.add(byteBuf.toString(CharsetUtil.UTF_8));//傳遞到下一個(gè)handler
}
}

ch.pipeline().addLast(new MessageCodec());
//8. 向pipeline中添加自定義業(yè)務(wù)處理handler
ch.pipeline().addLast(new NettyServerHandler());

測(cè)試結(jié)果與1.2.5測(cè)試結(jié)果一致

到此這篇關(guān)于詳解Netty編碼器和解碼器的文章就介紹到這了,更多相關(guān)Netty編解碼器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring Boot實(shí)戰(zhàn)之靜態(tài)資源處理

    Spring Boot實(shí)戰(zhàn)之靜態(tài)資源處理

    這篇文章主要介紹了Spring Boot實(shí)戰(zhàn)之靜態(tài)資源處理,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-01-01
  • 詳解在Java的Struts2框架中配置Action的方法

    詳解在Java的Struts2框架中配置Action的方法

    這篇文章主要介紹了詳解在Java的Struts2框架中配置Action的方法,講解了包括struts.xml中的action配置及基于注解方式Action配置的兩個(gè)方式,需要的朋友可以參考下
    2016-03-03
  • 基于Springboot的高校社團(tuán)管理系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)

    基于Springboot的高校社團(tuán)管理系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)

    本文將基于Springboot+Mybatis開發(fā)實(shí)現(xiàn)一個(gè)高校社團(tuán)管理系統(tǒng),系統(tǒng)包含三個(gè)角色:管理員、團(tuán)長(zhǎng)、會(huì)員。文中采用的技術(shù)有Springboot、Mybatis、Jquery、AjAX、JSP等,感興趣的可以了解一下
    2022-07-07
  • Java實(shí)現(xiàn)UDP多線程在線咨詢

    Java實(shí)現(xiàn)UDP多線程在線咨詢

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)UDP多線程在線咨詢,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • 徹底解決java.lang.ClassNotFoundException: com.mysql.jdbc.Driver問(wèn)題

    徹底解決java.lang.ClassNotFoundException: com.mysql.jdbc.Dr

    這篇文章給大家介紹了如如何徹底解決java.lang.ClassNotFoundException: com.mysql.jdbc.Driver問(wèn)題,文中有詳細(xì)的解決思路以及解決方法,需要的朋友可以參考下
    2023-11-11
  • Java中switch判斷語(yǔ)句典型使用實(shí)例

    Java中switch判斷語(yǔ)句典型使用實(shí)例

    這篇文章主要介紹了Java中switch判斷語(yǔ)句典型使用實(shí)例,本文直接給出代碼實(shí)例,在忘記switch語(yǔ)法時(shí)特別有用,復(fù)制修改即可使用,需要的朋友可以參考下
    2015-06-06
  • Groovy編程入門攻略

    Groovy編程入門攻略

    這篇文章主要介紹了Groovy編程入門攻略,Groovy是一種同樣使用Java虛擬機(jī)的動(dòng)態(tài)語(yǔ)言,需要的朋友可以參考下
    2015-07-07
  • Spring Gateway處理微服務(wù)的路由轉(zhuǎn)發(fā)機(jī)制

    Spring Gateway處理微服務(wù)的路由轉(zhuǎn)發(fā)機(jī)制

    我們?cè)敿?xì)地介紹了Spring Gateway,這個(gè)基于Spring 5、Spring Boot 2和Project Reactor的API網(wǎng)關(guān),通過(guò)這篇文章,我們可以清晰地看到Spring Gateway的工作原理,以及它的強(qiáng)大之處,感興趣的朋友一起看看吧
    2024-08-08
  • 字節(jié)二面SpringBoot可以同時(shí)處理多少請(qǐng)求

    字節(jié)二面SpringBoot可以同時(shí)處理多少請(qǐng)求

    這篇文章主要為大家介紹了字節(jié)二面之SpringBoot可以同時(shí)處理多少請(qǐng)求面試分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • JAVA三種異常處理機(jī)制的具體使用

    JAVA三種異常處理機(jī)制的具體使用

    異常是程序在編譯或執(zhí)行的過(guò)程中可能出現(xiàn)的問(wèn)題,本文主要介紹了JAVA三種異常處理機(jī)制的具體使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-06-06

最新評(píng)論