netty 协议解析,netty编解码器

  netty 协议解析,netty编解码器

  无论使用Netty还是native Socket编程,都可以实现自定义的通信协议。

  所谓协议就是:客户端和服务器约定好每个二进制数据包中每个字节的含义的规则。

  有了规则,服务器和客户端可以通过这个设定的规则进行二进制和对象的转换。

  通信协议格式可以参考以下格式

  每个部分的描述如下

  幻数:用来标识这个数据包是否遵循我们设计的通信协议,类似于Java字节码开头的4个字节:0xcafebabe。

  版本ID:用于标识该协议是什么版本,用于后续协议的升级。

  序列化算法(Serialization algorithm):用于标识该协议的数据包使用什么序列化算法,如JSON、XML等。

  指令:用于标识在接收到数据后,应该对该数据使用什么处理逻辑。

  长度数据内容:不赘述。

  设置格式后,

  接下来,我们可以就双方的序列化方法达成一致。这里,我们可以以JSON序列化/反序列化为例。其他格式类似。

  Gson可以轻松地将JSON字符串和对象相互转换:

  私有静态最终Gson Gson=new Gson();

  //序列化

  public byte[]serialize(Object Object){

  返回gson.toJson(对象)。getBytes(UTF _ 8);

  }

  //反序列化

  public T T deserialize(Class T clazz,byte[] bytes) {

  返回gson.fromJson(new String(bytes,UTF_8),clazz);

  }实现了对象与字节数组的相互转换后,我们需要实现字节数组与Netty通信载体ByteBuf的相互转换,包括以下两种方法

  ByteBuf编码(数据包)上述编码方法需要做以下事情

  Allocate ByteBuf(分配一个内存区域,Netty会直接创建一个堆外内存)。根据协议获取数据包对应的内容,严格按照协议规定的字节数填入ByteBuf。包解码(ByteBuf byteBuf)以上解码方法主要做以下几件事。

  如果幻数的验证版本号严格按照规范中传输的ByteBuf,则上述两步验证必须通过,可以直接跳过。获取序列化算法、指令和包长度,并将数据内容转换为字节数组,将字节数组转换为对应的包对象。因为不同数据包的内容不一样,所以要建立一个抽象类,每个子类可以实现具体数据包的内容。

  包协议;

  进口龙目岛。数据;

  /**

  *数据包抽象类

  *

  * @ author a href= mailto:410486047 @ QQ . com Grey/a

  * @日期2022/9/15

  * @自从

  */

  @数据

  公共抽象类数据包{

  /**

  *协议版本

  */

  私有字节版本=1;

  /**

  *指令,由子类实现

  *

  * @返回

  */

  公共抽象字节get command();

  }对于一个特定的操作,比如登录操作,它需要的数据包需要继承和实现这个抽象类的抽象方法。

  包协议;

  进口龙目岛。数据;

  导入静态协议。Command . LOGIN _ REQUEST

  /**

  * @ author a href= mailto:410486047 @ QQ . com Grey/a

  * @日期2022/9/15

  * @自从

  */

  @数据

  公共类LoginRequestPacket扩展数据包{

  //登录操作需要的数据内容包括以下三项

  私有整数userId

  私有字符串用户名;

  私有字符串密码;

  @覆盖

  公共字节getCommand() {

  返回LOGIN _ REQUEST

  }

  }对于调用者来说,他们只需要使用LoginRequestPacket,而不需要关注它的底层编码和解码工作。伪代码如下

  func() {

  LoginRequestPacket LoginRequestPacket=new LoginRequestPacket();

  loginrequestpacket . set version((byte)1));

  loginrequestpacket . set userid(123);

  loginRequestPacket.setUsername(张三);

  loginrequestpacket . set password( password );

  //编码

  ByteBuf byteBuf=封装的编解码器工具类。编码(loginRequestPacket);

  //解码

  Packet decodedPacket=封装的编解码器工具类。解码(byte buf);

  //序列化成我们需要的对象

  以及序列化和反序列化工具类。序列化(decoded packet);

  }

  版权归作者所有:原创作品来自博主小二上九8,转载请联系作者取得转载授权,否则将追究法律责任。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: