p2p、分布式,区块链笔记:libp2p通过libp2p_demo::network实现文件传递功能

代码

  • 代码来自github开源项目file-sharing.rs。主要依赖clap库进行命令行参数解析,使用async_std进行并行操作,使用libp2p_demo::network中的相关方法进行网络建立与文件传输,但是代码量却减少了很多,这是由于libp2p_demo::network对libp2p中的集群事件等相关方法,将文件传递功能进行了集成。
use async_std::task::spawn;
use clap::Parser;
use futures::prelude::*;
use libp2p::core::{Multiaddr, PeerId};
use libp2p::multiaddr::Protocol;
use libp2p_demo::network;
use std::error::Error;
use std::io::Write;
use std::path::PathBuf;#[async_std::main]
async fn main() -> Result<(), Box<dyn Error>> {env_logger::init();let opt = Opt::parse();// network::new 返回值是一个元组,包含三个部分:// network_client(网络客户端:用于在应用程序的任何位置与网络层进行交互。)、// network_events(网络事件流 :用于接收传入请求的事件流)// network_event_loop(网络任务驱动:用于驱动网络本身的任务)// network::new来自libp2p_demo::network模块,从源代码看其为Swarm::new的进一步封装let (mut network_client, mut network_events, network_event_loop) =network::new(opt.secret_key_seed).await?;// async-std 是一个用于异步编程的库,类似于 tokio// async-std::task::spawn()函数会在后台启动一个新的异步任务,允许多个任务同时执行,这样可以提高程序的并发性能。// Spawn the network task for it to run in the background.spawn(network_event_loop.run());// 启动网络监听 In case a listen address was provided use it, otherwise listen on any address.match opt.listen_address {Some(addr) => network_client.start_listening(addr)// 侦听给定地址上的输入连接请求.await.expect("Listening not to fail."),None => network_client.start_listening("/ip4/0.0.0.0/tcp/0".parse()?).await.expect("Listening not to fail."),};// 连接到指定的对等节点,如果命令行参数指定了对等节点的地址(peer),则根据地址中的信息构建对等节点的ID,并尝试通过dial方法连接到该节点。if let Some(addr) = opt.peer {let peer_id = match addr.iter().last() {Some(Protocol::P2p(hash)) => PeerId::from_multihash(hash).expect("Valid hash."),_ => return Err("Expect peer multiaddr to contain peer ID.".into()),};network_client.dial(peer_id, addr).await.expect("Dial to succeed");}// 处理命令行参数中的不同操作match opt.argument {// 如果提供了一个文件,即{ path, name }。CliArgument::Provide { path, name } => {// Advertise oneself as a provider of the file on the DHT.network_client.start_providing(name.clone()).await;//  network_client.start_providing将本地节点作为DHT上给定文件的提供者进行播发。loop {match network_events.next().await {// Reply with the content of the file on incoming requests.Some(network::Event::InboundRequest { request, channel }) => {if request == name {network_client.respond_file(std::fs::read(&path)?, channel).await;}}e => todo!("{:?}", e),}}}// 如果给出了一个名称,即{name}CliArgument::Get { name } => {// Locate all nodes providing the file.let providers = network_client.get_providers(name.clone()).await;if providers.is_empty() {return Err(format!("Could not find provider for file {}.", name).into());}// Request the content of the file from each node.let requests = providers.into_iter().map(|p| {let mut network_client = network_client.clone();let name = name.clone();async move { network_client.request_file(p, name).await }.boxed()});// Await the requests, ignore the remaining once a single one succeeds.let file_content = futures::future::select_ok(requests).await.map_err(|_| "None of the providers returned file.")?.0;std::io::stdout().write_all(&file_content)?;}}Ok(())
}#[derive(Parser, Debug)] // #[derive(Parser, Debug)]: 这是一个Rust的属性宏(attribute macro),用于自动为结构体实现解析器(parser)和调试输出(Debug trait)。Parser是由Clap库提供的,用于解析命令行参数
#[clap(name = "libp2p file sharing example")] // #[clap(name = "libp2p file sharing example")]: 这个属性指定了生成的命令行接口的名称为 "libp2p file sharing example"。
struct Opt {///  #[clap(long)] // #[clap(long)]: 这个属性指示Clap库将下面的字段作为长格式命令行参数处理。长格式参数通常由两个破折号(--)引导,例如 --secret-key-seed。/// Fixed value to generate deterministic peer ID.#[clap(long)]secret_key_seed: Option<u8>,#[clap(long)]peer: Option<Multiaddr>,#[clap(long)]listen_address: Option<Multiaddr>,#[clap(subcommand)] //  #[clap(subcommand)] 属性,表示它是一个子命令(subcommand)。CliArgument 可能是一个枚举类型,用于定义不同的子命令选项。argument: CliArgument,
}
// 有两个成员的枚举变量
#[derive(Debug, Parser)]
enum CliArgument {Provide {#[clap(long)]path: PathBuf,#[clap(long)]name: String,},Get {#[clap(long)]name: String,},
}

运行结果

发送端

  • cargo run --example 05-file-sharing -- --listen-address /ip4/127.0.0.1/tcp/40837 --secret-key-seed 1 provide --path ./test.exe --name testname
PS C:\Users\kingchuxing\Documents\learning-libp2p-main\rust> cargo run --example 05-file-sharing -- --listen-address /ip4/127.0.0.1/tcp/40837 --secret-key-seed 1 proet-key-seed 1 provide --path .\test.txt --name testnameCompiling libp2p_demo v0.1.0 (C:\Users\kingchuxing\Documents\learning-libp2p-main\rust)Finished `dev` profile [unoptimized + debuginfo] target(s) in 4.47sRunning `target\debug\examples\05-file-sharing.exe --listen-address /ip4/127.0.0.1/tcp/40837 --secret-key-seed 1 provide --path .\test.txt --name testname`
Local node is listening on "/ip4/127.0.0.1/tcp/40837/p2p/12D3KooWPjceQrSwdWXPyLLeABRXmuqt69Rg3sBYbU1Nft9HyQ6X"

接收端

  • 由于最后需要用std::io::stdout().write_all(&file_content)?;输出文件内容,所以采用了txt格式的文件进行测试
  • cargo run --example 05-file-sharing -- --peer /ip4/127.0.0.1/tcp/40837/p2p/12D3KooWPjceQrSwdWXPyLLeABRXmuqt69Rg3sBYbU1Nft9HyQ6X get --name testname
PS C:\Users\kingchuxing\Documents\learning-libp2p-main\rust> cargo run --example 05-file-sharing  -- --peer /ip4/127.0.0.1/tcp/40837/p2p/12D3KooWPjceQrSwdWXPyLLeABRXmuqt69Rg3sBYbU1Nft9HyQ6X    get   --name testnameFinished `dev` profile [unoptimized + debuginfo] target(s) in 0.32sRunning `target\debug\examples\05-file-sharing.exe --peer /ip4/127.0.0.1/tcp/40837/p2p/12D3KooWPjceQrSwdWXPyLLeABRXmuqt69Rg3sBYbU1Nft9HyQ6X get --name testname`
Local node is listening on "/ip4/192.168.3.12/tcp/62691/p2p/12D3KooWDDffKUnjVzsbMK5JHNQHsTE8FJNQDzS9tzKwSckGPe3f"
Local node is listening on "/ip4/127.0.0.1/tcp/62691/p2p/12D3KooWDDffKUnjVzsbMK5JHNQHsTE8FJNQDzS9tzKwSckGPe3f"
12345656867867867867867845634534523423453534564654645634 // test.txt文件的内容

参数解释

Usage: 05-file-sharing.exe [OPTIONS] <COMMAND>Commands:providegethelp     Print this message or the help of the given subcommand(s)Options:--secret-key-seed <SECRET_KEY_SEED>  Fixed value to generate deterministic peer ID //用于决定生成peer ID的固定值--peer <PEER>--listen-address <LISTEN_ADDRESS>-h, --help                               Print help
error: process didn't exit successfully: `target\debug\examples\05-file-sharing.exe` (exit code: 2)

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

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

相关文章

Matplotlib 学习

知识点 1.plot()&#xff1a;用于绘制线图和 散点图scatter() 函数&#xff1a;plot() 函数可以接受许多可选参数&#xff0c;用于控制图形的外观&#xff0c;例如&#xff1a;颜色: colorblue 控制线条的颜色。线型: linestyle-- 控制线条的样式&#xff0c;例如虚线。标记…

YoloV8改进策略:Block改进|轻量实时的重参数结构|最新改进|即插即用(全网首发)

摘要 本文使用重参数的Block替换YoloV8中的Bottleneck&#xff0c;GFLOPs从165降到了116&#xff0c;降低了三分之一&#xff1b;同时&#xff0c;map50-95从0.937涨到了0.947。 改进方法简单&#xff0c;只做简单的替换就行&#xff0c;即插即用&#xff0c;非常推荐&#xf…

C++_STL---list

list的相关介绍 list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代。 list的底层是带头双向循环链表结构&#xff0c;链表中每个元素存储在互不相关的独立节点中&#xff0c;在节点中通过指针指向其前一个元素和后一个元素。…

IDEA与通义灵码的智能编程之旅

1 概述 本文主要介绍在IDEA中如何安装和使用通义灵码来助力软件编程,从而提高编程效率,创造更大的个人同企业价值。 2 安装通义灵码 2.1 打开IDEA插件市场 点击IDEA的设置按钮,下拉选择Plugins,如下: 2.2 搜索通义灵码 在搜索框中输入“通义灵码”,如下: 2.3 安…

C语言 二分法求方程根

用二分法求下面方程在&#xff08;-10&#xff0c;10&#xff09;的根。 2x^3-4x^23x-60 这个程序使用二分法求方程 2x^3 - 4x^2 3x - 6 0 在区间 (-10, 10) 内的根。 #include <stdio.h> #include <math.h>// 方程 f(x) double f(double x) {return 2 * pow(x…

使用ifconfig命令获取当前服务器的内网IP地址

如何使用ifconfig命令获取当前服务器的内网IP地址呢&#xff1f; ifconfig eth0 | grep inet | awk {print $2}

什么是五级流水?银行眼中的“好流水”,到底是什么样的?

无论是按揭买房还是日常贷款&#xff0c;银行流水都是绕不开的一环。规划好你的流水&#xff0c;不仅能让你在申请贷款时更有底气&#xff0c;还可能帮你省下不少冤枉钱。今天&#xff0c;咱们就来一场深度剖析&#xff0c;聊聊如何在按揭贷款、个人经营抵押贷款前&#xff0c;…

相关向量机(Relevance Vector Machine,RVM)及Python和MATLAB实现

**相关向量机&#xff08;Relevance Vector Machine&#xff0c;RVM&#xff09;** 是一种基于贝叶斯框架的机器学习模型&#xff0c;于2001年由Michael Tipping提出。RVM是一种稀疏建模技术&#xff0c;类似于支持向量机&#xff08;SVM&#xff09;&#xff0c;但其重点在于自…

代码随想录 数组部分+代码可在本地编译器运行

代码随想录 数组部分&#xff0c;代码可在本地编译器运行 文章目录 数组理论基础704.二分查找题目&#xff1a;思路二分法第一种写法二分法第二种写法 代码 27.移除元素题目&#xff1a;思路-双指针法代码 977.有序数组的平方题目思路-双指针代码 209.长度最小的子数组题目&am…

MPI,0号进程发信息,其他进程收信息

进程0向进程1发送值: 42 进程0向进程2发送值: 42 进程0向进程3发送值: 42 进程0向进程4发送值: 42 进程0向进程5发送值: 42 进程1收到的数据是: 42 进程2收到的数据是: 42 进程3收到的数据是: 42 进程5收到的数据是: 42 进程4收到的数据是: 42 #include <mpi.h> #include…

ChatGPT4深度解析:探索智能对话新境界

大模型chatgpt4分析功能初探 目录 1、探测目的 2、目标变量分析 3、特征缺失率处理 4、特征描述性分析 5、异常值分析 6、相关性分析 7、高阶特征挖掘 1、探测目的 1、分析chat4的数据分析能力&#xff0c;提高部门人效 2、给数据挖掘提供思路 3、原始数据&#xf…

科研绘图系列:R语言径向柱状图(Radial Bar Chart)

介绍 径向柱状图(Radial Bar Chart),又称为雷达图或蜘蛛网图(Spider Chart),是一种在极坐标系中绘制的柱状图。这种图表的特点是将数据点沿着一个或多个从中心向外延伸的轴来展示,这些轴通常围绕着一个中心点均匀分布。 特点: 极坐标系统:数据点不是在直角坐标系中展…

王者荣耀游戏复盘

在王者荣耀中&#xff0c;复盘是一个重要的学习和提升过程。根据搜索结果&#xff0c;复盘模板通常包括以下几个部分&#xff1a; 1. **内容&计划**&#xff1a; 记录你在游戏中做了什么&#xff0c;包括具体行动内容&#xff0c;明确原定目标与实际结果的差异。 2. **亮点…

【后端面试题】【中间件】【NoSQL】MongoDB查询优化3(拆分、嵌入文档,操作系统)

拆分大文档 很常见的一种优化手段&#xff0c;在一些特定的业务场景中&#xff0c;会有一些很大的文档&#xff0c;这些文档有很多字段&#xff0c;而且有一些特定的字段还特别的大。可以考虑拆分这些文档 大文档对MongoDB的性能影响还是很大的&#xff0c;就我个人经验而言&…

ASCII码对照表【2024年汇总】

&#x1f37a;ASCII相关文章汇总如下&#x1f37a;&#xff1a; &#x1f388;ASCII码对照表&#xff08;255个ascii字符汇总&#xff09;&#x1f388;&#x1f388;ASCII码对照表&#xff08;Unicode 字符集列表&#xff09;&#x1f388;&#x1f388;ASCII码对照表&#x…

Day05-04-持续集成总结

Day05-04-持续集成总结 1. 持续集成2. 代码上线目标项目 1. 持续集成 git 基本使用, 拉取代码,上传代码,分支操作,tag标签 gitlab 用户 用户组 项目 , 备份,https,优化. jenkins 工具平台,运维核心, 自由风格工程,maven风格项目,流水线项目, 流水线(pipeline) mavenpom.xmlta…

【瑞数补环境实战】某网站Cookie补环境与后缀分析还原

文章目录 1. 写在前面2. 特征分析3. 接口分析3. 补JS环境4. 补后缀参数 【&#x1f3e0;作者主页】&#xff1a;吴秋霖 【&#x1f4bc;作者介绍】&#xff1a;擅长爬虫与JS加密逆向分析&#xff01;Python领域优质创作者、CSDN博客专家、阿里云博客专家、华为云享专家。一路走…

二分查找2

1. 山脉数组的峰顶索引&#xff08;852&#xff09; 题目描述&#xff1a; 算法原理&#xff1a; 根据题意我们可以将数组分为两个部分&#xff0c;一个部分是arr[mid-1]<arr[mid]&#xff0c;另一个部分为arr[mid-1]>arr[mid]&#xff0c;此时不难发现我们可以将二分…

Flink,spark对比

三&#xff1a;az 如何调度Spark、Flink&#xff0c;MR 任务 首先&#xff0c;使用java编写一个spark任务&#xff0c;定义一个类&#xff0c;它有main方法&#xff0c;里面写好逻辑&#xff0c;sparkConf 和JavaSparkContext 获取上下文&#xff0c;然后打成一个jar包&#xf…

数据结构——二叉树相关题目

1.寻找二叉树中数值为x的节点 //寻找二叉树中数值为x的节点 BTNode* TreeFind(BTNode* root, BTDataType x)//传过来二叉树的地址和根的地址&#xff0c;以及需要查找的数据 {if (root Null){return Null;}//首先需要先判断这个树是否为空&#xff0c;如果为空直接返回空if (…