python-ndn分析
Python-ndn是Python 3 中支持 AsyncIO 的命名数据网络客户端库。
个人理解:通过调用python-ndn库可以创建新的客户端节点,节点可以产生和接收兴趣包和数据包,节点需要通过NFD进行路由和转发。
简介:ndn.app 包包含类 NDNApp ,它连接 NDN 应用程序和 NFD 节点。NDNApp 提供类似于ndn-cxx 中的应用程序Face 的功能,包括:建立与NFD 节点的连接。表达兴趣并处理返回的数据。使用兴趣处理函数注册和取消注册路由。
/home/ygtrece/.local/lib/python3.6/site-packages/
ndn.app模块包括构造函数,创建用于连接NFD节点的face,(平台默认的接口,Linux下是Unix接口),用于存储身份和密钥的keychain,兴趣包和数据包的默认验证器。
async def _receive(self, typ: int, data: BinaryStr):函数用于根据不同的包的类型(兴趣包,数据包,Nack包)对包进行解析,提取出对应的字段,并根据包的类型不同调用后续的 _on_xxx函数
put_raw_packet()函数用于调用self.face.send()发送一个data包,发送数据包。
prepare_data()函数通过生成、编码和签名来准备数据包,调用make_data()。
put_data()结合了put_raw_packet()和prepare_data()。
express_interest()函数用于立即发送兴趣包并返回用于获取结果的协程。其调用express_raw_interest()函数。express_raw_interest()函数通过self.face.send(raw_interest)发送兴趣包,然后调用_wait_for_data()阻塞等待,_wait_for_data()调用底层系统函数aio.wait_for()等待数据包到来,直到收到数据并返回该数据。如果无法接收数据或者超过约定的超时时间,则会引发异常。
main_loop()函数:param after_start: 与 NFD 建立连接后启动的协程。:return: True
如果连接不是由Ctrl+C
关闭的。例如,手动或通过对方。调用starting_task()函数,self.register()函数进行自身信息的登记。然后等待self.face.open()和self.face.run()。after_start:与 NFD 建立连接后启动的协程。
route()函数:用于为特定前缀注册永久路由的装饰器。该函数是非阻塞的,可以随时调用。如果在连接 NFD 之前调用它,NDNApp 会记住这条路由,并在每次建立连接时自动注册。将此路由注册到 NFD 失败将被忽略。
register函数:动态注册特定前缀的路由。
unregister函数:取消注册特定前缀的路由。
set_interest_filter:设置兴趣前缀的回调函数,无需向转发器发送注册命令。
unset_interest_filter:删除兴趣前缀的回调函数,而不发送取消注册命令。
关键参数:
这些参数用于填写数据包的 MetaInfo 字段。
- meta_info (MetaInfo) - Data 的 MetaInfo 字段。 所有其他相关参数将被忽略。
- content_type (int) - 内容类型。 ContentType.BLOB 默认情况下。
- freshness_period (int) - FreshnessPeriod 以毫秒为单位。 默认情况下无。
- final_block_id (BinaryStr) - FinalBlockId。 它应该是一个编码的组件。 默认情况下无。
这些参数用于填写兴趣包的字段。
- interest_param (InterestParam) - 包含所有参数的数据类。 所有其他相关参数将被忽略。
- can_be_prefix (bool) - CanBePrefix。 默认为假。
- must_be_fresh (bool) - MustBeFresh。 默认为假。
- nonce (int) - 随机数。 默认情况下会生成一个随机数。 要省略 Nonce,请明确将 None 传递给此参数。生命周期 (int) - InterestLifetime 以毫秒为单位。 默认为 4000。
- hop_limit (int) - HopLimit。 默认情况下无。
- forwarding_hint (list[NonStrictName]) - 参见 InterestParam。
签名:这些参数用于决定兴趣包或数据包如何签名以及由哪个签名者签名。 每个 Keychain 支持的参数都不同。 此处仅列出默认Keychain 支持的那些。 如果存在冲突,则参数越早列出其优先级越高。
简介:ndn.encoding 包包含有助于对 NDN 名称、名称组件、数据和兴趣进行编码和解码的类和函数。
这个包包含三个部分: TLV 元素:处理 TLV 变量、Names 和 NameComponents。
TlvModel:设计一种描述 TLV 格式的通用方式。 TLV 对象可以用派生自 TlVModel 的类来描述,其成员类型为 Field。
NDN Packet Fotmat v0.3:用于在 NDN Packet Format Spec 0.3 中编码和解析兴趣包和数据包的函数。
1 | def make_interest(name: NonStrictName, |
简介:ndn.security 包提供了安全使用的基本工具。
简介:ndn.schema 包提供了名称树模式的实现,这是一个应用程序框架,通过应用程序命名空间组织应用程序功能。 可以基于它开发模块化的 NDN 库,应用程序开发人员可以使用这些库作为构建块。
NTSchema 的核心概念是命名空间模式树。 模式树是一个包含应用程序所有可能的命名约定的树结构。 与名称树不同,它的边缘可能是模式变量,而不是特定的名称组件。 例如,路径 /<Identity>/KEY/<KeyID>
可用于表示键的命名约定,其中特定键 - 例如 /Alice/KEY/%01
和 /Bob/KEY/%c2
与之匹配 .
NTSchema 的两个主要组件是自定义节点和策略。 在模式树中,每个节点都代表一个命名空间。 与特定名称匹配后,节点可用于生产和消费数据。 例如,如果我们调用matched_node = tree.match('/Alice/KEY/%01')
,它将返回一个匹配节点/<Identity>/KEY/<KeyID>
,变量设置Identity='Alice', KeyID =\x01
。 然后我们调用matched_node.provide(key_data)
,它将生成带有数据key_data
的密钥并使其可用。 当我们调用 key_data =matched_node.need()
时,它会尝试获取密钥。 自定义节点将具有自定义管道来处理提供和需要函数调用。 策略是附加到节点的注释,指定用户定义的安全、存储等策略。
基本应用:
NDNApp 连接到 NFD 节点,并提供表达和处理兴趣的接口。以下代码使用默认配置初始化 NDNApp 实例。
1 | from ndn.app import NDNApp #从ndn.app导入NDNApp函数 |
如果应用程序有 main 函数,请使用该参数。
1 | from ndn.app import NDNApp #从ndn.app导入NDNApp函数 |
消费者:
1 | from ndn.encoding import Name |
生产者
生产者可以调用以注册永久路由。可以在启动应用程序之前完成路由注册。NDNApp 将自动宣布该路由到 NFD 节点。
1 |
|
python-ndn
提供了一种描述性方法来定义特定的 TLV 格式,称为 TLV 模型。每个对象都可以由从 TlvModel
派生的类来描述。TLV 对象的元素表示为 Field
的实例变量。字段按顺序编码。
1 | from ndn.encoding import * |
TLV 模型中没有必填字段。默认情况下,每个字段
都是,这意味着它不会被编码。None
嵌套模型
python-ndn
允许一个 TLV 模型是另一个 TLV 模型的字段(ModelField
),从而实现分层结构。此外,TLV 模型不包含外部“类型”和“长度”。这可以通过将它封装到另一个TLV模型中来解决。
1 | class Inner(TlvModel): # Inner = [Val1] |
重复模型
重复字段
是特定类型字段的数组。编码时,元素按顺序编码。
1 | class WordArray(TlvModel): # WordArray = *Words |
派生
为了避免重复,TlvModel
可以扩展1个或多个其他TlvModels。但是,要指示 TLV 编码导线中基类的位置,必须为每个基类提供一个字段以显式包含其基类。这些字段必须具有值 IncludeBase
。无法分配 TlvModel 实例的包含字段,并且在编码和解析过程中将被忽略。
1 | class Base(TlvModel): # Base = [M2] |
重写
派生类可以重写其基类的字段。若要覆盖字段,请在包含后声明具有相同名称的字段。覆盖字段将在其原始位置进行编码,与声明顺序无关。
1 | class A1(TlvModel): # A1 = [M1] |
解析
TlvModel可以从导线解析。所有字段都按顺序解析。如果无序或未知字段是非关键字段,则忽略这些字段。未知的临界场导致 解码错误
。
1 | from ndn.encoding import * |
1 | def prepare_data(self, name: NonStrictName, content: Optional[BinaryStr] = None, **kwargs): |
1 | def express_interest(self, |
1 | async def _wait_for_data(self, future: aio.Future, lifetime: int, name: FormalName, node: InterestTreeNode, validator: Validator, need_raw_packet: bool): |
python-ndn提供了一种描述性方法来定义特定的 TLV 格式,称为 TLV 模型。每个对象都可以由从 TlvModel 派生的类来描述。TLV 对象的元素表示为 Field 的实例变量。字段按顺序编码。
python-ndn允许一个 TLV 模型是另一个 TLV 模型的字段ModelField,从而实现分层结构。此外,TLV 模型不包含外部“类型”和“长度”。这可以通过将它封装到另一个TLV模型中来解决。
consumer:
1 | from ndn.app import NDNApp |
producer:
1 | from ndn.app import NDNApp |
producer2
1 | from ndn.app import NDNApp |