JSON-RPC-CXX深度解析:C++中的远程调用利器

一、引言

1. JSON-RPC 简介及其在 C++ 开发中的重要性

JSON-RPC(JavaScript Object Notation - Remote Procedure Call)是一种基于 JSON 格式的远程过程调用协议。在 C++ 开发中,它扮演着至关重要的角色。随着软件系统的日益复杂和分布式架构的广泛应用,高效的远程过程调用成为构建强大应用程序的关键。JSON-RPC 以其简洁的 JSON 数据格式,使得不同的系统之间可以轻松地进行通信,而无需关心底层的网络细节和数据传输方式。

在 C++ 开发中,JSON-RPC 为开发者提供了一种跨平台、高效且灵活的远程调用解决方案。它允许 C++ 程序与其他语言编写的程序进行无缝交互,促进了多语言环境下的软件开发。同时,JSON-RPC 的轻量级特性使其在资源受限的环境中也能表现出色,适用于各种类型的 C++ 项目,从嵌入式系统到高性能服务器应用。

2. 引入 json-rpc-cxx 库的独特价值

json-rpc-cxx 库作为一个开源的 C++ 实现,为 C++ 开发者带来了诸多独特价值。首先,它严格遵循 JSON-RPC 协议,确保了与其他符合该协议的系统的兼容性。该库提供了丰富的功能,方便地定义可远程调用的函数,处理客户端和服务器之间的 JSON 数据序列化和反序列化,以及支持多种网络传输方式或可与其他网络库集成。

json-rpc-cxx 库的跨平台兼容性也是其一大优势。无论是在 Windows、Linux 还是 OSX 上,都能无缝运行,为开发者提供了极大的便利。此外,它利用了流行的 nlohmann::json 库,确保了数据处理的高效性和便捷性。同时,该库的设计充分考虑了类型安全和编译时错误检查,减少了运行时问题,提升了开发效率。

  • json-rpc-cxx 开源库链接

二、JSON-RPC-CXX 库概述

1. 严格遵循 JSON-RPC 协议,实现跨网络通信

json-rpc-cxx 库严格遵循 JSON-RPC 2.0 规范,确保了在不同的网络环境下,客户端和服务器能够进行稳定且高效的通信。通过使用 JSON 格式作为数据交换格式,它克服了不同编程语言和系统之间的差异,使得跨网络通信变得轻而易举。

JSON-RPC 协议定义了一种简洁而有效的方式来进行远程过程调用。在 json-rpc-cxx 库的实现中,客户端可以通过发送包含方法名和参数的 JSON 请求,向服务器发起远程调用。服务器接收到请求后,解析 JSON 数据,执行相应的方法,并将结果以 JSON 格式返回给客户端。这种方式不仅使得通信过程清晰明了,而且易于理解和调试。

2. 丰富功能列举

  • 方便定义远程调用函数:json-rpc-cxx 库提供了简洁的接口,使得开发者可以轻松地定义可远程调用的函数。通过继承 jsonrpccxx::JsonRpcServer 类,并使用 BindMethod 函数,开发者可以将 C++ 的函数绑定为远程可调用的方法。例如,可以像这样定义一个加法函数:BindMethod("add", [](int num1, int num2) { return num1 + num2; });。这种方式使得 C++ 程序中的函数可以被其他系统通过网络远程调用,极大地提高了程序的可扩展性和灵活性。
  • 处理 JSON 数据序列化反序列化:该库利用流行的 nlohmann::json 库,高效地处理 JSON 数据的序列化和反序列化。在客户端和服务器之间进行通信时,需要将数据转换为 JSON 格式进行传输。json-rpc-cxx 库能够自动地将 C++ 的数据类型转换为 JSON 格式,并在接收到 JSON 数据时,将其反序列化为 C++ 的数据类型。这样,开发者无需手动处理数据的转换过程,大大提高了开发效率。
  • 支持多种网络传输方式:json-rpc-cxx 库具有很强的灵活性,支持多种网络传输方式。它可以与不同的网络库集成,如 HTTP、WebSocket 等。这使得开发者可以根据具体的应用场景选择最适合的网络传输方式。例如,在需要实时通信的场景下,可以选择 WebSocket 传输方式;而在传统的基于请求 - 响应的场景下,HTTP 可能是更好的选择。这种灵活性使得 json-rpc-cxx 库能够适应各种不同的网络环境和应用需求。

三、服务器端应用

在构建基于json-rpc-cxx库的服务器端应用时,我们需要关注几个关键步骤:创建服务器、定义服务方法以及启动服务器。下面将详细介绍这些步骤。

(一)创建服务器

包含必要头文件及作用介绍

在服务器端代码中,包含的头文件如jsonrpccxx/server.hjsonrpccxx/server_connector.h起着至关重要的作用。

  • jsonrpccxx/server.h:提供了创建服务器的类和相关函数,使我们能够构建一个JSON-RPC服务器实例,以监听客户端的请求并进行相应的处理。
  • jsonrpccxx/server_connector.h:提供了服务器连接相关的类和函数,用于实现服务器与客户端之间的连接管理。

以HttpServer为例创建服务器实例,监听指定端口

json-rpc-cxx库提供了不同类型的服务器类,以HttpServer为例,我们可以在特定端口创建服务器实例。假设我们要在端口8080创建服务器,可以使用以下代码:

jsonrpccxx::HttpServer httpServer(8080);

这样就创建了一个基于HTTP协议监听在8080端口的服务器对象,等待客户端的连接和请求。

(二)定义服务方法

创建继承JsonRpcServer的类,用于定义可被客户端调用的方法

为了定义可被客户端调用的方法,我们可以创建一个继承自jsonrpccxx::JsonRpcServer的类。这个类可以封装特定的业务逻辑,并将其暴露为远程可调用的方法。

通过BindMethod函数绑定具体方法,如加法函数示例

在继承自jsonrpccxx::JsonRpcServer的类中,我们可以使用BindMethod函数将C++的函数绑定到特定的方法名上。例如,定义一个加法函数并绑定到名为add的方法上,可以这样实现:

BindMethod("add", [](int num1, int num2) { return num1 + num2; });

这样,当客户端通过JSON-RPC请求调用add方法时,服务器将执行这个加法函数并返回结果。

(三)启动服务器

在main函数中启动服务器并保持运行的逻辑

main函数中,我们可以启动服务器并使其保持运行,以持续监听客户端的请求。

  1. 创建服务器实例和服务类实例
jsonrpccxx::HttpServerConnector serverConnector(8080);
MyService service(serverConnector);
  1. 调用StartListening启动服务器监听
service.StartListening();
std::cout << "Server started on port 8080." << std::endl;

当调用StartListening函数后,服务器会进入监听状态,等待客户端的连接和请求。一旦有请求到达,服务器会根据请求的方法名和参数执行相应的方法,并将结果返回给客户端。

  1. 保持服务器运行

为了保持服务器运行,可以使用一个循环,例如while (true) {}。这个循环只是一个简单的示例,在实际应用中,可能需要更好的服务器运行管理逻辑,比如使用信号处理来优雅地停止服务器。

  1. StartListening和StopListening函数的作用
  • StartListening:启动服务器的监听,使服务器开始接收客户端的请求。
  • StopListening:停止服务器的监听。在服务器运行过程中,如果需要停止服务器,可以调用这个函数来释放资源并结束服务器进程。

服务端示例

以下是使用json-rpc-cxx库创建服务器的详细代码示例:

#include <iostream>
#include "jsonrpccxx/server.h"
#include "jsonrpccxx/server_connector.h"
#include "jsonrpccxx/http_server_connector.h"class MyService : public jsonrpccxx::JsonRpcServer
{
public:MyService(jsonrpccxx::ServerConnector& serverConnector): jsonrpccxx::JsonRpcServer(serverConnector){BindMethod("add", [](int num1, int num2) {return num1 + num2;});}
};int main()
{jsonrpccxx::HttpServerConnector serverConnector(8080);MyService service(serverConnector);service.StartListening();std::cout << "Server started on port 8080." << std::endl;while (true) {}service.StopListening();return 0;
}

在这个示例中,我们创建了一个基于HTTP的服务器,定义了一个名为add的远程方法,该方法接受两个整数参数并返回它们的和。服务器启动后会一直运行,直到程序被手动终止。

四、客户端应用

在 JSON-RPC 通信中,客户端应用负责发起请求并处理服务器的响应。以下是如何使用 json-rpc-cxx 库来创建客户端应用并调用服务器上的远程方法的详细步骤。

(一)创建客户端连接

包含客户端所需头文件

在客户端代码中,首先需要包含必要的头文件。这些头文件提供了创建客户端和处理客户端连接相关功能的类和函数。

#include "jsonrpccxx/client.h"
#include "jsonrpccxx/client_connector.h"
#include "jsonrpccxx/http_client_connector.h"
  • jsonrpccxx/client.h 包含了客户端的主要实现类,如 jsonrpccxx::JsonRpcClient,用于发起远程过程调用。
  • jsonrpccxx/client_connector.h 提供了客户端连接的相关类,用于建立与服务器的连接。
  • jsonrpccxx/http_client_connector.h 是具体的 HTTP 客户端连接器实现。

以 HttpClient 创建连接对象,指向服务器地址

接下来,使用 HttpClient 创建客户端连接对象。假设服务器在本地运行且监听在端口 8080,可以使用以下代码创建连接对象:

jsonrpccxx::HttpClientConnector client("http://127.0.0.1:8080");

这里创建了一个指向本地 8080 端口的 HTTP 客户端连接对象,为后续创建 JSON-RPC 客户端实例和调用远程方法提供了基础。

(二)创建 JSON-RPC 客户端实例

使用创建好的客户端连接对象,可以创建 jsonrpccxx::JsonRpcClient 实例:

jsonrpccxx::JsonRpcClient rpcClient(client);

这个实例将用于调用服务器上的远程方法。通过这个实例,客户端可以发起 JSON-RPC 请求,将方法名和参数发送给服务器,并接收服务器返回的结果。

(三)调用远程方法

通过 CallMethod 函数调用服务器方法,处理可能的异常

通过 rpcClient 可以调用服务器上的方法。例如,调用 add 方法:

try
{int result = rpcClient.CallMethod<int>("add", 3, 4);std::cout << "Result of add: " << result << std::endl;
}
catch (const jsonrpccxx::JsonRpcException& e)
{std::cerr << "JSON-RPC Exception: " << e.what() << std::endl;
}

在上述代码中,CallMethod 函数用于调用服务器上的方法。它的模板参数指定了返回值类型,第一个参数是要调用的方法名称,后面的参数是传递给方法的参数。这里调用 add 方法并传递 34 作为参数。如果调用过程中出现 JSON-RPC 相关的异常,会被 catch 块捕获并输出错误信息。

客户端示例

以下是使用 json-rpc-cxx 库创建 HTTP 客户端的详细代码示例:

#include <iostream>
#include "jsonrpccxx/client.h"
#include "jsonrpccxx/client_connector.h"
#include "jsonrpccxx/http_client_connector.h"int main()
{// 创建 HTTP 客户端连接对象,连接到服务器(假设服务器在本地,端口为 8080)jsonrpccxx::HttpClientConnector client("http://127.0.0.1:8080");// 创建 JSON-RPC 客户端实例jsonrpccxx::JsonRpcClient rpcClient(client);try{// 调用服务器上的某个方法,这里假设服务器有一个名为 'add' 的方法,接受两个整数参数int result = rpcClient.CallMethod<int>("add", 3, 4);std::cout << "Result of add: " << result << std::endl;}catch (const jsonrpccxx::JsonRpcException& e){std::cerr << "JSON-RPC Exception: " << e.what() << std::endl;}return 0;
}

在这个示例中,客户端连接到本地运行在 8080 端口的 HTTP 服务器,并调用服务器上定义的 add 方法,传入两个参数 34,然后输出结果。如果调用过程中出现 JSON-RPC 相关的异常,会被捕获并输出错误信息。

五、错误处理

在分布式应用程序中,错误处理是确保系统稳定和可靠性的关键。无论是服务器端还是客户端,都需要对可能出现的错误进行细致处理。以下是如何在 JSON-RPC 应用程序中进行错误处理的详细指南。

(一)服务器端错误处理

方法内部对可能错误的处理

在服务器端方法内部,对可能出现的错误进行细致处理是确保系统稳定的关键。以除法运算为例,当方法涉及到可能出现除数为 0 的情况时,需要进行特别处理。

class MyService : public jsonrpccxx::JsonRpcServer
{
public:MyService(jsonrpccxx::ServerConnector& serverConnector): jsonrpccxx::JsonRpcServer(serverConnector){BindMethod("divide", [](int num1, int num2) {try {if (num2 == 0) {throw std::runtime_error("Division by zero");}return num1 / num2;} catch (const std::exception& e) {// 将异常信息作为错误消息返回给客户端return std::string("Error: ") + e.what();}});}
};

在上述代码中,divide 方法通过 try-catch 块进行异常处理。如果除数为 0,会抛出 std::runtime_error 异常,并在 catch 块中将错误信息以字符串形式返回给客户端。

设置全局异常处理函数

除了在方法内部处理错误,设置全局异常处理函数可以进一步增强服务器的稳定性。

class MyService : public jsonrpccxx::JsonRpcServer
{
public:MyService(jsonrpccxx::ServerConnector& serverConnector): jsonrpccxx::JsonRpcServer(serverConnector){// 设置全局异常处理函数SetExceptionHandler([](const std::exception& e) {return std::string("Internal server error: ") + e.what();});BindMethod("divide", [](int num1, int num2) {if (num2 == 0) {throw std::runtime_error("Division by zero");}return num1 / num2;});}
};

这里设置的全局异常处理函数,在捕获到未在方法内部处理的异常时,会将错误信息以特定格式返回给客户端。这样,即使某个方法没有正确处理异常,也能通过全局异常处理函数向客户端返回有意义的错误信息。

(二)客户端错误处理

使用 try-catch 块捕获 JsonRpcException 异常

在客户端调用远程方法时,使用 try-catch 块捕获 jsonrpccxx::JsonRpcException 异常是一种良好的编程习惯。

try {// 调用远程方法的代码
} catch (const jsonrpccxx::JsonRpcException& e) {std::cerr << "JSON-RPC Exception: " << e.what() << std::endl;// 可以根据错误码进行更详细的处理if (e.Code() == -32602) {std::cerr << "Invalid parameters." << std::endl;} else if (e.Code() == -32603) {std::cerr << "Internal error." << std::endl;}
} catch (const std::exception& e) {std::cerr << "Standard Exception: " << e.what() << std::endl;
}

在上述代码中,当捕获到 JsonRpcException 异常时,首先输出异常信息。然后,根据异常中的错误码进行更详细的错误处理。通过这种方式,可以更准确地定位和处理客户端在调用远程方法时出现的问题。

同时捕获标准异常处理其他问题

除了捕获 JsonRpcException 异常,还需要捕获其他可能的标准异常,以处理网络连接等其他问题。例如,在上述代码中,同时捕获了 std::exception 异常。这样,当出现其他未知的异常情况时,也能进行适当的处理。

六、总结

JSON-RPC 库,尤其是 json-rpc-cxx,在构建分布式应用程序中展现出诸多优势。以下是对 JSON-RPC 库优势的总结以及实际应用中的扩展方向。

1. JSON-RPC 库的优势

  • 高效便捷的远程过程调用:JSON-RPC 库提供了高效且便捷的远程过程调用方式,使得不同节点之间的通信变得简单而直接。
  • 跨平台兼容性json-rpc-cxx 在 Windows、Linux 和 OSX 上都能无缝运行,提高了开发效率和应用的可移植性。
  • 出色的数据处理能力:利用流行的 nlohmann::json 库,高效地处理 JSON 数据的序列化和反序列化,确保了数据在网络传输中的准确性和高效性。
  • 丰富的功能和灵活的选择:支持多种网络传输方式,为不同的应用场景提供了灵活的选择。
  • 全面的错误处理机制:服务器端和客户端都可以进行详细的错误处理,提高了系统的稳定性和可维护性。

2. 实际应用中的扩展方向

  • 添加更多复杂的远程方法:根据项目需求,添加更多复杂的远程方法以满足不同的业务需求。
  • 优化性能:通过调整网络传输参数、优化数据处理算法等方式,提高系统的响应速度和吞吐量。
  • 实现安全机制:添加身份验证和授权机制,确保只有合法的用户才能访问特定的远程方法。加密通信也是提高系统安全性的重要手段。

3. 利用文档和示例代码的重要性

  • 文档的重要性:文档提供了详细的使用说明和功能介绍,帮助开发者快速上手并深入理解库的功能特点。
  • 示例代码的重要性:示例代码展示了具体的应用场景和使用方法,为开发者提供了实际的参考。通过深入研究文档和示例代码,开发者可以更好地掌握库的使用技巧,避免常见的错误,提高开发效率。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【嵌入式开发】单片机CAN配置详解

0 前言 CAN外设作为一种传输速率较高&#xff0c;且连线较为简洁的通信协议&#xff0c;如今很多单片机内部都集成了CAN控制模块&#xff0c;这样只需要再外接一个CAN收发芯片&#xff0c;将TTL/CMOS电平转换成CAN协议的差分电平&#xff0c;就是一个完整的CAN收发节点。   最…

虚拟机安装Ubuntu 24.04服务器版(命令行版)

这个是专门用于服务器使用的&#xff0c;没有GUI&#xff0c;常用软件安装&#xff0c;见 虚拟机安装Ubuntu 24.04及其常用软件(2024.7)_ubuntu24.04-CSDN博客https://blog.csdn.net/weixin_42173947/article/details/140335522这里只记录独特的安装步骤 1 下载Ubuntu 24.04安…

ctfshow-web入门-SSTI(web361-web368)上

目录 1、web361 2、web362 3、web363 4、web364 5、web365 6、web366 7、web367 8、web368 1、web361 测试一下存在 SSTI 注入 方法很多 &#xff08;1&#xff09;使用子类可以直接调用的函数来打 payload1&#xff1a; ?name{{.__class__.__base__.__subclasses__…

Axure网络短剧APP端原型图,竖屏微剧视频模版40页

作品概况 页面数量&#xff1a;共 40 页 使用软件&#xff1a;Axure RP 9 及以上&#xff0c;非软件无源码 适用领域&#xff1a;短剧、微短剧、竖屏视频 作品特色 本作品为网络短剧APP的Axure原型设计图&#xff0c;定位属于免费短剧软件&#xff0c;类似红果短剧、河马剧场…

如何从头开始构建神经网络?(附教程)

随着流行的深度学习框架的出现&#xff0c;如 TensorFlow、Keras、PyTorch 以及其他类似库&#xff0c;学习神经网络对于新手来说变得更加便捷。虽然这些框架可以让你在几分钟内解决最复杂的计算任务&#xff0c;但它们并不要求你理解背后所有需求的核心概念和直觉。如果你知道…

JS 实现SSE通讯和了解SSE通讯

SSE 介绍&#xff1a; Server-Sent Events&#xff08;SSE&#xff09;是一种用于实现服务器向客户端实时推送数据的Web技术。与传统的轮询和长轮询相比&#xff0c;SSE提供了更高效和实时的数据推送机制。 SSE基于HTTP协议&#xff0c;允许服务器将数据以事件流&#xff08;…

HTML之表单学习记录

如果一个页面仅仅供用户浏览&#xff0c;那就是静态页面。如果这个页面还能实现与服务器进行数据交互&#xff08;像注册登录、话费充值、评论交流&#xff09;​&#xff0c;那就是动态页面。表单是我们接触动态页面的第一步。其中表单最重要的作用就是&#xff1a;在浏览器端…

WPF学习之路,控件的只读、是否可以、是否可见属性控制

C#的控件学习之控件属性操作 控件的只读、是否可以、是否可见&#xff0c;是三个重要的参数&#xff0c;在很多表单、列表中都有用到&#xff0c;正常表单控制可以在父层主键控制参数是否可以编辑和可见&#xff0c;但是遇到个别字段需要单独控制时&#xff0c;可以在初始化wi…

three.js 杂记

clip&#xff1a; 1&#xff1a; 着色器 #ifdef USE_CLIP_DISTANCE vec4 worldPosition modelMatrix * vec4( position, 1.0 ); gl_ClipDistance[ 0 ] worldPosition.x - sin( time ) * ( 0.5 ); #endif gl_Position projectionMatrix * modelViewMatrix * vec4( positio…

基于混合配准策略的多模态医学图像配准方法研究

摘要&#xff1a; 提出了一种由“粗”到“细”的混合配准策略&#xff0c;该配准策略吸取了以往配准方法的优点&#xff0c;且在细配阶段将基于特征的配准方法和基于灰度的配准方法结合在一起&#xff0c;提出了基于轮廓特征点集最大互信息的配准方法&#xff0c;从而在速度和精…

贪心算法入门(二)

相关文章 贪心算法入门&#xff08;一&#xff09;-CSDN博客 1.什么是贪心算法&#xff1f; 贪心算法是一种解决问题的策略&#xff0c;它将复杂的问题分解为若干个步骤&#xff0c;并在每一步都选择当前最优的解决方案&#xff0c;最终希望能得到全局最优解。这种策略的核心…

Autosar CP 基于CAN的时间同步规范导读

Autosar CP 基于CAN的时间同步规范主要用途 实现精确时间同步 提供了一种在CAN总线上准确分发时间信息的机制&#xff0c;确保连接到CAN网络的各个电子控制单元&#xff08;ECU&#xff09;能够共享精确的公共时间基准&#xff0c;对于需要精确时间协调的汽车系统功能&#xff…

前端常用布局模板39套,纯CSS实现布局

前端常用布局模板39套&#xff0c;纯CSS实现布局 说明 写博客、官网、管理后台都可以参考以下布局模板&#xff0c;实现模板布局的方式包含&#xff1a;flex、CSS、HTML5、Layout。 不需要下载积分&#xff0c;没有特殊库引用&#xff0c;不用安装任何插件&#xff0c;打开资源…

jmeter常用配置元件介绍总结之后置处理器

系列文章目录 安装jmeter jmeter常用配置元件介绍总结之后置处理器 8.后置处理器8.1.CSS/JQuery提取器8.2.JSON JMESPath Extractor8.3.JSON提取器8.4.正则表达式提取器8.5.边界提取器8.5.Debug PostProcessor8.6.XPath2 Extractor8.7.XPath提取器8.8.结果状态处理器 8.后置处理…

边缘计算在智能交通系统中的应用

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 边缘计算在智能交通系统中的应用 边缘计算在智能交通系统中的应用 边缘计算在智能交通系统中的应用 引言 边缘计算概述 定义与原…

Vue 项目打包后环境变量丢失问题(清除缓存),区分.env和.env.*文件

Vue 项目打包后环境变量丢失问题&#xff08;清除缓存&#xff09;&#xff0c;区分.env和.env.*文件 问题背景 今天在导报项目的时候遇到一个问题问题&#xff1a;在开发环境中一切正常&#xff0c;但在打包后的生产环境中&#xff0c;某些环境变量&#xff08;如 VUE_APP_B…

十三、注解配置SpringMVC

文章目录 1. 创建初始化类&#xff0c;代替web.xml2. 创建SpringConfig配置类&#xff0c;代替spring的配置文件3. 创建WebConfig配置类&#xff0c;代替SpringMVC的配置文件4. 测试功能 1. 创建初始化类&#xff0c;代替web.xml 2. 创建SpringConfig配置类&#xff0c;代替spr…

(干货)Jenkins使用kubernetes插件连接k8s的认证方式

#Kubernetes插件简介 Kubernetes 插件的目的是能够使用 Kubernetes 配合&#xff0c;实现动态配置 Jenkins 代理&#xff08;使用 Kubernetes 调度机制来优化负载&#xff09;&#xff0c;在执行 Jenkins Job 构建时&#xff0c;Jenkins Master 会在 kubernetes 中创建一个 Sla…

俏美韵从心出发,与女性一道为健康生活贡献力量

近期发布的《2025 全球食品与饮料》报告中显示&#xff0c;“回归本源”为2025年食品饮料赛道的趋势之一&#xff0c;消费者对于产品成分要求越来越严格&#xff0c;尤其是女性消费者&#xff0c;对成分是否自然&#xff0c;营养含量等方面越来越看重&#xff0c;俏美韵品牌从产…

区块链技术在慈善捐赠中的应用

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 区块链技术在慈善捐赠中的应用 区块链技术在慈善捐赠中的应用 区块链技术在慈善捐赠中的应用 引言 区块链技术概述 定义与原理 发…