返回顶部
首页 > 资讯 > 后端开发 > Python >详解Netty编码器和解码器
  • 327
分享到

详解Netty编码器和解码器

2024-04-02 19:04:59 327人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

目录一、java的编解码二、Netty编解码器2.1 解码器(Decoder)2.2 代码实现2.3 编码器(Encoder)2.4 代码实现2.5 测试结果三、编码解码器Codec

一、java的编解码

1.编码(Encode)称为序列化, 它将对象序列化为字节数组,用于网络传输、数据持久化或者其它 用途。

2.解码(Decode)称为反序列化,它把从网络、磁盘等读取的字节数组还原成原始对象(通常是原 始对象的拷贝),以方便后续的业务逻辑操作。

image-20210605230045944

java序列化对象只需要实现java.io.Serializable接口并生成序列化ID,这个类就能够通过 java.io.ObjectInput和java.io.ObjectOutput序列化和反序列化。

java序列化对象只需要实现java.io.Serializable接口并生成序列化ID,这个类就能够通过 java.io.ObjectInput和java.io.ObjectOutput序列化和反序列化。

Java序列化目的:1.网络传输。2.对象持久化。

Java序列化缺点:1.无法跨语言。 2.序列化后码流太大。3.序列化性能太低。

Java序列化仅仅是Java编解码技术的一种,由于它的种种缺陷,衍生出了多种编解码技术和框 架,这些编解码框架实现消息的高效序列化。

二、Netty编解码器

概念:在网络应用中需要实现某种编解码器,将原始字节数据与自定义的消息对象进行互相转换。网络中都是以字节码的数据形式来传输数据的,服务器编码数据后发送到客户端,客户端需要对数据进行解码。

对于Netty而言,编解码器由两部分组成:编码器、解码器

  • 解码器:负责将消息从字节或其他序列形式转成指定的消息对象。
  • 编码器:将消息对象转成字节或其他序列形式在网络上传输。

Netty 的编(解)码器实现了 ChannelHandlerAdapter,也是一种特殊的 ChannelHandler,所 以依赖于 ChannelPipeline,可以将多个编(解)码器链接在一起,以实现复杂的转换逻辑。

Netty里面的编解码: 解码器:负责处理“入站 InboundHandler”数据。 编码器:负责“出站 OutboundHandler” 数据。

入栈解码,出栈编码:

2.1 解码器(Decoder)

解码器负责 解码“入站”数据从一种格式到另一种格式,解码器处理入站数据是抽象 ChannelInboundHandler的实现。需要将解码器放在ChannelPipeline中。对于解码器,Netty中主要提供了抽象基类ByteToMessageDecoder和MessageToMessageDecoder。

image-20210605231024070

抽象解码器

ByteToMessageDecoder: 用于将字节转为消息,需要检查缓冲区是否有足够的字节

ReplayingDecoder: 继承ByteToMessageDecoder,不需要检查缓冲区是否有足够的字节,但 是 ReplayingDecoder速度略慢于ByteToMessageDecoder,同时不是所有的ByteBuf都支持。 项目复杂性高则使用ReplayingDecoder,否则使用ByteToMessageDecoder

MessageToMessageDecoder: 用于从一种消息解码为另外一种消息(例如POJO到POJO)

核心方法


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

2.2 代码实现

 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("正在进行消息解码....");
        ByteBuf byteBuf = (ByteBuf) msg;
        out.add(byteBuf.toString(CharsetUtil.UTF_8));//传递到下一个handler
    }
}

NettyServerHandler

nettyServerHandler 实现ChannelInboundHandler, 重新若干方法。

通道读取方法:



    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("客户端发送过来的消息:" + msg);
    }

服务端在接收客户端的消息时,首先会经过MessageDecoder编码器,将字节变为字符串,因此,在此处可直接输出。

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中添加自定义业务处理handler
                        ch.pipeline().addLast(new NettyServerHandler());
                    }
                });

在pipeline中添加解码器

2.3 编码器(Encoder)

与ByteToMessageDecoder和MessageToMessageDecoder相对应,Netty提供了对应的编码器 实现MessageToByteEncoder和MessageToMessageEncoder,二者都实现 ChannelOutboundHandler接口。

image-20210605232231876

抽象编码器

MessageToByteEncoder: 将消息转化成字节MessageToMessageEncoder: 用于从一种消息编码为另外一种消息(例如POJO到POJO)

核心方法:


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

2.4 代码实现

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("消息正在进行编码....");
        String str = (String) msg;
        out.add(Unpooled.copiedBuffer(str, CharsetUtil.UTF_8));
    }
}

NettyClientHandler



    @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("数据发送成功!");
                } else {
                    System.out.println("数据发送失败!");
                }
            }
        });
    }

    
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("服务端发送的消息:" + msg);
    }

当客户端通道准备就绪时,会向服务端发送 “你好呀.我是Netty客户端”,由于出栈是逆序的,因此,直接传入字符串,当出栈时,会经过编码器(在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中添加自定义业务处理handler
                        ch.pipeline().addLast(new NettyClientHandler());
                    }
                });

同时,在NettyServerHandler 中也添加相同的编解码器。

因为是双向通信,因此,在服务端和客户端的pipeline中均需要添加编解码器。

2.5 测试结果

服务端打印:

image-20210605233932707

客户端打印:

image-20210605233943017

三、编码解码器Codec

编码解码器:

同时具有编码与解码功能,特点同时实现了ChannelInboundHandler和 ChannelOutboundHandler接口,因此在数据输入和输出时都能进行处理。

image-20210605234135527

Netty提供提供了一个ChannelDuplexHandler适配器类,编码解码器的抽象基类

ByteToMessageCodec ,MessageToMessageCodec都继承与此类

3.1 代码实现:


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 {
    
    @Override
    protected void encode(ChannelHandlerContext ctx, Object msg, List out) throws Exception {
        System.out.println("消息正在进行编码....");
        String str = (String) msg;
        out.add(Unpooled.copiedBuffer(str, CharsetUtil.UTF_8));
    }

    
    @Override
    protected void decode(ChannelHandlerContext ctx, Object msg, List out) throws Exception {
        System.out.println("正在进行消息解码....");
        ByteBuf byteBuf = (ByteBuf) msg;
        out.add(byteBuf.toString(CharsetUtil.UTF_8));//传递到下一个handler
    }
}

NettyServer、NettyClient

在NettyServer和NettyClient中添加


ch.pipeline().addLast(new MessageCodec());
//8. 向pipeline中添加自定义业务处理handler
ch.pipeline().addLast(new NettyServerHandler());

eBuf = (ByteBuf) msg;
out.add(byteBuf.toString(CharsetUtil.UTF_8));//传递到下一个handler
}
}


ch.pipeline().addLast(new MessageCodec());
//8. 向pipeline中添加自定义业务处理handler
ch.pipeline().addLast(new NettyServerHandler());

测试结果与1.2.5测试结果一致

到此这篇关于详解Netty编码器和解码器的文章就介绍到这了,更多相关Netty编解码器内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 详解Netty编码器和解码器

本文链接: https://lsjlt.com/news/127714.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 详解Netty编码器和解码器
    目录一、java的编解码二、Netty编解码器2.1 解码器(Decoder)2.2 代码实现2.3 编码器(Encoder)2.4 代码实现2.5 测试结果三、编码解码器Codec...
    99+
    2024-04-02
  • 详解netty中常用的xml编码解码器
    目录简介XmlFrameDecoderXmlDecoder总结简介 在json之前,xml是最常用的数据传输格式,虽然xml的冗余数据有点多,但是xml的结构简单清晰,至今仍然运用在...
    99+
    2024-04-02
  • 详解netty中的frame解码器
    目录简介LineBasedFrameDecoderDelimiterBasedFrameDecoderFixedLengthFrameDecoderLengthFieldBasedF...
    99+
    2024-04-02
  • netty中常用的xml编码解码器怎么用
    这篇文章主要讲解了“netty中常用的xml编码解码器怎么用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“netty中常用的xml编码解码器怎么用”吧!简介在json之前,xml是最常用的数...
    99+
    2023-06-30
  • 基于Protostuff怎么实现Netty编解码器
    本篇内容主要讲解“基于Protostuff怎么实现Netty编解码器”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“基于Protostuff怎么实现Netty编解...
    99+
    2024-04-02
  • Netty分布式行解码器逻辑源码解析
    目录行解码器LineBasedFrameDecoder首先看其参数我们跟到重载的decode方法中我们看findEndOfLine(buffer)方法前文传送门:Netty分布式固定...
    99+
    2024-04-02
  • Netty实战源码解析NIO编程
    目录1 前言2 Netty是什么?3 Java I/O模型简介3.1 BIO代码实现4 Java NIO4.1 基本介绍4.2 三大核心组件的关系4.3 Buffer缓冲区4.4 C...
    99+
    2022-12-21
    Netty NIO编程 Netty NIO
  • shiro编码和加密代码详解
    涉及到密码存储问题上,应该加密/生成密码摘要存储,而不是存储明文密码。比如之前的600w csdn账号泄露对用户可能造成很大损失,因此应加密/生成不可逆的摘要方式存储。编码/解码 Shiro提供了base64和16进制字符串编码/...
    99+
    2023-05-31
    shiro 编码 加密
  • netty中的frame解码器怎么用
    这篇文章主要介绍“netty中的frame解码器怎么用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“netty中的frame解码器怎么用”文章能帮助大家解决问题。简介netty中的数据是通过Byte...
    99+
    2023-06-30
  • Netty结合Protobuf进行编解码的方法
     一般在使用netty时,数据传输的时候都会选择对传输的数据进行编解码,编码后的数据变小, 有利于在有限的带宽下传输更多的数据。 由于java本身序列化的缺点较多(无法跨...
    99+
    2024-04-02
  • android webp编解码详解
    key words:android decode webp sample 当我敲下键盘的时候有种深深的耻辱感,看到android 4.0支持webp格式的图像,于是我狠命的找提...
    99+
    2022-06-06
    解码 webp Android
  • 【Python编程错误:‘utf-8‘编解码器无法解码字节0xd5】--解决方法详解
    【Python编程错误:'utf-8’编解码器无法解码字节0xd5】–解决方法详解 Python是一门非常流行的高级编程语言,用户可以很方便地使用它来实现各种功能。然而,在使用Python编...
    99+
    2023-08-31
    Python
  • 解决Netty解码http请求获取URL乱码问题
    目录Netty解码http请求获取URL乱码解决方案原因Netty---编解码(原理) 1.ByteToMessageDecoder2.FixedLengthFrameDe...
    99+
    2024-04-02
  • python密码学Base64编码和解码教程
    目录Base64编码编码程序输出解码程序输出差异在ASCII和base64之间缺点Base64编码 Base64编码将二进制数据转换为文本格式,通过通信通道传递,用户可以安全地处理文...
    99+
    2024-04-02
  • Netty分布式抽象编码器MessageToByteEncoder逻辑分析
    目录MessageToByteEncoder首先看MessageToByteEncoder的类声明跟到allocateBuffer方法中前文回顾:Netty分布式编码器及写数据事件处...
    99+
    2024-04-02
  • Python3内置json模块编码解码方法详解
    目录JSON简介dumps编码编码字典编码列表编码字符串格式化输出JSON转换关系对照表loads解码总结JSON简介 JSON(JavaScript Object Notation...
    99+
    2024-04-02
  • Vue编译器源码分析compileToFunctions作用详解
    目录引言Vue.prototype.$mount函数体shouldDecodeNewlinesoptions.delimiters & options.commentscom...
    99+
    2024-04-02
  • 解决uWSGI的编码问题详解
    发现问题 最近工作中遇到一个问题,在把 Flask 写的应用通过 Supervisor+uWSGI 部署到正式服务器上时,出现了这样的错误: Unable to print the message an...
    99+
    2022-06-04
    详解 uWSGI
  • Netty组件NioEventLoopGroup创建线程执行器源码解析
    目录前言第一节:  NioEventLoopGroup之创建线程执行器创建EventLoopGroup的构造方法跟到MultithreadEventExecutorGrou...
    99+
    2024-04-02
  • Netty分布式ByteBuf缓冲区分配器源码解析
    目录缓冲区分配器以其中的分配ByteBuf的方法为例, 对其做简单的介绍跟到directBuffer()方法中我们回到缓冲区分配的方法然后通过validate方法进行参数验...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作