尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Reticulum 官方代码示例全解:从最小接入、加密链路到自定义接口的实战指南

发布时间:2026/9/29 11:29:42

资讯中心
01
ARTICLE

Reticulum 官方代码示例全解:从最小接入、加密链路到自定义接口的实战指南

Reticulum 官方代码示例全解:从最小接入、加密链路到自定义接口的实战指南
网络通信密码学IoT协议【免费下载链接】ReticulumThe cryptography-based networking stack for building unstoppable networks with LoRa, Packet Radio, WiFi and everything in between.项目地址https://gitcode.com/gh_mirrors/re/Reticulum点击查看免费下载本篇技术指南以 Reticulum 官方文档《Code Examples》源文件为 docs/source/examples.rst为主体系统讲解随源码发行版附带的 11 个示例程序Minimal、Announce、Broadcast、Echo、Link、Identify、Request、Channel、Buffer、Filetransfer与ExampleInterface。全部示例位于仓库 Examples 目录运行它们不需要任何专用硬件本地即可体验 Reticulum 的 Destination目的地、Packet数据包、Link加密链路、Channel结构化信道、Buffer缓冲流、Resource资源传输与自定义 Interface接口等核心机制。读完本文你将掌握编写自己的 Reticulum 程序所需的全部基础模式如何接入网络栈、如何通告与发现目的地、如何收发数据包、如何建立加密链路并识别对端、如何做请求/响应、如何传输结构化数据与任意大小的文件以及如何为 Reticulum 编写可热加载的自定义接口。运行前提与通用入口所有示例都遵循相同的启动模式import RNS后通过RNS.Reticulum(configpath)完成网络栈初始化随后创建一个或多个RNS.Destination最后进入一个while True交互循环。命令行均支持--config参数用于指定替代的 Reticulum 配置目录默认值为None即使用标准配置目录。交互循环中按回车可手动发送 announceCtrl-C退出程序。以Minimal为例典型的启动方式为python3 Examples/Minimal.py # 或指定自定义配置目录 python3 Examples/Minimal.py --config /path/to/configdir从源码结构看RNS/Reticulum.py 负责加载并管理配置中的全部接口、启动 Transport 实例示例程序只要完成这一步就能接入本机已配置的所有接口如 LocalInterface、TCPInterface、UDPInterface 等。在examples.rst开头官方文档即说明这些示例用于帮助读者学习如何编写自己的 Reticulum 程序。Minimal约五行业务代码接入 Reticulum 网络Minimal演示接入网络所需的最少代码初始化网络栈、创建随机身份、创建目的地并在回车时发送 announce。完整代码位于 Examples/Minimal.py核心逻辑如下def program_setup(configpath): # 1. 初始化 Reticulum 网络栈 reticulum RNS.Reticulum(configpath) # 2. 随机生成一个新的身份 identity RNS.Identity() # 3. 用该身份创建目的地IN 方向、SINGLE 类型、位于 app 命名空间下 destination RNS.Destination( identity, RNS.Destination.IN, RNS.Destination.SINGLE, APP_NAME, # example_utilities minimalsample ) # 4. 配置目的地自动证明所有发往它的数据包 destination.set_proof_strategy(RNS.Destination.PROVE_ALL) # 5. 进入 announce 循环 announceLoop(destination)这里的每个环节对应 Reticulum 的核心概念IdentityReticulum 的身份与加密基础。RNS/Identity.py 中实现身份生成、公私钥派生与签名。示例中的RNS.Identity()每次运行都会随机生成一个新身份因此目的地哈希每次都会变化。Destination可寻址、可通信的网络端点。构造参数依次为identity、方向RNS.Destination.IN表示入站、类型RNS.Destination.SINGLE表示单播以及作为分层命名空间的APP_NAME和示例名。目的地通告announce后网络中其他节点会自动建立到达它的路径。方向与类型常量定义在 RNS/Destination.py。证明策略RNS.Destination.PROVE_ALL源码中取值为0x23让 RNS 自动为每个入站数据包生成证明并回传给发送方使通信双方都能确认消息是否被正确接收。同一文件还定义了PROVE_NONE0x21与PROVE_APP0x22由proof_requested_callback决定是否证明两种策略。announce 循环负责等待回车并调用destination.announce()同时用RNS.prettyhexrep(destination.hash)打印目的地哈希的十六进制表示。Announce通告发布与通告回调过滤Announce在 Minimal 的基础上深入讲解两件事如何带app_data发布通告以及如何让程序在收到相关目的地的通告时获得通知。完整代码见 Examples/Announce.py。示例在同一个身份下创建了两个目的地分别对应fruits与noble_gases两个 aspectannounce 时携带随机挑选的水果或惰性气体名称作为应用数据destination_1.announce(app_datafruit.encode(utf-8)) destination_2.announce(app_datanoble_gas.encode(utf-8))接收端通过自定义的ExampleAnnounceHandler类监听通告。该类的构造参数aspect_filter决定它关心哪些通告注册时传入过滤字符串example_utilities.announcesample.fruits则只接收该 aspect 前缀的通告announce_handler ExampleAnnounceHandler( aspect_filterexample_utilities.announcesample.fruits ) RNS.Transport.register_announce_handler(announce_handler)通告处理器必须实现received_announce(self, destination_hash, announced_identity, app_data)方法Reticulum 的 Transport 系统在收到匹配的通告时调用它。文档特别提醒过滤器必须具体不支持通配符。register_announce_handler是 RNS/Transport.py 提供的公开静态方法Transport是 Reticulum 的路由与传输核心负责路径发现、通告分发与包路由。Broadcast明文广播消息Broadcast演示向网络中所有监听方发送不加密的广播消息。与 SINGLE 目的地不同这里创建的是PLAIN类型目的地——任何人都可以监听并向它发送数据。完整代码见 Examples/Broadcast.py。示例还展示了频道channel概念channel参数会拼入目的地命名空间从而划分不同的广播频道默认值为public_informationif channel None: channel public_information broadcast_destination RNS.Destination( None, # PLAIN 目的地不需要身份 RNS.Destination.IN, RNS.Destination.PLAIN, APP_NAME, broadcast, channel ) # 指定每次收到数据时回调的函数 broadcast_destination.set_packet_callback(packet_callback)发送方在交互循环中把用户输入编码为 UTF-8 字节构造RNS.Packet(destination, data)并调用packet.send()接收回调packet_callback(data, packet)直接解码打印收到的数据。命令行额外提供--channel参数用于选择广播频道。这是典型的单向、无保密性要求信息分发场景。Echo基于 Packet 的请求-证明往返Echo演示两个目的地之间用 Packet 接口通信并展示 Reticulum 的**数据包证明proof与投递回执PacketReceipt**机制。完整代码见 Examples/Echo.py它包含服务端与客户端两部分。服务端创建example_utilities.echo.request命名的 SINGLE 入站目的地配置PROVE_ALL自动对每个入站包回送证明并通过set_packet_callback(server_callback)在收到请求时打印日志——包括从数据包或共享实例读取的 RSSI/SNR 无线信号指标视是否连接共享 RNS 实例而走不同取值路径。客户端把命令行传入的目的地十六进制哈希解析为字节长度必须等于RNS.Reticulum.TRUNCATED_HASHLENGTH//8字节即截断哈希长度先校验len(destination_hexhash) ! dest_len再bytes.fromhex。随后# 检查 RNS 是否已知到达目的地的路径 if RNS.Transport.has_path(destination_hash): # 取回服务器公钥身份构造出站目的地 server_identity RNS.Identity.recall(destination_hash) request_destination RNS.Destination( server_identity, RNS.Destination.OUT, RNS.Destination.SINGLE, APP_NAME, echo, request ) # 发送请求包得到投递回执 echo_request RNS.Packet(request_destination, RNS.Identity.get_random_hash()) packet_receipt echo_request.send() if timeout ! None: packet_receipt.set_timeout(timeout) packet_receipt.set_timeout_callback(packet_timed_out) packet_receipt.set_delivery_callback(packet_delivered) else: RNS.Transport.request_path(destination_hash) # 请求路径回执机制是理解 Reticulum 可靠性的关键set_delivery_callback当目的地对该包的证明被收到时自动调用。回调中检查receipt.status RNS.PacketReceipt.DELIVERED即表示投递成功并可调用receipt.get_rtt()计算往返时延1秒时以毫秒显示。set_timeout_callback超时未送达时触发receipt.status变为RNS.PacketReceipt.FAILED。若本地尚无路径则调用RNS.Transport.request_path(destination_hash)请求路径待 announce 到达后再重试。PacketReceipt类定义于 RNS/Packet.py与 Packet 一同构成 Reticulum 端到端可靠投递的底层支撑。Link建立端到端加密链路Link演示如何与远程目的地建立加密链路并在其上往返传输数据。完整代码见 Examples/Link.py。链路是 Reticulum 中面向连接的双向加密通道适用于需要持续、可靠、可确认通信的场景。服务端创建 SINGLE 目的地后通过set_link_established_callback(client_connected)注册新客户端接入回调。回调中获得link引用再注册链路关闭回调与数据包回调def client_connected(link): global latest_client_link RNS.log(Client connected) link.set_link_closed_callback(client_disconnected) link.set_packet_callback(server_packet_received) latest_client_link link收到链路数据后服务端构造RNS.Packet(latest_client_link, reply_data).send()回复——注意Packet 的目的地参数可以直接传 Link 实例这是链路通信与目的地通信的统一接口。客户端先用RNS.Transport.has_path/request_path确保已知路径RNS.Identity.recall取回服务器身份构造出站 SINGLE 目的地然后一行代码建立链路link RNS.Link(server_destination) link.set_packet_callback(client_packet_received) link.set_link_established_callback(link_established) link.set_link_closed_callback(link_closed)link_established回调中保存link引用交互循环发送文本前会校验长度if len(data) RNS.Link.MDU: RNS.Packet(server_link, data).send() else: RNS.log(... exceeds the link packet MDU of str(RNS.Link.MDU) bytes, RNS.LOG_ERROR)RNS.Link.MDU是链路单包最大数据单元Maximum Data Unit超过它将无法装入单个链路包。链路关闭回调中通过link.teardown_reason区分关闭原因RNS.Link.TIMEOUT链路超时、RNS.Link.DESTINATION_CLOSED对端主动关闭或其它情况。Link类实现位于 RNS/Link.py链路建立涉及基于身份密钥的端到端加密握手。Identify识别链路的发起方Identify在 Link 基础上增加对端身份识别一旦链路建立发起方主动向对端声明自己的身份。完整代码见 Examples/Identify.py。客户端在link_established回调中主动识别def link_established(link): global server_link, client_identity server_link link RNS.log(Link established with server, identifying to remote peer...) link.identify(client_identity)服务端在client_connected中注册识别回调并在收到数据时查询对端身份link.set_remote_identified_callback(remote_identified) # ... def remote_identified(link, identity): RNS.log(Remote identified as: str(identity)) # 在数据回调中 if packet.link.get_remote_identity() ! None: remote_peer str(packet.link.get_remote_identity())在RNS.Link中identify(identity)通过链路向对端发送身份声明get_remote_identity()返回对端已声明的Identity实例set_remote_identified_callback则在收到对端身份声明时触发。这为上层应用提供了这条链路的另一端到底是谁的可验证信息可在此基础上实现访问控制或会话绑定。Requests Responses链路请求/响应模式Request演示基于链路的请求/响应RPC 风格交互。完整代码见 Examples/Request.py。服务端用register_request_handler注册请求处理器并指定允许策略server_destination.register_request_handler( /random/text, response_generator random_text_generator, allow RNS.Destination.ALLOW_ALL )请求路径字符串如/random/text用于区分不同请求response_generator是生成响应的回调签名包含path, data, request_id, link_id, remote_identity, requested_atallow为请求许可策略RNS/Destination.py 中定义有ALLOW_ALL0x01、ALLOW_NONE与ALLOW_LIST仅允许列表中已识别对端。客户端通过link.request()发起请求并注册响应与失败回调server_link.request( /random/text, data None, response_callback got_response, failed_callback request_failed ) def got_response(request_receipt): RNS.log(Got response for request RNS.prettyhexrep(request_receipt.request_id): str(request_receipt.response))request()返回并最终通过回调传递一个request_receipt对象携带request_id与response。服务端响应由response_generator生成客户端通过request_receipt.response读取。这一模式适合在链路上实现带语义的远程调用而不必自行设计请求/响应的包格式与关联逻辑。Channel在链路上传输结构化消息Channel演示在链路对端之间传输结构化消息。完整代码见 Examples/Channel.py。Channel 的核心是RNS.MessageBase消息基类定义于 RNS/Channel.py消息必须继承它并实现序列化/反序列化协议Channel 才能把消息对象打包进数据包、在接收端还原并与其他消息类型多路复用。链路两端必须注册相同的消息类型定义才能互通。示例定义了一个携带字符串与时间戳的StringMessageclass StringMessage(RNS.MessageBase): # 2 字节整数用于在接收端查找对应消息类的构造器 # 在同一 Channel 内必须唯一 0xf000 的系统消息类型被保留 MSGTYPE 0x0101 # 构造器必须可无参调用参数需有默认值 # 以便 Channel 创建空消息实例用于解包 def __init__(self, dataNone): self.data data self.timestamp datetime.now() def pack(self) - bytes: return umsgpack.packb((self.data, self.timestamp)) def unpack(self, raw): self.data, self.timestamp umsgpack.unpackb(raw)pack/unpack分别把消息编成/解出字节流示例使用 RNS 捆绑的RNS.vendor.umsgpack也可用 Pythonstruct做更底层的字节布局控制。打包后的消息必须能完整装入一个数据包——可用Channel.MDU属性查询信道单包载荷上限它因消息头编码而略小于Link.MDU。双方在链路建立后取得并配置各自的 Channelchannel link.get_channel() channel.register_message_type(StringMessage) channel.add_message_handler(server_message_received) # 客户端同理发送方用channel.is_ready_to_send()确认信道空闲并以len(message.pack()) channel.mdu校验打包尺寸后channel.send(message)。消息处理器按注册顺序被依次调用若某个处理器返回True则视为已处理、跳过后续处理器——示例服务端在回复后返回True即利用了这一语义。Buffer链路缓冲读写流Buffer演示在链路上以缓冲读写器方式传输二进制数据。完整代码见 Examples/Buffer.py。对连续、可能较大的字节流逐包构造过于繁琐RNS.Buffer提供类似文件读写的流式抽象实现位于 RNS/Buffer.py。两端在链路建立后各创建一个双向缓冲channel link.get_channel() latest_buffer RNS.Buffer.create_bidirectional_buffer(0, 0, channel, server_buffer_ready)stream_id参数类似文件描述符但它是相对于接收方唯一的示例中读写两端都使用stream_id 0实际是两条方向相反的单向流。create_bidirectional_buffer返回一个 Buffer 实例注册的ready回调在有数据可读时被调用并传入可读字节数def server_buffer_ready(ready_bytes: int): data latest_buffer.read(ready_bytes) RNS.log(Received data over the buffer: data.decode(utf-8)) reply_message I received \data\ over the buffer.encode(utf-8) latest_buffer.write(reply_message) latest_buffer.flush()发送端流程为buffer.write(text)后buffer.flush()强制把缓冲数据发出多客户端场景下旧连接的 buffer 用buffer.close()关闭。Buffer 把分段、排队、流控从应用逻辑中剥离适合需要像串口或管道一样持续读写数据流的应用。Filetransfer用 Resource 传输任意大小文件Filetransfer实现一个基础文件服务器客户端可列出并下载服务器目录中的文件。完整代码见 Examples/Filetransfer.py。文件数据通过Resource接口高效传输——RNS.Resource实现于 RNS/Resource.py把数据源分片、压缩、加密并序列化地经链路传输接收端自动重组。服务端客户端接入后先把文件清单用umsgpack.packb(list_files())打包若不超过RNS.Link.MDU则单包发送并设置APP_TIMEOUT 45.0秒的回执超时与投递回调收到客户端点名请求后用文件句柄构造 Resource 发送file_resource RNS.Resource( file, packet.link, callbackresource_sending_concluded ) file_resource.filename filename客户端把链路资源策略设为全量接收并注册资源开始/结束回调link.set_resource_strategy(RNS.Link.ACCEPT_ALL) link.set_resource_started_callback(download_began) link.set_resource_concluded_callback(download_concluded)下载期间用current_download.get_progress()渲染百分比进度结束后通过resource.status RNS.Resource.COMPLETE或FAILED判断成败用resource.data.read()读取重组后的完整数据写入磁盘并统计resource.total_size、实际传输量resource.size与耗时打印时间/文件大小/有效速率/传输速率统计。文档在示例注释中给出重要工程提示用 RNS Resource 传输大文件并不被推荐——压缩、加密与哈希表分片在慢 CPU 上耗时可能超过客户端超时需要传输大文件时应改用Bundle类它会自动把数据切成适合打包为 Resource 的块。这正是资源 链路 回执组合在实际工程中的边界条件值得在选型时注意。ExampleInterface编写并热加载自定义接口ExampleInterface演示如何为 Reticulum 编写自定义接口并说明其能力与原生接口完全对等支持全部接口模式如 gateway、boundary、access point 等与通用配置选项。完整代码见 Examples/ExampleInterface.py。接口类必须继承RNS.Interface基类位于 RNS/Interfaces/Interface.py构造器签名固定为__init__(self, owner, configuration)其中owner是所属的 RNS Transport 实例configuration是配置字典。示例实现了一个串口接口其核心结构如下class ExampleInterface(Interface): DEFAULT_IFAC_SIZE 8 # 未指定 IFAC 尺寸时的默认值字节 def __init__(self, owner, configuration): # 依赖检查缺少 pyserial 时提示安装并 panic if importlib.util.find_spec(serial) ! None: import serial else: RNS.log(Using this interface requires a serial communication module to be installed., RNS.LOG_CRITICAL) RNS.panic() super().__init__() # 用基类方法规范化配置保证跨平台兼容 ifconf Interface.get_config_obj(configuration) self.name ifconf[name] # 读取参数并提供默认值 port ifconf[port] if port in ifconf else None speed int(ifconf[speed]) if speed in ifconf else 9600 databits int(ifconf[databits]) if databits in ifconf else 8 # ... 打开串口、配置设备、启动读线程 ... self.HW_MTU 564 # 底层介质不分割时的最大包载荷 self.bitrate speed需要实现的协议点包括HW_MTU向 Transport 声明底层介质能无分割承载的最大数据包载荷字节数online/bitrate状态属性process_incoming(data)收到完整数据帧时调用self.owner.inbound(data, self)交给 Transport 处理并累加self.rxb接收计数process_outgoing(data)Transport 要求发包时调用。示例先按简化 HDLC 帧FLAG0x7E、ESC0x7D、ESC_MASK0x20做字节转义与成帧再写入串口并累加self.txbread_loop()后台线程持续读串口字节、按 HDLC 标志解帧异常时置onlineFalse、关闭串口并进入reconnect_port()周期重连每 5 秒尝试__str__与文件末尾的interface_class ExampleInterface后者把接口类注册为 Reticulum 运行时加载的目标类。使用方式把该文件放入~/.reticulum/interfaces目录然后在 Reticulum 配置文件中加入对应接口条目示例中enabled no表示默认禁用[[Example Custom Interface]] type ExampleInterface enabled no mode gateway port /dev/ttyUSB0 speed 115200 databits 8 parity none stopbits 1文档明确说明可以创建并加载任意数量的自定义接口且它们与内置接口完全对等包括全部接口模式与通用配置选项。这套机制是 Reticulum 可扩展性的核心——新介质如自研无线电调制解调器、其它总线只需实现上述少量协议点即可接入网络栈。从示例到自己的应用把这 11 个示例连起来看正好构成 Reticulum 应用开发的能力阶梯Minimal让你在几行代码内接入网络Announce/Broadcast解决发现与公开信息Echo展示基于 Packet 的可靠投递与往返时延测量Link/Identify提供加密链路与对端身份Request带来请求/响应语义Channel/Buffer分别解决结构化消息与连续字节流Filetransfer示范资源传输与下载进度ExampleInterface则打开接入任意物理介质的大门。进一步深入学习时可对照阅读以下仓库内资料本文档源文件docs/source/examples.rst 与渲染版 docs/manual/examples.html全部示例源码Examples 目录Minimal.py、Announce.py、Broadcast.py、Echo.py、Link.py、Identify.py、Request.py、Channel.py、Buffer.py、Filetransfer.py、ExampleInterface.py核心 API 实现RNS/Destination.py、RNS/Packet.py、RNS/Link.py、RNS/Transport.py、RNS/Channel.py、RNS/Buffer.py、RNS/Resource.py、RNS/Interfaces/Interface.py参考手册docs/source/reference.rst 与接口专题 docs/source/interfaces.rst仓库测试用例如 tests/link.py、tests/ifac.py、tests/channel.py可验证本文所述 API 的实际调用方式与预期行为。建议的实践路径先在本机启动两个终端分别运行同一示例的服务端与客户端例如两个Echo一端加-s观察 announce 到达、路径建立与往返时延输出随后基于Minimal骨架把APP_NAME换成自己的应用名逐层叠加 announce 回调、Link 与 Request即可快速产出一个可运行的 Reticulum 应用。赞分享网络通信密码学IoT协议【免费下载链接】ReticulumThe cryptography-based networking stack for building unstoppable networks with LoRa, Packet Radio, WiFi and everything in between.项目地址https://gitcode.com/gh_mirrors/re/Reticulum点击查看免费下载相关推荐redux-form 自定义输入组件接入指南从最小接口到适配器封装redux form 自定义输入组件接入指南从最小接口到适配器封装 redux form 是一个通过 react redux 将表单状态托管到 Redux s前端UI组件Tokio 官方示例完全指南从 hello_world 到自定义执行器的实战入门Tokio 官方示例完全指南从 hello_world 到自定义执行器的实战入门 导读 本文基于 Tokio 仓库的 examples/README.md h后端异步编程通信并发编程react-diagrams 官方文档全指南从零上手到自定义节点、端口与链接react diagrams 官方文档全指南从零上手到自定义节点、端口与链接 本篇技术指南系统梳理 react diagrams 开源仓库a super sUI组件前端上一篇探秘Open edX配置项目打造高效在线学习平台下一篇【亲测免费】 以数据划分为核心的Iterative Stratification库智能且均衡的数据分割新选择创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。