用于对等网络的python库
py2p的Python项目详细描述
基本用法
要连接到网格网络,您将使用MeshSocket对象。您可以将其实例化如下:
>>>importpy2p>>>sock=py2p.MeshSocket('0.0.0.0',4444)
使用'0.0.0.0'将自动获取您的局域网地址。如果要使用面向外部的Internet连接,则需要按如下方式指定此地址:
>>>importpy2p>>>sock=py2p.MeshSocket('0.0.0.0',4444,out_addr=('8.8.8.8',8888))
此外,如果安装了pyopenssl或加密,则可以启用ssl加密。这是通过指定自定义协议对象来实现的,如下所示:
>>>importpy2p>>>sock=py2p.MeshSocket('0.0.0.0',4444,prot=py2p.protocol('mesh','SSL'))
最终这将是默认的,但在测试过程中,它将默认为纯文本。指定不同的协议对象将确保您只能连接到共享对象结构的人。所以如果有人有'mesh2'而不是'mesh',您将无法连接。
不幸的是,这次失败目前是无声的。因为这本质上是异步的,所以不可能引发Exception。因此,连接后最好执行以下检查:
>>>importpy2p,time>>>sock=py2p.MeshSocket('0.0.0.0',4444)>>>sock.connect('192.168.1.14',4567)>>>time.sleep(1)>>>assertsock.routing_table
要发送消息,应该使用send方法。您提供的每个参数都将对应于您的对等方接收的数据包。此外,还可以使用两个键控参数。flag将指定其他节点如何转发此消息。b'broadcast'将指示其他节点应该中继它。b'whisper'将指示您的对等方not应该中继它。还有其他技术上有效的选项,但不推荐使用。type将指定其他节点应该对其执行的操作。它默认为b'broadcast',这表示与正常值没有变化。还有其他有效的选项,但通常应该单独使用,除非您编写了处理程序(见下文)来执行此操作。
>>>sock.send('this is','a test')
接收比较简单。当您调用recv方法时,您将收到一条消息对象。这里列出了许多方法here。最值得注意的是,您可以使用Message.packets获取消息中的数据包,并使用Message.reply()直接回复。
>>>sock.send('Did you get this?')>>>msg=sock.recv()>>>print(msg)Message(type=b'whisper',packets=[b'yes',b'I did'],sender=b'6VnYj9LjoVLTvU3uPhy4nxm6yv2wEvhaRtGHeV9wwFngWGGqKAzuZ8jK6gFuvq737V')>>>print(msg.packets)[b'whisper',b'yes',b'I did']>>>formsginsock.recv(10):...msg.reply("Replying to a list")
高级用法
除此之外,您还可以为传入消息注册自定义处理程序。这将附加到所包含内容的末尾。在编写处理程序时,必须记住,只会向您传递消息对象和指向接收连接的链接。幸运的是,您可以从这些对象访问所需的所有内容。要查看每个方法都有哪些方法,请参见API docs。示例服务如下:
>>>defrelay_tx(msg,handler):..."""Relays bitcoin transactions to various services"""...packets=msg.packets# Gives a list of the non-metadata packets...server=msg.server# Returns your MeshSocket object...ifpackets[0]==b'tx_relay':# It's important that this flag is bytes...frompycoinimporttx,services...relay=tx.Tx.from_bin(packets[1])...services.blockchain_info.send_tx(relay)...services.insight.InsightProvider().send_tx(relay)...returnTrue# This tells the daemon to stop calling handlers...>>>importpy2p>>>sock=py2p.MeshSocket('0.0.0.0',4444)>>>sock.register_handler(relay_tx)
如果不带两个参数,register_handler将引发一个值错误。要帮助调试这些服务,可以在构造函数中指定调试级别。使用值5,可以看到它何时进入每个处理程序,以及进入或退出的每个消息。