GO语言实现P2P网络-服务端代码实现

727 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 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可以断开AB的连接。
 4AB发送一个消息,此消息会被B所在的路由器丢弃。
 5BA发送一个消息,由于上一步A发送时,B地址已经处于A所在路由器列表中。
 6B发送成功后,B所在的路由器内部也记录了A的地址,双发可以正常通信。

使用UDP机制通过代码实现服务器端代码

我们可以使用UDP机制通过代码将上述过程进行代码实现。

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的公网地址是公开的,相当于媒婆。