使用网状的进行编解码的操作过程详解

  

  

何为编解码,通俗的来说,我们需要将一串文本信息从一个发送到B并且将这段文本进行加工处理,如:一个将信息文本信息编码为2进制信息进行传输。B接受到的消息是一串2进制信息,需要将其解码为文本信息才能正常进行处理。

  

上章我们介绍的网状的如何解决拆包和粘包问题,就是运用了解码的这一功能。

  


  

  

使用网状的大多是java程序猿,我们基于一切都是对象的原则,经常会将对象进行网络传输,那么对于序列化操作肯定大家都是非常熟悉的。

  

一个对象是不能直接进行网络I/O传输的,jdk默认是将对象转换为可存储的字节数组来进行网络操作。基于jdk默认的序列化机制可以避免操作底层的字节数组,从而提升开发效率。

  

jdk默认的序列化机制虽然能给程序猿带来极大的方便,但是它也带来了许多问题:

  
      <李>无法跨语言。   <李>序列化后的码流太大,会给网络传输带来极大的开销。   <李>序列化的性能太低,对于高性能的网络架构是极其不友好的。   
  


  

  
      <李>谷歌的Protobuf。   <李> Facebok的节俭。   <李> Jboss编组李   <李> MessagePack李   
  

这几类编解码框架都有各自的特点,有兴趣的童鞋可以自己对其进行研究。

  

我们这里主要对MessagePack进行讲解。

  


  

  

MessagePack是一个高效的二进制序列化框架,它像JSON一样支持不同的语言间的数据交换,并且它的性能更快,序列化之后的码流也更小。

  

它的特点如下:

  
      <李>编解码高效、性能高李   <李>序列化之后的码流小,利于网络传输或存储李   <李>支持跨语言李   
  


  

  

首先导包
  

        & lt; !——https://mvnrepository.com/artifact/org.msgpack/msgpack——比;   & lt; dependency>   & lt; groupId> org.msgpack   & lt; artifactId> msgpack   & lt; version> 0.6.12   & lt;/dependency>      

使用API进行编码和解码
  

        List名称列表=new ArrayList ();   nameList.add(“汤姆”);   nameList.add(“杰克”);   MessagePack MessagePack=new MessagePack ();//开始序列化   生byte []=messagePack.write(学生名单);//使用MessagePack的模版,来接序列化后的字节数组转换为列表   ListdeNameList=messagePack.read(原始Templates.tList (Templates.TString));   System.out.println (deNameList.get (0));   System.out.println (deNameList.get (1));   System.out.println (deNameList.get (2));      


  

  

<强>编码器的实现

        公开课MsgpackEncoder延伸MessageToByteEncoder {      @Override   保护无效编码(ChannelHandlerContext ctx、对象味精ByteBuf){抛出异常   MessagePack msgpack=new MessagePack ();//使用MessagePack对要发送的数据进行序列化   生byte []=msgpack.write(味精);   out.writeBytes(生);      }      }      

<>强解码器的实现
  

        公开课MsgpackDecoder延伸MessageToMessageDecoder{      @Override   保护无效解码(ChannelHandlerContext ctx ByteBuf味精、List){抛出异常//从味精中获取需要解码的字节数组   最后一个int长度=msg.readableBytes ();   byte [] b=新的字节(长度);   msg.getBytes (msg.readerIndex (), b, 0,长度);//使用MessagePack的阅读方法将其反序列化成对象对象,并加入到解码列表中   MessagePack msgpack=new MessagePack ();   out.add (msgpack.read (b));   }      }      

<>强实现该编码器和解码器的网状的服务端
  

        公开课NettyServer {   公共空间绑定(int端口){抛出异常   EventLoopGroup bossGruop=new NioEventLoopGroup ();   EventLoopGroup工作组=new NioEventLoopGroup ();   ServerBootstrap引导=new ServerBootstrap ();   引导。集团(bossGruop工作组)   .channel (NioServerSocketChannel.class)   .option (ChannelOption。SO_BACKLOG, 1024)   .childHandler(新的ChannelInitializer () {   @Override   保护无效initChannel (SocketChannel SocketChannel){抛出异常//TODO自动生成方法存根   socketChannel.pipeline ()//添加支持粘包,拆包解码器,意义:从头两个字节解析出数据的长度,并且长度不超过1024个字节   .addLast (“frameDecoder”、新LengthFieldBasedFrameDecoder (1024 0 2 0 2))//反序列化解码器   .addLast (“msgpack译码器”,新的MsgpackDecoder ())//添加支持粘包,拆包编码器,发送的每个数据都在头部增加两个字节表消息长度   .addLast (“frameEncoder”,新的LengthFieldPrepender (2))//序列化编码器   新MsgpackEncoder .addLast (“msgpack编码器”()//后续自己的业务逻辑   .addLast(新ServerHandler ());   }   });   尝试{   ChannelFuture未来=bootstrap.bind(端口).sync ();   .sync .closeFuture future.channel () () ();   }捕捉(异常e) {   e.printStackTrace ();   最后}{   bossGruop.shutdownGracefully ();   workGroup.shutdownGracefully ();   }   }   }

使用网状的进行编解码的操作过程详解

Copyright © 2020-2023 feiqueyun.cn. All Rights Reserved. 肥雀云_南京肥雀信息技术有限公司版权所有 南京肥雀信息技术有限公司 苏ICP备16063723号-5