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

从单机AI到Agent网络:构建多智能体协作系统的技术演进与实践 最近在尝试将大语言模型(LLM)应用到实际业务场景时,我遇到了一个典型困境:一个看似简单的“智能客服”需求,却需要调用多个外部API(天气查询、订单检索、知识库问答),并处理复杂的逻辑判断。单个大模型调用(如GPT-4)虽然能理解意图,但无法稳定执行这一系列动作。这让我深刻体会到,当前大多数AI应用仍停留在“单机问答”阶段,距离真正的“智能”还有巨大鸿沟。 这不禁让我思考一个更宏大的问题:从PC时代的Windows,到移动互联网的iOS/Android,每一次技术革命都催生了属于那个时代的“超级应用”。那么 阅读详情

代码

  • 代码来自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 testname
   Compiling libp2p_demo v0.1.0 (C:\Users\kingchuxing\Documents\learning-libp2p-main\rust)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 4.47s
     Running `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 testname
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.32s
     Running `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:
  provide
  get
  help     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)
【go-libp2p学习笔记】使用go-libp2p搭建中转服务器(circuit relay server) libp2p算是一个蛮新的库,提供了非常强大的p2p节点发现/连接/通信能力。IPFS的基石。 中文网上的**技术教程**比较少,所以抛砖引玉开一点坑来体验一下! 阅读详情

相关推荐

libp2p-chat-demo:此演示演示使用libp2p创建p2p聊天应用程序有多么容易

Libp2p聊天演示 该演示演示了使用libp2p创建p2p聊天应用程序有多么容易。 我通过结合的routed-echo和chat-with-rendezvous演示创建了该演示。 我从那个回购中无耻地借钱(尤其是在此回购的详细信息部分中)。 建立 > make 用法 在一台计算机(或终端)上,运行命令./chat -p 1000 ,其中1000是libp2p节点将监听的端口。 它看起来应该像这样: > ./chat -p 1000 2019/12/18 21:00:49 bootstrapped with QmSoLPppuBtQSGwKDZT2M73ULpjvfd3aZ6ha4oFGL

什么是Libp2p,简单介绍

Libp2p(library peer-to-peer),是一个模块化的p2p网络架构,能够帮助开发p2p应用。该框架由一系列协议、规范和库组成,可以促进网络节点之间的p2p通信。

vxstar的博客 2661

GPS-SDR-SIM使用详解

GPS-SDR-SIM 是一款开源工具,能够生成 GPS 基带信号数据流,这些数据流可通过软件定义无线电(SDR)平台(如 ADALM-Pluto、bladeRF、HackRF、USRP 等)转换为射频(RF)信号。简单来说,它能模拟 GPS 卫星信号,帮助开发者或爱好者测试 GPS 接收设备的性能,而无需依赖真实的卫星信号。

qq_35621280的博客 1241

libp2p 快速开始

Libp2p是一个模块化的网络栈,通过将各种传输和P2P协议结合在一起,使得开发人员很容易构建大型、健壮的P2P网络。

西京刀客 4918

基于云平台的ATS系统微服务架构方案研究

在当前智慧地铁的升级转型过程中,城市轨道交通ATS系统面临着稳定性差、运维方 式繁琐和故障应急处理效率低等问题。为此,提出一种基于云平台的ATS系统微服务架构方案; 研究了ATS系统在云平台上的微服务总体架构、ATS应用的微服务划分和设计、容器部署方式 及通信交互模式,可实现系统松耦合和易扩展,达到节约计算资源、提高系统稳定性和运营效 率的目的

mi_lan1的博客 966

TI DSP的 FFT与IFFT库函数的使用测试

/** * Copyright (C) 2013 Guangzhou Tronlong Electronic Technology Co., Ltd. - www.tronlong.com * * @file dsplib_fft.c * * @brief Example application main file. * This application will run FFT performance test. * * @author Tronlong <support@tron.

ToneChip的专栏,一个传统的嵌入式码农,裸机编程 2676

干货|更通用的P2P网络协议栈——Libp2p

Libp2p通过upgrader的muxer模块将普通接口升级为支持流复用的接口,节点间数据传输时会在连接上通过流进行并行数据收发,而不是新建连接,从而减少了节点间新建连接的消耗。数据传输建立在节点连接的基础上,在可以拨号远程节点并建立连接之前,需要知道远程节点的监听地址。Libp2p通过“multiaddr”的编码方案来统一不同协议的地址格式,在Swarm模块根据“multiaddr”解析协议并调用相应协议的接口完成具体操作,从而达到了应用层不需要关注使用的传输层协议的目的。...

weixin_60043341的博客 2924

玩转肺癌目标检测数据集Lung-PET-CT-Dx ——①从TCIA获取影像数据集

该目标检测公共数据集源自 The Cancer Imaging Archive(TCIA),是肿瘤研究方面的著名的医学影像公开数据库。 数据以 DICOM 格式存储,由肺癌受试者的 CT 和 PET-CT DICOM 图像组成。

takedachia的博客 1万+

从Atom节点到分布式系统:核心架构、设计原则与Go实战

在分布式系统和区块链领域,节点作为系统中最基础的执行单元,其设计理念深刻影响着整个网络的稳定性与扩展性。节点本质上是一个遵循标准化接口、具备自治能力的计算单元,通过模块化分层架构(如网络通信层、共识层、业务逻辑层、数据存储层和API层)实现功能解耦与高效协作。这种设计模式的价值在于能够支撑起去中心化网络、微服务架构和边缘计算等复杂场景,确保系统在规模化时仍能保持可靠运行。本文以构建一个简化的区块链节点为例,深入探讨了节点设计中的关键原则,如单一职责、配置驱动和可观察性,并提供了基于Go语言的实战代码,涵盖从

weixin_30328063的博客 431

WGS-84 ECEF ENU 坐标系学习记录

地球坐标系固定在地球上而随地球一起在空间做公转和自转运动,因此地球上任一固定点在地球坐标系的坐标就不会由于地球旋转而变化。地心地固直角坐标系和大地坐标系都属于这种坐标系。 一、 几种坐标系 地心地固直角坐标系(ECEF)坐标系 其原点为地球的质心,x轴延伸通过本初子午线(0度经度)和赤道(0deglatitude)的交点。 z轴延伸通过的北极(即,与地球旋转轴重合)。 y轴完成右手坐标系,穿...

YYshuangshuang的博客 1万+

【Proteus仿真】74HC595+74LS154驱动显示16X16点阵

【Proteus仿真】74HC595+74LS154驱动显示16X16点阵

perseverance51博客 2893

p2p、分布式,区块链笔记: libp2p基础

【代码】p2p、分布式,区块链笔记: libp2p基础。

ResumeProject的博客 1738

多源异构数据融合(Kaggle+Google Trends联合分析)

本文详细介绍了如何利用Python实现多源异构数据融合,以Kaggle电商销售数据与Google Trends搜索指数为例,展示了数据清洗、预处理、时间对齐、数据合并、相关性分析、回归建模和可视化全过程。数据预处理与内存优化通过分块加载、数据类型转换和缺失值处理,有效降低了大规模数据在内存中的占用,并确保数据质量。时间对齐与数据融合策略采用重采样与内连接方法对齐不同数据源的时间维度,实现了高质量数据的融合,为后续联合分析奠定基础。模型构建与分析。

闲人编程的博客 1016

libp2p概览

Introduction to libp2p Why do we need libp2p? libp2p 是一个模块化的网络堆栈,从 IPFS 演变为一个独立的项目。 为了解释为什么 libp2p 是去中心化网络中如此重要的一部分,我们需要退后几步,了解它的来源。 libp2p 的初始实现始于 IPFS(一种对等文件共享系统)内部。让我们从探索 IPFS 旨在解决的网络问题开始。 Web 2.0 我们越来越喜欢互联网,并将其用于日常生活的方方面面,例如学习、与朋友和家人联系、购物、管理财务等等。 我们已经变

MyHerux的博客 3202

知识图谱设计简记

知识图谱是一种语义化的知识表示框架,通过实体-关系-属性三元组形式表达现实世界关联。其核心价值在于关联化整合数据、支持可解释性推理和赋能智能化应用。知识图谱可分为通用型和领域型两类,基本构成包括实体、关系、属性等基础元素,以及本体和实例等架构层元素。设计方法主要有自上而下、自下而上和混合式三种,需遵循业务导向、一致性等原则。在建模时需要明确属性与实体的判断标准,规范处理关系的方向性与对称性,并合理构建多重关系。主流技术框架如RDF和属性图体系均支持多重关系建模,选择需考虑业务需求。本体作为知识图谱的概念骨架

生活在别处 358

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

【libp2p——NAT】

AutoNAT允许一个节点通过拨打预定的公共地址来请求其他节点。对于NAT背后的私有节点,强烈建议如下不广播私有地址通过NAT获得一个预留的中继的地址广播这个中继地址对于在公网上的节点启动中继功能以帮助其他节点考虑激活DHT服务器模式以改善与公网的连接如果大多数拨号尝试都成功,则该节点可以合理地确定它不在 NAT 后面。另一方面,如果大多数拨号尝试都失败,则强烈表明 NAT 正在阻止传入连接。

qq_45467608的博客 3058

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

为什么 ETH2.0 要选择 libp2p ?

如果你有持续关注Polkadot、Ethereum 2.0或Substrate的开发近况,你应该听说过libp2p。Libp2p 是一个便于使用者开发去中心化点对点应用的网络框架,它原先是IPFS的网络协议延申,如今已自成一家。 愿景 所有的分布式点对点网络,都会面临一系列不同于传统网络的挑战。Libp2p 是个通用工具包,有了它,开发者就可以在分布式应用上使用可插拔的网...

跨链技术践行者 1万+

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

[libp2p的一些核心概念]

libp2使用对等体的身份和位置进行区分。对等体的身份是稳定的、可验证的,并在对等体的整个生命周期内有效。在特定网络上,在特定时间点,对等体可能具有一个或多个位置,可以用地址表示。例如,我可以通过全局IPv4地址198.51.100的TCP端口1234进行访问。在一个只支持TCP/IP或UDP over IP的系统中,我们可以很容易地使用熟悉的:表示法编写我们的地址,并将它们存储为地址和端口的元组。然而,libp2p被设计为传输无关,这意味着我们甚至不能假设我们将使用基于IP的网络。

qq_45467608的博客 1924

Libp2p学习01一个简单的聊天服务

说明 本人是刚学 libp2p, 这些博客 不能当作是教程或者是引导。 也许会有大量错误,欢迎大佬指导。 此博客源码 imjoel/go-libp2p-learn 搭建一个简单的穿透服务 搭建穿透服务一共需要3步, 生成一个节点ID 创建一个 Host 等待连接 1. 生成节点ID 不用多说,github.com/libp2p/go-libp2p-examples 上有示例, 下面是我将目标代码整合成了一个方法 import ( crand "crypto/rand" "github.com/lib

Joel的博客 3839

IPFS、区块链的libp2p

IPFS基本定义 IPFS即InterPlanetary File System,是一个基于内容寻址的、分布式 的、新型超媒体传输协议。IPFS支持创建完全分布式的应用。它旨在使 网络更快、更安全、更开放。IPFS是一个分布式文件系统,它的目标是 将所有计算设备连接到同一个文件系统,从而成为一个全球统一的存储 系统。 IPFS与区块链的基本关系 区块链是什么? 区块链实际上就是一个分布式数据库,而这个数据库是分布式的、基于密码学的分布式账本数据库。其具有分布式、不可篡改、开放与共识等基本特性。 但是,其具

qq_41393481的博客 2224

peerDependency到底是什么

它告诉 NPM 忽略项目中引入的各个 modules 之间的相同 modules 但不同版本的问题并继续安装,保证各个引入的依赖之间对自身所使用的不同版本 modules 共存。在 NPM v7 中,默认安装 peerDependencies,在我们日常使用的插件例如 babel-plugin-dynamic-import-node、babel-plugin-transform-vue-jsx、lottie-web,它们都依赖于 webpack 进行开发的。正常开发中,我们经常接触到的是。

Hi,印象钟情 2176

libp2p连接就像送快递?轻松看懂节点如何“找路”

特点类比快递网络实际效果多协议支持兼容汽车、火车、飞机适应各种网络环境自动寻址快递站帮你找地址无需手动配置复杂参数加密安全包裹上锁+身份验证防止数据泄露或篡改中继穿透顺丰网点代收突破路由器/NAT限制高效复用一条路跑多种车节省带宽,降低延迟让设备像快递网络一样灵活、可靠地通信,无论它们身处何地、用什么方式联网!

qq_23949975的博客 626

P2P网络编程-2-案例实践:P2P聊天应用

文章目录一、初代版本1.1 简介1.2 代码与解析1.3 测试运行二、节点发现2.1 简介2.2 代码与解析2.3 测试运行三、总结3.1 libp2p节点发现构建流程3.2 libp2p中地址的转换关系 上一节学习了IPFS项目中P2P网络的构建工具libp2p的基本概念以及简单案例 接下来通过官方的聊天案例进一步了解该项目的使用 项目地址: https://github.com/libp2p/go-libp2p/tree/master/examples 我们从初代版本(手动发送接收)p2p聊天到具有节

文杰的博客 3499

【libp2p-echo案例】

主机是在集群的顶部管理服务的抽象。它提供了一个清晰的接口,用于连接到给定远程对等节点上的服务。

qq_45467608的博客 1165

libp2p服务发现之 Multicast DNS(mDNS)

在libp2p中,mDNS和Kademlia DHT都是用于节点发现和连接管理的技术。当一个节点需要加入libp2p网络时,它可以通过mDNS和Kademlia DHT查找和连接其他节点,以建立对等网络。具体来说,mDNS通常用于在局域网中查找其他节点,而Kademlia DHT则是在广域网中查找其他节点。

西京刀客 3243

p2p、分布式,区块链笔记: Libp2p分散打孔 2022 IEEE 第 42 届分布式计算系统国际会议研讨会 (ICDCSW)

我们提出了一种内置于对等网络库 libp2p [1] 中的去中心化打洞机制。打洞对于对等网络至关重要,它使每个参与者能够直接与任何其他参与者通信,尽管被防火墙和 NAT 隔开。去中心化的 libp2p 打洞协议利用了类似于 STUN(RFC 8489 [2])、TURN(RFC 8566 [3])和 ICE(RFC 8445 [4])的协议,而无需任何中心化基础设施。具体而言,它不需要任何有关网络参与者的先前知识,除了至少一个(任意)节点来引导对等发现。关键见解是,用于打洞的协议(即地址发现和中继协议)可以

ResumeProject的博客 2577
上一篇: 生物化学笔记:电阻抗基础+电化学阻抗谱EIS+电化学系统频率响应分析
下一篇: 【工业工艺与设计 机械】翻砂铸造+铸砂工艺
FakeOccupational
博客等级 码龄6年 2万+粉丝 1727原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值