持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第7天,点击查看活动详情
GO语言实现P2P网络
P2P是区块链节点通信的基础协议,使用起来比TCP协议要麻烦一些。因为通信的两个节点在两个独立的网络内部,在不清楚对方公网的IP的情况下,想要通信确实不容易。
实现P2P网络的通信过程
1、主机A向服务器s发出连接请求,S获得A主机的公网地址。 2、主机B向服务器S发出连接申请,S获得B主机的公网地址。 3、S将A地址发送B,将B地址发送给A,此后S可以断开A和B的连接。 4、A向B发送一个消息,此消息会被B所在的路由器丢弃。 5、B向A发送一个消息,由于上一步A发送时,B地址已经处于A所在路由器列表中。 6、B发送成功后,B所在的路由器内部也记录了A的地址,双发可以正常通信。
## 使用UDP机制通过代码实现服务器端代码 我们可以使用UDP机制通过代码将上述过程进行代码实现。 ```go package main
import ( "fmt" "net" "time" )
func main(){ //服务器启动侦听,定义端口 listener,:=net.ListenUDP("udp",&net.UDPAddr{Port: 9555}) defer listener.Close() //定义切片存放udp地址 peers:=make([]*net.UDPAddr,2,2) buf:=make([]byte,256) //从两个udp消息中获得连接的地址A和B n,addr,:=listener.ReadFromUDP(buf) fmt.Printf("read from <%s>:%s\n",addr.String(),buf[:n]) peers[0]=addr n,addr,_=listener.ReadFromUDP(buf) fmt.Printf("read from <%s>:%s\n",addr.String(),buf[:n]) peers[1]=addr fmt.Println("begin nat \n") //将A和B分别介绍 listener.WriteToUDP([]byte(peers[0].String()),peers[1]) listener.WriteToUDP([]byte(peers[1].String()),peers[0]) //睡眠,确保发送成功 time.Sleep(time.Second*10) } ``` 服务器端还是比较容易的,服务器s的公网地址是公开的,相当于媒婆。