p2p网络中的节点发现之UDP

http://blockgeek.org/t/topic/1915
server启动的时候,除了监听本地的tcp端口之外,还启动了udp端口的监听,而且udp端口的监听与udp通信在节点发现的时候起着关键作用。
先看下为什么udp在节点发现中起着关键作用。
https://blog.csdn.net/adwen2009/article/details/82878626 介绍了在节点启动后连接到bootnode节点,然后每隔15s向bootnode发送ReqNodesMsg请求其他节点信息,收到bootnode节点返回的ResNodesMsg信息后,将节点信息放入到buckets中。前文介绍的节点的连接,nodesmsg的互换等都是通过TCP连接进行的。但在将节点信息放入buckets之前,是有一个节点的校验的,这里的校验是通过udp pingpong来实现的,如果udp的ping消息得不到正确的回应,则当前节点是不会加入到buckets中的,所以说udp在这里是起了关键作用。具体代码可参照table.go中的pingpong函数,从ping函数中可以看到,tab.net是实现ping的关键,这里的net就是包含了udp连接的结构体,下面看一下这个net的来源。

在server启动的时候,有一个UDP端口的监听,即下面的代码
ntab, ourend, err := discover.ListenUDP(…)
在这个函数中主要做了3件事
1、通过ResolveUDPAddr查询端口和IP地址是否可用,并返回一个UDPAddr
2、通过ListenUDP监听udp端口,创建一个接收目的地是本地地址UDPAddr的UDP数据包的网络连接conn,此连接
3、封装一个新的UDP结构体,在这个newUDP中有个newTable,传参为udp,对应的就是table.net属性。这就解释了net的来源问题。
4、在newUDP中还启动了两个线程,loop()和readloop()。其中loop()中主要是对收到的消息进行校验,readloop中主要是接收来自其他节点的消息,这里的消息包括ping消息,pong消息,nodeReq,nodeRes消息,主要是ping,pong消息,实际上节点信息交换用的TCP,而不是这里的udp。

另外从代码send函数中可以看出udp的消息传递是明文的,并没有进行加密,只是做了下签名

猜你喜欢

转载自blog.csdn.net/adwen2009/article/details/84790459