P2P网络中的节点发现

在P2P网络中,要发现并连接其他节点,常见的是通过种子节点连接到网络,然后通过种子节点获取其他节点的地址。以太坊的种子节点在cmd/swarm/bootnodes.go中定义,hpb的种子节点在config/networkconfig.go中定义

以hpb节点为例说明:https://github.com/hpb-project/go-hpb,以太坊基本是一样的。
1、节点启动的时候调用server.go的start(),除了建立监听端口之外,还需要将bootnodes信息添加到静态节点变量中,通过setfallbacknodes函数和newdialstate函数实现
2、在start的最后go run(),开启连接节点的任务
3、在server.go 的run()中,通过newTasks函数创建新的连接任务,在newtasks中可以看到,节点信息的来源有两个:一个是静态节点,一个是ntab的buckets。节前刚启动的时候buckets当然是空的,只能靠静态节点,即bootnodes接入网络。
4、有了任务,就可以连接对应的节点了,run函数中通过starttasks函数进行节点的连接,实际执行的函数是task.do()–>dial.go中的dialtask.dial()。 通过dialer.Dial()建立TCP连接,然后通过setupconn进行握手校验。校验通过后连接正式建立,校验失败会断开连接。

以上即为bootnode的连接,到此,新节点已连接成功bootnode,接下来需要通过bootnode获取其他节点信息并建立连接。

6、在setupconn的最后有个checkpoint函数,至此触发addpeer事件。 addpeer事件的处理在第3步提到的run函数中。然后通过server.runpeer(),实际为peerbase.run()来保持连接。
7、在peerbase.run()中,可以看到有个 go updatenodesloop(),在这里将开始于bootnode请求其他节点信息。
8、从updatenodesloop函数可以看出,这里通过定时器每15s进行一次节点请求。
9、当前节点在收到bootnode返回的节点后,在protocol.go的handleresnodesmsg函数中处理,通过bondall函数一步一步将所有节点信息写入自己的buckets中。(其中bootnode收到请求后,在protocol.go的handelreqnodesmsg函数中处理,将自己的节点从buckets取出并发给请求者。)
10、至此,重复第3步的时候,buckets中就有了其他节点的信息,可以与其他节点进行连接了。

在实际应用中,能拿到网络中所有节点的信息,可能受操作系统,防火墙,网络等因素影响不一定所有的节点都能连接上。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值