網絡編程-編碼與解碼(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>() {@Overrideprotected 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>() {@Overrideprotected 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 {@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {ByteBuf buf=(ByteBuf) msg;System.out.println("client msg:"+buf.toString(CharsetUtil.UTF_8));}@Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception {BookMessage.Book book =BookMessage.Book.newBuilder().setId(1).setName("beyound").build();ctx.writeAndFlush(book);}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {ctx.close();}
}
public class NettyServerHandler extends ChannelInboundHandlerAdapter {@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {BookMessage.Book book=(BookMessage.Book)msg;System.out.println("receive book msg:"+ book.getName());}@Overridepublic void channelReadComplete(ChannelHandlerContext ctx) throws Exception {ctx.writeAndFlush(Unpooled.copiedBuffer("response", Charset.defaultCharset()));}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {ctx.close();}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/714609.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/714609.shtml
英文地址,請注明出處:http://en.pswp.cn/news/714609.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Python 實現海康機器人工業相機 MV-CS050-10GC 的實時顯示視頻流及拍照功能(實時顯示視頻流同時可以進行拍照)

參考鏈接&#xff1a; https://www.cnblogs.com/HanYork/p/17388506.html https://www.cnblogs.com/miracle-luna/p/16960556.html#5138211 Flask搭建流媒體服務器&#xff1a;使用Flask搭建一個流媒體服務器_multipart/x-mixed-replace; boundaryframe-CSDN博客

公共字段自動填充

在開發中經常面臨對于一些公共字段的賦值。 如在下表中&#xff1a; 如何讓程序自動為我們需要賦值的公共字段進行賦值&#xff0c;避免在業務代碼中重復寫這些公共字段的賦值代碼 如下圖所示&#xff1a; 實現思路&#xff1a; 1.自定義注解AutoFill&#xff0c;用于標識需…

linux環境安裝cuda toolkit

1 全新安裝 如果環境中沒安裝過cuda版本&#xff0c; 這種情況下比較簡單。 直接在https://developer.nvidia.com/cuda-toolkit-archive選擇對應版本下載安裝即可。 如下為安裝cuda toolkit 11.8. 2 環境中已經存在其他版本 這種情況下比較復雜一些。 首先要確認最高支持的…

李沐動手學習深度學習——4.2練習

1. 在所有其他參數保持不變的情況下&#xff0c;更改超參數num_hiddens的值&#xff0c;并查看此超參數的變化對結果有何影響。確定此超參數的最佳值。 通過改變隱藏層的數量&#xff0c;導致就是函數擬合復雜度下降&#xff0c;隱藏層過多可能導致過擬合&#xff0c;而過少導…

Git多人合作的推送流程

多人合作時&#xff0c;使用Git進行代碼推動&#xff08;push&#xff09;需要一定的協調和規范&#xff0c;以確保代碼庫的整體健康。以下是一個常見的多人合作時的Git代碼推動流程&#xff1a; 同步主分支&#xff1a; 在推送之前&#xff0c;確保你的本地主分支&#xff08;…

【Java】四大函數式接口

消費型接口Consumer 消費型接口接收一個輸入&#xff0c;沒有返回值 在stream流計算中 forEach() 接收一個消費型接口Consumer用于 遍歷元素 /*** 消費型接口* 接收一個輸入&#xff0c;沒有返回值*/ public class demo01 {public static void main(String[] args) {//TODO 消…

【MySQL】表的內連和外連(重點)

表的連接分為內連和外連。 一、內連接 內連接實際上就是利用 where 子句對兩種表形成的笛卡兒積進行篩選&#xff0c;前面學習的查詢都是內連接&#xff0c;也是在開發過程中使用的最多的連接查詢。 select 字段 from 表1 inner join 表2 on 連接條件 and 其他條件; 注意&…

【數倉】Hadoop集群配置常用參數說明

Hadoop集群中&#xff0c;需要配置的文件主要包括四個 配置核心Hadoop參數&#xff1a; 編輯core-site.xml文件&#xff0c;設置Hadoop集群的基本參數&#xff0c;如文件系統、Hadoop臨時目錄等。 配置HDFS參數&#xff1a; 編輯hdfs-site.xml文件&#xff0c;設置HDFS的相關參…

策略開發:EMA如何計算

EMA的計算原理 EMA 是MA&#xff08;平滑移動平均線&#xff09;的另一種形式。全名“加權指數移動平均線”。 2/13就是12日移動平均線的平滑因子&#xff0c;他的意思是指&#xff1a;給予新價格 2/13的權重&#xff0c;給予過去的EMA 11/13的權重。 在計算的時候第一天的M…

Linux使用基礎命令

1.常用系統工作命令 (1).用echo命令查看SHELL變量的值 qiangziqiangzi-virtual-machine:~$ echo $SHELL /bin/bash(2).查看本機主機名 qiangziqiangzi-virtual-machine:~$ echo $HOSTNAME qiangzi-virtual-machine (3).date命令用于顯示/設置系統的時間或日期 qiangziqian…

Linux多線程服務端編程:使用muduo C++網絡庫 學習筆記 附錄B 從《C++ Primer(第4版)》入手學習C++

這是作者為《C Primer&#xff08;第4版&#xff09;&#xff08;評注版&#xff09;》寫的序言&#xff0c;文中“本書”指的是這本書評注版。 B.1 為什么要學習C 2009年本書作者Stanley Lippman先生應邀來華參加上海祝成科技舉辦的C技術大會&#xff0c;他表示人們現在還用…

MySQL存儲過程和Function

一、存儲過程 MySQL中提供存儲過程和存儲函數機制&#xff0c;將其統稱為存儲程序。 SQL語句要先編譯&#xff0c;然后執行&#xff0c;存儲程序是一組為了完成特定功能的SQL語句&#xff0c;編譯后存到數據庫中。 用戶通過指定存儲程序的名字并給定參數來調用才會執行。 存…

擴展學習|大數據分析的現狀和分類

文獻來源&#xff1a;[1] Mohamed A , Najafabadi M K , Wah Y B ,et al.The state of the art and taxonomy of big data analytics: view from new big data framework[J].Artificial Intelligence Review: An International Science and Engineering Journal, 2020(2):53. 下…

藍橋杯(3.2)

1209. 帶分數 import java.io.*;public class Main {static BufferedReader br new BufferedReader(new InputStreamReader(System.in));static PrintWriter pw new PrintWriter(new OutputStreamWriter(System.out));static final int N 10;static int n, cnt;static int[…

LabVIEW流量控制系統

LabVIEW流量控制系統 為響應水下航行體操縱舵翼環量控制技術的試驗研究需求&#xff0c;通過LabVIEW開發了一套小量程流量控制系統。該系統能夠滿足特定流量控制范圍及精度要求&#xff0c;展現了其在實驗研究中的經濟性、可靠性和實用性&#xff0c;具有良好的推廣價值。 項…

tritonserver學習之八:redis_caches實踐

tritonserver學習之一&#xff1a;triton使用流程 tritonserver學習之二&#xff1a;tritonserver編譯 tritonserver學習之三&#xff1a;tritonserver運行流程 tritonserver學習之四&#xff1a;命令行解析 tritonserver學習之五&#xff1a;backend實現機制 tritonserv…

【C++初階】內存管理

目錄 一.C語言中的動態內存管理方式 二.C中的內存管理方式 1.new/delete操作內置類型 2.new和delete操作自定義類型 3.淺識拋異常 &#xff08;內存申請失敗&#xff09; 4.new和delete操作自定義類型 三.new和delete的實現原理 1.內置類型 2.自定義類型 一.C語…

C++學習筆記:二叉搜索樹

二叉搜索樹 什么是二叉搜索樹?搜索二叉樹的操作查找插入刪除 二叉搜索樹的應用二叉搜索樹的代碼實現K模型:KV模型 二叉搜索樹的性能怎么樣? 什么是二叉搜索樹? 二叉搜索樹又稱二叉排序樹&#xff0c;它或者是一棵空樹&#xff0c;或者是具有以下性質的二叉樹: 若它的左子樹…

Linux安裝Nginx詳細步驟

1、創建兩臺虛擬機&#xff0c;分別為主機和從機&#xff0c;區別兩臺虛擬機的IP地址 2、將Nginx素材內容上傳到/usr/local目錄&#xff08;pcre,zlib,openssl,nginx&#xff09; 附件 3、安裝pcre庫   3.1 cd到/usr/local目錄 3.2 tar -zxvf pcre-8.36.tar.gz 解壓 3.3 cd…

MATLAB圖像噪聲添加與濾波

在 MATLAB 中添加圖像噪聲和進行濾波通常使用以下函數&#xff1a; 添加噪聲&#xff1a;可以使用imnoise函數向圖像添加各種類型的噪聲&#xff0c;如高斯噪聲、椒鹽噪聲等。 濾波&#xff1a;可以使用各種濾波器對圖像進行濾波處理&#xff0c;例如中值濾波、高斯濾波等。 …