网络编程-编码与解码(Protobuf)

编码与解码

下面的文字都来自于极客时间
为什么要编解码呢?因为计算机数据传输的是二进制的字节数据
解码:字节数据 --> 字符串(字符数据)
编码:字符串(字符数据)–> 字节数据

我们在编写网络应用程序的时候需要注意 codec (编解码器),因为数据在网络中传输的都是二进制字节
码数据,而我们拿到的目标数据往往不是字节码数据。因此在发送数据时就 需要编码,接收数据时就需
要解码。
codec 的组成部分有两个:decoder(解码器)和 encoder(编码器)。

  • encoder 负责把业务数据转换成字节码数据
  • decoder 负责把字节码数据转换成业务数据
    其实 Java 的序列化技术就可以作为 codec 去使用,但是它的硬伤太多:
  1. 无法跨语言,这应该是 Java 序列化最致命的问题了
  2. 序列化后的体积太大,是二进制编码的 5 倍多
  3. 序列化性能太低

Netty 自身提供了一些 编解码器,如下:

  • StringEncoder对字符串数据进行编码
  • ObjectEncoder对 Java 对象进行编码

Netty 本身自带的 ObjectDecoder 和 ObjectEncoder 可以用来实现 POJO 对象或各种业务对象的编码和解码,但其内部使用的仍是 Java 序列化技术,所以在某些场景下不适用。对于 POJO 对象或各种业务对象要实现编码和解码,我们需要更高效更强的技术。由此引出:Google 的 Protobuf。

Google 的 Protobuf

Protobuf 是 Google 发布的开源项目,全称 Google Protocol Buffers,特点如下:支持跨平台、多语言(支持目前大多数语言,例如 C++、C#、Java、python 等)高性能,高可靠性。
使用 protobuf 编译器能自动生成代码,Protobuf 是将类的定义使用.proto 文件进行描述,然后通过 protoc.exe 编译器根据.proto 自动成.java 文件在使用 Netty 开发时,经常会结合 Protobuf 作为 codec (编解码器)去使用,具体用法如下所示。
使用步骤:

  1. 第一步:将传递数据的实体类生成【基于构建者模式设计】
  2. 第二步:配置编解码器
  3. 第三步:传递数据使用生成后的实体类

使用案例

1 引入依赖

<dependency>
   <groupId>com.google.protobuf</groupId>
   <artifactId>protobuf-java</artifactId>
   <version>3.21.11</version>
</dependency>

定义protoc文件,是生成具体类的描述:
语法规则:https://www.topgoer.com/%E5%BE%AE%E6%9C%8D%E5%8A%A1/Protobuf%E8%AF%AD%E6%B3%95.html

syntax = "proto3";
option java_outer_classname = "BookMessageDB";
message Book{
int32 id = 1;
string name = 2;
}

2 安装插件
在这里插入图片描述
GenProtobuf是生产插件。Protobuf是一定要安装的。
配置GenProtobuf:
在这里插入图片描述
做如下配置:
在这里插入图片描述

特别注意:这个版本要和你引入的依赖版本一致,否则会出先有些方法或类找不到报红的情况
在这里插入图片描述

public class AIOServer {
    public static void main(String[] args) throws InterruptedException {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workGroup = new NioEventLoopGroup();
        ServerBootstrap b = new ServerBootstrap();
        b.group(bossGroup, workGroup)
                .channel(NioServerSocketChannel.class)
                .option(ChannelOption.SO_BACKLOG, 128)
                .childOption(ChannelOption.SO_KEEPALIVE, true)
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        // 解码
                        ch.pipeline().addLast("decoder", new ProtobufDecoder(BookMessage.Book.getDefaultInstance()));
                        ch.pipeline().addLast(new NettyServerHandler());
                    }
                });
        System.out.println("============服务器启动");
        b.bind(9999).sync();

//        bossGroup.shutdownGracefully();
//        workGroup.shutdownGracefully();
    }
}
public class AIOClient {
    public static void main(String[] args) throws InterruptedException {
        NioEventLoopGroup group = new NioEventLoopGroup();
        Bootstrap bootstrap = new Bootstrap();
        bootstrap.group(group)
                .channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        // 设置编码器
                        ch.pipeline().addLast("encoder", new ProtobufEncoder());
                        ch.pipeline().addLast(new NettyClientHandler());
                    }
                });
        System.out.println();
        ChannelFuture connect = bootstrap.connect(new InetSocketAddress(9999));
        connect.channel().closeFuture().sync();
    }
}
public class NettyClientHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf buf=(ByteBuf) msg;
        System.out.println("client msg:"+buf.toString(CharsetUtil.UTF_8));
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        BookMessage.Book book =
                BookMessage.Book.newBuilder().setId(1).setName("beyound").build();
        ctx.writeAndFlush(book);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.close();
    }
}
public class NettyServerHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        BookMessage.Book book=(BookMessage.Book)msg;
        System.out.println("receive book msg:"+ book.getName());
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
       ctx.writeAndFlush(Unpooled.copiedBuffer("response", Charset.defaultCharset()));
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.close();
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/410585.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

(二十三)Flask之高频面试点

目录&#xff1a; 每篇前言&#xff1a;Q1&#xff1a;为什么把request和session放在一起&#xff1f;Q2&#xff1a;Local对象的作用&#xff1f;Q3:&#xff1a;LocalStack对象的作用&#xff1f;Q4&#xff1a;一个运行中的Flask应用程序分别包括几个Local/LocalStack&#…

能为企业节省巨额成本的稳定性测试!你确定不来看看吗?

首先来说说性能测试&#xff1a; 性能是软件的一种非功能特性&#xff0c;他关注的不是软件是否完成了特定的功能&#xff0c;而是软件在完成特定功能是展示出来的及时性。 及时性从不同的视角代表不同的指标&#xff1a; 用户&#xff1a;响应时间 系统管理员&#xff1a;资…

20240223-2092.查找所有有秘密的人

题目要求 给你一个整数 n&#xff0c;表示有 n 个人&#xff0c;编号从 0 到 n - 1。你还给你一个 0 索引的二维整数数组 meetings&#xff0c;其中 meetings[i] [xi, yi, timei] 表示 xi 和 yi 在 timei 有一个会议。一个人可以同时参加多个会议。最后&#xff0c;给你一个整…

用Python Matplotlib画图导致paper中含有Type-3字体,如何解决?

用Python Matplotlib画图导致paper中含有Type-3字体&#xff0c;如何解决&#xff1f; 在提交ACM或者IEEE论文之前&#xff0c;都会有格式的检查&#xff0c;格式的其中一个要求是paper中不能含有Type-3的字体。因为Type-1和True Type字体都是矢量字体&#xff0c;而Type-3并不…

工控网关在智能制造领域的应用与实践-天拓四方

随着工业4.0和智能制造的深入推进&#xff0c;工控系统作为连接管理层与执行层的关键纽带&#xff0c;其智能化、网络化水平日益成为衡量企业现代化程度的重要标志。工控网关作为实现工控系统内外信息交互的“智能桥梁”&#xff0c;在提升工业控制网络的连通性、安全性和智能化…

第3集《灵峰宗论导读》

《灵峰宗论》导读。诸位法师&#xff0c;诸位同学&#xff0c;阿弥陀佛&#xff01;&#xff08;阿弥陀佛&#xff01;&#xff09; 请大家打开讲义第5面&#xff0c;悟道。 这一科我们是说明论主略史&#xff0c;在这一科当中&#xff0c;我们根据弘一大师所编的《蕅益大师年…

【Linux运维系列】vim操作

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

【C++ QT项目5】——基于HTTP与JSON数据流的天气预报界面设计

【C QT项目5】——基于HTTP与JSON数据流的天气预报界面设计 一、项目概述二、UI设计与stylesheet样式表三、天气预报数据接口四、JSON数据4.1 概述4.2 QT生成JSON数据4.3 QT解析JSON数据4.4 将JSON数据解析到QMap中 五、软件开发网络通信架构5.1 BS架构/CS架构5.2 HTTP基本概念…

Vi/Vim 使用小窍门,如何消除搜索后的关键字高亮

Vim/Vi 基本上是 *nix 世界最受欢迎的编辑器了&#xff0c;不知道为什么&#xff0c;一直以来觉得和 Emacs 比起来&#xff0c;Vim 更加有亲和力。用起来很舒服。 今天就记录一个困扰了我很久的问题。 大家应该都知道&#xff0c;在 Vi 里面如果要搜索某个关键字&#xff0c;…

2024国际生物发酵展览会不容错过-欧瑞安电气

参展企业介绍 山东欧瑞安电气有限公司成立于2013年&#xff0c;坐落于泰山脚下的泰安国家高新区&#xff0c;是国家高新技术企业、国家专精特新“小巨人”企业、中国产学研合作创新示范企业、山东省“隐形冠军”企业、山东省技术创新示范企业、山东省高端品牌培育企业、山东省…

Mac使用K6工具压测WebSocket

commend空格 打开终端&#xff0c;安装k6 brew install k6验证是否安装成功 k6 version设置日志级别为debug export K6_LOG_LEVELdebug执行脚本&#xff08;进入脚本所在文件夹下&#xff09; k6 run --vus 100 --duration 10m --out csvresult.csv script.js 脚本解释&…

免费分享一套SpringBoot+Vue实验室(预约)管理系统,帅呆了~~

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的SpringBootVue实验室(预约)管理系统 &#xff0c;分享下哈。 项目视频演示 【免费】SpringBootVue实验室(预约)管理系统 Java毕业设计_哔哩哔哩_bilibili【免费】SpringBootVue实验室(预约)管理系统 Java毕…

【深度学习笔记】3_11 模型选择、欠拟合和过拟合

注&#xff1a;本文为《动手学深度学习》开源内容&#xff0c;做了部分个人理解标注&#xff0c;仅为个人学习记录&#xff0c;无抄袭搬运意图 3.11 模型选择、欠拟合和过拟合 在前几节基于Fashion-MNIST数据集的实验中&#xff0c;我们评价了机器学习模型在训练数据集和测试数…

【前端】nginx 反向代理,实现跨域问题

前面讲跨域的问题&#xff0c;这篇 C# webapi 文章里面已经说过了。在上述文章中是属于从服务器端去允许访问的策略去解决跨域问题。而这里是从客户端的角度利用反向代理的方法去解决跨域问题。 反向代理&#xff1a;其原理就是将请求都接收到一个中间件&#xff08;中间地址&a…

【SRE系列之Jenkins的使用】--实现ssh和http克隆

1、Jenkins的概念 1.1Jenkins的介绍 Jenkins是一个独立的开源软件项目&#xff0c;是基于Java开发的一种CI&#xff08;Continuous integration&#xff0c;持续集成&#xff09; &CD (Continuous Delivery&#xff0c;持续交付)工具&#xff0c;用于监控持续重复的工作&a…

深入浅出JVM(十二)之垃圾回收算法

上篇文章深入浅出JVM&#xff08;十一&#xff09;之如何判断对象“已死”已经深入浅出的解析JVM是如何评判对象不再使用&#xff0c;不再使用的对象将变成“垃圾”&#xff0c;等待回收 垃圾回收算法有多种&#xff0c;适用于不同的场景&#xff0c;不同的垃圾收集器使用不同…

Matlab自学笔记二十七:详解格式化文本sprintf各参数设置方法

1.一个程序引例 上篇文章已经介绍了格式化文本的初步应用&#xff0c;程序示例如下&#xff1a; sprintf(|%f\n|%.2f\n|%8.2f,pi*ones(1,3)) 2.格式化操作符各字段的含义解析 格式化操作符可以有六个字段&#xff0c;只有主字符%和转换格式是必需的&#xff0c;其他都是可选…

DWT硬件延时

DWT硬件延时 文章目录 DWT硬件延时软件&硬件延时方案软件延时硬件延时方案 DWT硬件延时方案DWT硬件延时方案DEMCR寄存器DWT硬件延时方案实现延时初始化&#xff1a;US延时&#xff1a;MS延时&#xff1a; 软件&硬件延时方案 软件延时 static void Delay(uint32_t cou…

Sora抢饭碗!好莱坞大亨停止8亿美元投资

好莱坞消息&#xff0c;著名演员、影视投资人Tyler Perry在看到OpenAI最新发布的文生视频模型Sora后&#xff0c;停止了8亿&#xff08;约57亿元&#xff09;美元的投资。 该投资项目位于亚特兰大&#xff0c;本来要扩展十几个摄影棚用于影视剧的拍摄&#xff08;类似横店影视…

企业微信主体怎么转让给别人?

企业微信变更主体有什么作用&#xff1f;当我们的企业因为各种原因需要注销或已经注销&#xff0c;或者运营变更等情况&#xff0c;企业微信无法继续使用原主体继续使用时&#xff0c;可以申请企业主体变更&#xff0c;变更为新的主体。企业微信变更主体的条件有哪些&#xff1…