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

news2024/11/19 10:19:40

编码与解码

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

我们在编写网络应用程序的时候需要注意 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();
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

车载测试-常用adb命令和使用场景

app安装&#xff1a; 最常用 adb install apk地址 应用安装&#xff0c;常用于直接在系统上安装新包用于测试验证bug 常用参数&#xff08;一般直接使用这三个参数一起&#xff09; -t 允许测试包 -r 替换已存在的应用程序&#xff0c;也就是说强制安装 -d 允许进行将见状…

【.NET Core】深入理解IO之File类

【.NET Core】深入理解IO之File类 文章目录 【.NET Core】深入理解IO之File类一、概述二、File类2.1 File.AppendAllLines方法2.2 File.AppendAllText方法2.3 File.Copy 方法2.4 File.Create 方法2.5 File.Decrypt(String) 方法2.6 File.Delete(String) 方法2.7 File.Move 方法…

基于Python网络爬虫的IT招聘就业岗位数据分析可视化推荐系统

文章目录 基于Python网络爬虫的IT招聘就业岗位数据分析可视化推荐系统项目概述招聘岗位数据爬虫分析系统展示用户注册登录系统首页IT招聘数据开发岗-javaIT招聘数据开发岗-PythonIT招聘数据开发岗-AndroidIT招聘数据开发岗-其它招聘岗位数据分析算法方面运维方面测试方面招聘岗…

C语言 变量

变量其实只不过是程序可操作的存储区的名称。C 中每个变量都有特定的类型&#xff0c;类型决定了变量存储的大小和布局&#xff0c;该范围内的值都可以存储在内存中&#xff0c;运算符可应用于变量上。 变量的名称可以由字母、数字和下划线字符组成。它必须以字母或下划线开头…

Python入门到精通(九)——Python数据可视化

Python数据可视化 一、JSON数据格式 1、定义 2、python数据和JSON数据转换 二、pyecharts 三、折线图 四、地图 五、动态柱状图 一、JSON数据格式 1、定义 JSON是一种轻量级的数据交互格式。可以按照JSON指定的格式去组织和封装数据JSON本质上是一个带有特定格式的字符…

python|闲谈2048小游戏和数组的旋转及翻转和转置

目录 2048 生成数组 n阶方阵 方阵旋转 顺时针旋转 逆时针旋转 mxn矩阵 矩阵旋转 测试代码 测试结果 翻转和转置 2048 《2048》是一款比较流行​的数字游戏​&#xff0c;最早于2014年3月20日发行。原版2048由Gabriele Cirulli首先在GitHub上发布&#xff0c;后被移…

LeetCode142. 环形链表 II刷题详解

今天力扣刷到了一个特别有意思的题目&#xff0c;于是就写了下面的题解来加深以下理解。 142. 环形链表 II - 力扣&#xff08;LeetCode&#xff09; 这个可以分为两大步去写&#xff0c;首先要判断链表是否有环&#xff0c;然后如果有环就去找到环的入口&#xff0c;没有环返…

11 PLL IP核

PLL IP 核简介 锁相环&#xff08;PLL&#xff09;作为一种反馈控制电路&#xff0c;其特点是利用外部输入的参考信号来控制环路内部震荡信号的频率和相位。因为锁相环可以实现输出信号频率对输入信号频率的自动跟踪&#xff0c;所以锁相环通常用于闭环跟踪电路。锁相环在工作…

一文读懂压敏电阻原理,参数,选型

大家好&#xff0c;我是砖一。 压敏电阻并不是一般的电阻&#xff0c;而是一种具有瞬态电压抑制功能的元件&#xff0c;效果同TVS。 这篇文章介绍压敏电阻的一些基本知识&#xff0c;包括参数、选型、应用等。 一&#xff0c;基础知识 压敏电阻用MY表示&#xff0c;MY后…

东方博宜 1078. 求恰好使s=1+1/2+1/3+…+1/n的值大于X时n的值

东方博宜 1078. 求恰好使s11/21/3…1/n的值大于X时n的值 #include<iostream> using namespace std; int main() {int x ;cin >> x ;double s 0 ;int i 1 ;bool m true ;while(m){s 1.0/i ;if(s>x)break;i ;}cout << i ;return 0 ; }

【C++那些事儿】深入理解C++类与对象:从概念到实践(上)| 揭开this指针的神秘面纱

&#x1f4f7; 江池俊&#xff1a; 个人主页 &#x1f525;个人专栏&#xff1a; ✅数据结构冒险记 ✅C那些事儿 &#x1f305; 有航道的人&#xff0c;再渺小也不会迷途。 文章目录 1. 面向过程和面向对象初步认识2.类的引入3.类的定义4.类的访问限定符及封装4.1 访问限定符…

SpringBoot案例(黑马学习笔记)

这个案例呢&#xff0c;就是Tlias智能学习辅助系统。 参考接口文档完成后端功能的开 发&#xff0c;然后结合前端工程进行联调测试即可。 完成后的成品效果展示&#xff1a; 准备工作 需求&环境搭建 需求说明 部门管理 部门管理功能开发包括&#xff1a; ● 查询部门列…

C++ 高频考点

1. C/C内存有哪几种类型&#xff1f; C中&#xff0c;内存分为5个区&#xff1a;堆(malloc)、栈(如局部变量、函数参数)、程序代码区&#xff08;存放二进制代码&#xff09;、全局/静态存储区&#xff08;全局变量、static变量&#xff09;和常量存储区&#xff08;常量&…

Linux如何磁盘分区2

gdisk GPT 128个分区 注意&#xff1a;转换格式时保证此分区没有被系统占用 parted -s /dev/sdc mklabel gpt #将/dev/sdc(MBR格式)转换成(GPT格式) parted -s /dev/sdc mklabel msdos #将/dev/sda(GPT格式)转换成(MBR格式) 1.创建分区 yum -y install gdisk #安装分…

Postman越来越难用了

今天看到有个哥们吐槽postman的新版界面&#xff0c;这位是Spotify的资深工程师&#xff0c;所以他的槽点还是有些代表性&#xff0c;他是这么说的 Uhhhh what happened to Postman? I just want to send, and inspect http requests? What is all this shit? Adam Rackis S…

【黑马程序员】3、TypeScript常用类型_黑马程序员前端TypeScript教程,TypeScript零基础入门到实战全套教程

课程地址&#xff1a;【黑马程序员前端TypeScript教程&#xff0c;TypeScript零基础入门到实战全套教程】 https://www.bilibili.com/video/BV14Z4y1u7pi/?share_sourcecopy_web&vd_sourceb1cb921b73fe3808550eaf2224d1c155 目录 3、TypeScript常用类型 3.1 类型注解 …

SD-WAN技术:优化国内外服务器访问的关键

在全球化的商业环境中&#xff0c;企业经常需要在国内访问国外的服务器。然而&#xff0c;由于地理位置和网络架构的限制&#xff0c;这种跨国访问往往会遇到速度慢、延迟高等问题。SD-WAN&#xff08;软件定义广域网&#xff09;技术的兴起&#xff0c;为企业提供了一种新的解…

kotlin与java的相互转换

Kotlin转java 将kotlin代码反编译成java Tools -> Kotlin -> Show Kotlin Bytecode 然后点击 【Decompile】 生成java代码 java转kotlin Code -> Convert Java File To Kotlin File

代码随想录算法训练营第二十七天| 39. 组合总和、40.组合总和II、131.分割回文串

文章目录 1.组合总和2.组合总和II3.分割回文串 1.组合总和 参数和返回值&#xff1a; vector<vector<int>> result; vector<int> path; int sum; void backtracking(vector<int>& candidates, int target, int index)终止条件&#xff1a;大于等于…

小白水平理解面试经典题目leetcode. 606 Construct String from Binary Tree【递归算法】

Leetcode 606. 从二叉树构造字符串 题目描述 例子 小白做题 坐在自习室正在准备刷题的小白看到这道题&#xff0c;想想自己那可是没少和白月光做题呢&#xff0c;也不知道小美刷题刷到哪里了&#xff0c;这题怎么还没来问我&#xff0c;难道是王谦谦去做题了&#xff1f; 这…