go语言代码实现区块链-P2P节点发现(二)
程序员文章站
2022-07-01 15:30:30
...
继续上一章节
Loop函数代码如下:
func(k *Kad) loop(){
log.Println("go loop...")
loop:
for{
select{
case <-k.ticker.C:
//定时检测node数量,如果小于N,执行节点发现
go k.checkNodes()
case n:=<-k.tc:
//将距离随机几点最近的节点写入K桶
go k.findNodes(true,n)
case n:=<-k.sc:
//将距离随机几点最近的节点写入远程节点的K桶
go k.findNodes(false,n)
case <-k.closed:
break loop
}
}
}
CheckNodes函数代码如下:
//检测当前正常连接的节点
func(k *Kad)checkNodes(){
log.Println("start checkNodes...")
currentNode:=k.nodes
l:=len(currentNode)
if l==0{
//写入种子节点至Nodes中
if !Besends{
k.nodes=append(k.nodes,nil)
}
}
var targetID NodeID
if l<minNodes{
log.Println("start findnode...")
//节点查找
rand.Read(targetID[:])
node:=Node{Addr:k.currendNode.Addr,TargetID:targetID,}
k.tc<-node
}else{
for _,n:=range currentNode{
info:=Msg_Beat0+k.currendNode.Addr //发送心跳消息
Udpconn.WriteToUDP([]byte(info),n.Addr)
}
//5秒后判断是否回应
time.Sleep(time.Duration(5)*time.Second)
k.mutex_a.Lock()
defer k.mutex_a.Unlock()
for _,n:=range currentNode{
if !k.askedCons(n.Nodeid){
k.deleteNode(n)
}
}
l=len(k.nodes)
if l==0{
//写入种子节点至Nodes中
if !Besends{
k.nodes=append(k.nodes,nil)
}
}
if l<minNodes{
log.Println("start findnode...")
rand.Read(targetID[:])
k.tc<-Node{Addr:k.currendNode.Addr,TargetID:targetID,}
}
}
}
检测节点的流程是首先判断已经连接的节点数量是否小于最小连接数,如果等于0,先将种子节点放入K桶,依次向K桶中的Node发送FindNode指令,依次获取距离随机节点更近的节点。
//计算节点和随机节点的异或距离
func(k *Kad)distance(node *Node,t NodeID)(uint8,*Node){
ct:=EOR(k.currendNode.Nodeid,t)
nt:=EOR(node.Nodeid,t)
var i uint8
for i=0;i<HashBits/8;i++{
if nt[i]==ct[i]{
continue
}
if nt[i]<ct[i]{
node.index=i
node.distance=nt[i]
return i,node
}else{
break
}
}
return 0,nil
}
//异或计算
func EOR(tnode,fnode NodeID)NodeID{
var n NodeID
for i:=0;i<HashBits/8;i++{
n[i]=tnode[i]^fnode[i]
}
return n
}
下一篇: webrtc demo搜集(转)