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.pswp.cn/diannao/42235.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/42235.shtml
英文地址,請注明出處:http://en.pswp.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 (…