日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Netty详解(七):Netty 编解码以及消息头编解码器

發布時間:2025/4/16 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Netty详解(七):Netty 编解码以及消息头编解码器 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1. MessagePack 概述

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

MessagePacke優點

  • 編解碼高效,性能高
  • 序列化后的碼流小
  • 支持跨語言

1.1 MessagePack Java API 介紹

<dependencies>...<dependency><groupId>org.msgpack</groupId><artifactId>msgpack</artifactId><version>${msgpack.version}</version></dependency>... </dependencies>

1.2 API 官方示例:

import java.io.IOException; import java.util.ArrayList; import java.util.List;import org.msgpack.MessagePack; import org.msgpack.template.Templates;public class TestMessagePack {public static void main(String[] args) {// Create serialize objectsList<String> src=new ArrayList<String>();src.add("msgpack");src.add("kumofs");src.add("viver");MessagePack msgpack=new MessagePack();// Serializebyte[] raw;try {raw = msgpack.write(src);// Deserialize directly using a templateList<String> dst1 = msgpack.read(raw,Templates.tList(Templates.TString));System.out.println(dst1.get(0));System.out.println(dst1.get(1));System.out.println(dst1.get(2));} catch (IOException e) {e.printStackTrace();}}}

2. Netty 編碼器和解碼器開發

2.1 Netty編碼器

import org.msgpack.MessagePack;import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.MessageToByteEncoder;public class MsgpackEncoder extends MessageToByteEncoder<Object> {@Overrideprotected void encode(ChannelHandlerContext arg0, Object arg1, ByteBuf arg2) throws Exception {MessagePack msgpack=new MessagePack();byte[] raw=msgpack.write(arg1);arg2.writeBytes(raw);} }

Netty編碼繼承MessageToByteEncoder,它負責將Object類型的POJO對象編碼成byte數組,然后寫入到ByteBuffer中。

2.2 Netty解碼器

import java.util.List;import org.msgpack.MessagePack;import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.MessageToMessageDecoder;public class MsgPackDecoder extends MessageToMessageDecoder<ByteBuf> {@Overrideprotected void decode(ChannelHandlerContext arg0, ByteBuf arg1, List<Object> arg2) throws Exception {final byte[] array;final int length=arg1.readableBytes();array=new byte[length];arg1.getBytes(arg1.readerIndex(), array,0,length);MessagePack msgpack=new MessagePack();arg2.add(msgpack.read(array));}}

Netty解碼繼承MessageToMessageDecoder,他負責將ByteBuffer類型的數據解碼成Object對象。首先從數據報arg1中獲取需要解碼的byte數組,然后調用MessagePacke的read方法將其反序列化為Object對象,將解碼的對象加入到解碼列表arg2中,這樣就完成了MessagePack解碼工作。

3. 利用LengthFieldBasedFrameDecoder解決TCP粘包/拆包

對于TCP粘包 拆包問題來說,最常用的在消息頭中新增報文長度字段,然后利用該字段進行半包的編解碼。下面我們就利用Netty提供的LengthFieldBasedFrameDecoder和LengthFieldPrepender結合新開發的Netty編解碼器來實現對TCP粘包/拆包的支持。

EventLoopGroup group=new NioEventLoopGroup();try{Bootstrap b = new Bootstrap();b.group(group).channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY, true).option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 3000).handler(new ChannelInitializer<SocketChannel>(){@Overrideprotected void initChannel(SocketChannel ch) throws Exception {//LengthFieldBasedFrameDecoder用于處理半包消息//這樣后面的MsgpackDecoder接收的永遠是整包消息ch.pipeline().addLast("frameDecoder",new LengthFieldBasedFrameDecoder(65535,0,2,0,2));ch.pipeline().addLast("msgpack decoder",new MsgPackDecoder());//在ByteBuf之前增加2個字節的消息長度字段ch.pipeline().addLast("frameEncoder",new LengthFieldPrepender(2)); ch.pipeline().addLast("msgpack encoder",new MsgpackEncoder());ch.pipeline().addLast(new EchoClientHandler(sendNumber));}});ChannelFuture f= b.connect(host,port).sync();f.channel().closeFuture().sync();}

在MessagePack編碼器之前增加LengthFieldPrepender,它將在ByteBuffer之前增加2個字節的消息長度字段,其原理如下:

在MessagePack解碼器之前增加LengthFieldBasedFrameDecoder,用于處理半包消息,這樣后面的MsgpackDecoder接受到的永遠是整包消息。它的工作原理如下:

LengthFieldBasedFrameDecoder構造函數參數列表如下:

* @param maxFrameLength* the maximum length of the frame. If the length of the frame is* greater than this value, {@link TooLongFrameException} will be* thrown.* @param lengthFieldOffset* the offset of the length field* @param lengthFieldLength* the length of the length field* @param lengthAdjustment* the compensation value to add to the value of the length field* @param initialBytesToStrip* the number of first bytes to strip out from the decoded frame

總結

以上是生活随笔為你收集整理的Netty详解(七):Netty 编解码以及消息头编解码器的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。