中文字幕第五页-中文字幕第页-中文字幕韩国-中文字幕最新-国产尤物二区三区在线观看-国产尤物福利视频一区二区

使用Netty進行編解碼的操作過程詳解

前言

成都創新互聯公司專注于丘北企業網站建設,成都響應式網站建設,電子商務商城網站建設。丘北網站建設公司,為丘北等地區提供建站服務。全流程按需定制制作,專業設計,全程項目跟蹤,成都創新互聯公司專業和態度為您提供的服務

何為編解碼,通俗的來說,我們需要將一串文本信息從A發送到B并且將這段文本進行加工處理,如:A將信息文本信息編碼為2進制信息進行傳輸。B接受到的消息是一串2進制信息,需要將其解碼為文本信息才能正常進行處理。

上章我們介紹的Netty如何解決拆包和粘包問題,就是運用了解碼的這一功能。

java默認的序列化機制

使用Netty大多是java程序猿,我們基于一切都是對象的原則,經常會將對象進行網絡傳輸,那么對于序列化操作肯定大家都是非常熟悉的。

一個對象是不能直接進行網絡I/O傳輸的,jdk默認是將對象轉換為可存儲的字節數組來進行網絡操作。基于JDK默認的序列化機制可以避免操作底層的字節數組,從而提升開發效率。

jdk默認的序列化機制雖然能給程序猿帶來極大的方便,但是它也帶來了許多問題:

  • 無法跨語言。
  • 序列化后的碼流太大,會給網絡傳輸帶來極大的開銷。
  • 序列化的性能太低,對于高性能的網絡架構是極其不友好的。

主流的編解碼框架

  • Google的Protobuf。
  • Facebok的Thrift。
  • Jboss Marshalling
  • MessagePack

這幾類編解碼框架都有各自的特點,有興趣的童鞋可以自己對其進行研究。

我們這里主要對MessagePack進行講解。

MessagePack簡介

MessagePack是一個高效的二進制序列化框架,它像JSON一樣支持不同的語言間的數據交換,并且它的性能更快,序列化之后的碼流也更小。

它的特點如下:

  • 編解碼高效,性能高
  • 序列化之后的碼流小,利于網絡傳輸或存儲
  • 支持跨語言

MessagePack Java Api的使用

首先導包

<!-- https://mvnrepository.com/artifact/org.msgpack/msgpack -->
<dependency>
  <groupId>org.msgpack</groupId>
  <artifactId>msgpack</artifactId>
  <version>0.6.12</version>
</dependency>

使用API進行編碼和解碼

List<String> nameList = new ArrayList<String>();
nameList.add("Tom");
nameList.add("Jack");
MessagePack messagePack = new MessagePack();
//開始序列化
byte[] raw = messagePack.write(nameList);
//使用MessagePack的模版,來接序列化后的字節數組轉換為List
List<String> deNameList = messagePack.read(raw,Templates.tList(Templates.TString));
System.out.println(deNameList.get(0));
System.out.println(deNameList.get(1));
System.out.println(deNameList.get(2));

Netty中如何使用MessagePack

編碼器的實現

public class MsgpackEncoder extends MessageToByteEncoder {

  @Override
  protected void encode(ChannelHandlerContext ctx, Object msg, ByteBuf out) throws Exception {
    MessagePack msgpack = new MessagePack();
    //使用MessagePack對要發送的數據進行序列化
    byte[] raw = msgpack.write(msg);
    out.writeBytes(raw);
    
  }

}

解碼器的實現

public class MsgpackDecoder extends MessageToMessageDecoder<ByteBuf> {

  @Override
  protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out) throws Exception {
    //從msg中獲取需要解碼的byte數組
    final int length = msg.readableBytes();
    byte[] b = new byte[length];
    msg.getBytes(msg.readerIndex(), b,0,length);
    //使用MessagePack的read方法將其反序列化成Object對象,并加入到解碼列表out中
    MessagePack msgpack = new MessagePack();
    out.add(msgpack.read(b));
  }

}

實現該編碼器和解碼器的Netty服務端

public class NettyServer {
  public void bind(int port) throws Exception {
    EventLoopGroup bossGruop = new NioEventLoopGroup();
    EventLoopGroup workGroup = new NioEventLoopGroup();
    ServerBootstrap bootstrap = new ServerBootstrap();
    bootstrap.group(bossGruop, workGroup)
        .channel(NioServerSocketChannel.class)
        .option(ChannelOption.SO_BACKLOG, 1024)
        .childHandler(new ChannelInitializer<SocketChannel>() {
          @Override
          protected void initChannel(SocketChannel socketChannel) throws Exception {
            // TODO Auto-generated method stub
            socketChannel.pipeline()
             //添加支持粘包、拆包解碼器,意義:從頭兩個字節解析出數據的長度,并且長度不超過1024個字節
            .addLast("frameDecoder",new LengthFieldBasedFrameDecoder(1024, 0, 2,0,2))
             //反序列化解碼器
            .addLast("msgpack decoder",new MsgpackDecoder())
             //添加支持粘包、拆包編碼器,發送的每個數據都在頭部增加兩個字節表消息長度
            .addLast("frameEncoder",new LengthFieldPrepender(2))
             //序列化編碼器
            .addLast("msgpack encoder",new MsgpackEncoder()
             //后續自己的業務邏輯
            .addLast(new ServerHandler());
          }
        });
    try {
      ChannelFuture future = bootstrap.bind(port).sync();
      future.channel().closeFuture().sync();
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      bossGruop.shutdownGracefully();
      workGroup.shutdownGracefully();
    }
  }
}  

實現該編碼器和解碼器的Netty客戶端

public class NettyClient {
  private void bind(int port, String host) {
    EventLoopGroup group = new NioEventLoopGroup();
    Bootstrap b = new Bootstrap();
    b.group(group)
        .channel(NioSocketChannel.class)
        .option(ChannelOption.TCP_NODELAY, true)
        .handler(new ChannelInitializer<SocketChannel>(){
          @Override
          protected void initChannel(SocketChannel socketChannel) throws Exception {
            // TODO Auto-generated method stub
            socketChannel.pipeline()
            .addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1024, 0, 2, 0, 2))
            .addLast("msgpack decoder", new MsgpackDecoder())
            .addLast("frameEncoder", new LengthFieldPrepender(2))
            .addLast("msgpack encoder", new MsgpackEncoder())
            .addLast(new ClientHandler());
          }
        });
    try {
      ChannelFuture f = b.connect(host, port).sync();
      f.channel().closeFuture().sync();
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      group.shutdownGracefully();
    }
  }
}

可以看出客戶端的代碼與服務端基本相同,所以啊,如果能熟練掌握Netty,今后在自己的項目中運用上定制化編解碼的傳輸,將會是一件十分簡單的活路。

總結

無論是之前解決粘包拆包問題,還是這里的使用序列化框架來進行編解碼。我相信讀者學習到這里,對于Netty的使用都有了較為全面的了解。其實Netty幫我們解決了很多底層棘手問題,如客戶端斷連、句柄泄漏和消息丟失等等。所以我們才能十分簡單開發出一個穩定的網絡通訊項目。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持創新互聯。

當前名稱:使用Netty進行編解碼的操作過程詳解
網站路徑:http://www.2m8n56k.cn/article36/poocpg.html

成都網站建設公司_創新互聯,為您提供移動網站建設商城網站App開發網站策劃網站排名定制開發

廣告

聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:[email protected]。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯

h5響應式網站建設
主站蜘蛛池模板: 9999视频| 5388国产亚洲欧美在线观看 | 丝袜紧身裙国产在线播放 | 亚洲毛片 | 亚洲色欧美 | 在线免费观看国产 | 欧美激情久久久久久久久 | 国产成人一区二区三区免费观看 | 亚洲国产精品一区二区三区久久 | 亚洲黄色美女视频 | 亚洲精品久 | 中文字幕精品视频在线 | 夜夜躁狠狠躁日日躁2021 | 美国三级毛片 | 女人a级毛片 | 日本黄色大片免费观看 | 美女又黄又免费的视频 | 亚洲男人的性天堂 | 国产成人一区二区三区 | 日韩福利视频精品专区 | 国产第一页在线观看 | 欧美超高清xoxoxoxo | 亚洲欧美一区二区三区在饯 | 三级手机在线观看 | 日本一本久道 | 欧美区一区二 | 亚洲成a人片在线观看 欧美 | 国产一级视频在线观看 | 夜夜躁狠狠躁日日躁2021 | 日韩精品午夜视频一区二区三区 | 午夜影院美女 | 欧美另类视频videosbest18 | 成年日韩片av在线网站 | 国产区二区 | 国内精品影院久久久久 | 久久精品国产福利 | 国产欧美va欧美va香蕉在线观 | 美女视频黄a全部 | 成人午夜性视频欧美成人 | 久草新视频 | 高清国产美女一级毛片 |