Bytom怎么实现P2P网络upnp端口映射
发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,这篇文章主要介绍"Bytom怎么实现P2P网络upnp端口映射",在日常操作中,相信很多人在Bytom怎么实现P2P网络upnp端口映射问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希
千家信息网最后更新 2026年11月02日Bytom怎么实现P2P网络upnp端口映射
这篇文章主要介绍"Bytom怎么实现P2P网络upnp端口映射",在日常操作中,相信很多人在Bytom怎么实现P2P网络upnp端口映射问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"Bytom怎么实现P2P网络upnp端口映射"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
UPNP介绍
UPNP(Universal Plug and Play)通用即插即用。UPNP端口映射将一个外部端口映射到一个内网ip:port。从而实现p2p网络从外网能够穿透网关访问到内网的bytomd节点。
UPNP协议
SSDP(Simple Service Discovery Protocol 简单服务发现协议) GENA(Generic Event Notification Architecture 通用事件通知结构) SOAP(Simple Object Access Protocol 简单对象访问协议) XML(Extensible Markup Language 可扩张标记语言)
UPNP代码
** p2p/upnp/upnp.go **
发现网络中支持UPNP功能的设备
从网络中发现支持UPNP功能的设备,并得到该设备的location和url等相关信息
type upnpNAT struct { serviceURL string // 设备的描述文件URL,用于得到该设备的描述信息 ourIP string // 节点本地ip地址 urnDomain string // 设备类型}func Discover() (nat NAT, err error) { ssdp, err := net.ResolveUDPAddr("udp4", "239.255.255.250:1900") if err != nil { return } conn, err := net.ListenPacket("udp4", ":0") if err != nil { return } socket := conn.(*net.UDPConn) defer socket.Close() err = socket.SetDeadline(time.Now().Add(3 * time.Second)) if err != nil { return } st := "InternetGatewayDevice:1" // 多播请求:M-SEARCH SSDP协议定义的发现请求。 buf := bytes.NewBufferString( "M-SEARCH * HTTP/1.1\r\n" + "HOST: 239.255.255.250:1900\r\n" + "ST: ssdp:all\r\n" + "MAN: \"ssdp:discover\"\r\n" + "MX: 2\r\n\r\n") message := buf.Bytes() answerBytes := make([]byte, 1024) for i := 0; i < 3; i++ { // 向239.255.255.250:1900发送一条多播请求 _, err = socket.WriteToUDP(message, ssdp) if err != nil { return } // 如果从网络中发现UPNP设备则会从239.255.255.250:1900收到响应消息 var n int n, _, err = socket.ReadFromUDP(answerBytes) for { n, _, err = socket.ReadFromUDP(answerBytes) if err != nil { break } answer := string(answerBytes[0:n]) if strings.Index(answer, st) < 0 { continue } // HTTP header field names are case-insensitive. // http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2 // 获得设备location locString := "\r\nlocation:" answer = strings.ToLower(answer) locIndex := strings.Index(answer, locString) if locIndex < 0 { continue } loc := answer[locIndex+len(locString):] endIndex := strings.Index(loc, "\r\n") if endIndex < 0 { continue } // 获得设备的描述url和设备类型 locURL := strings.TrimSpace(loc[0:endIndex]) var serviceURL, urnDomain string serviceURL, urnDomain, err = getServiceURL(locURL) if err != nil { return } var ourIP net.IP ourIP, err = localIPv4() if err != nil { return } nat = &upnpNAT{serviceURL: serviceURL, ourIP: ourIP.String(), urnDomain: urnDomain} return } } err = errors.New("UPnP port discovery failed.") return}添加端口映射
向upnp设备发送一条http post请求,将内部网络ip:port和外部网络ip:port做映射
func (n *upnpNAT) AddPortMapping(protocol string, externalPort, internalPort int, description string, timeout int) (mappedExternalPort int, err error) { // A single concatenation would break ARM compilation. message := "\r\n" + "" + strconv.Itoa(externalPort) message += " " + protocol + " " message += "" + strconv.Itoa(internalPort) + " " + "" + n.ourIP + " " + "1 " message += description + " " + strconv.Itoa(timeout) + " " var response *http.Response response, err = soapRequest(n.serviceURL, "AddPortMapping", message, n.urnDomain) if response != nil { defer response.Body.Close() } if err != nil { return } // TODO: check response to see if the port was forwarded // log.Println(message, response) // JAE: // body, err := ioutil.ReadAll(response.Body) // fmt.Println(string(body), err) mappedExternalPort = externalPort _ = response return}删除端口映射
向upnp设备发送一条http post请求,将内部网络ip:port和外部网络ip:port删除映射关系
func (n *upnpNAT) DeletePortMapping(protocol string, externalPort, internalPort int) (err error) { message := "\r\n" + "" + strconv.Itoa(externalPort) + " " + protocol + " " + " " var response *http.Response response, err = soapRequest(n.serviceURL, "DeletePortMapping", message, n.urnDomain) if response != nil { defer response.Body.Close() } if err != nil { return } // TODO: check response to see if the port was deleted // log.Println(message, response) _ = response return}获取映射后的公网地址
func (n *upnpNAT) GetExternalAddress() (addr net.IP, err error) { info, err := n.getExternalIPAddress() if err != nil { return } addr = net.ParseIP(info.externalIpAddress) return}func (n *upnpNAT) getExternalIPAddress() (info statusInfo, err error) { message := "\r\n" + " " var response *http.Response response, err = soapRequest(n.serviceURL, "GetExternalIPAddress", message, n.urnDomain) if response != nil { defer response.Body.Close() } if err != nil { return } var envelope Envelope data, err := ioutil.ReadAll(response.Body) reader := bytes.NewReader(data) xml.NewDecoder(reader).Decode(&envelope) info = statusInfo{envelope.Soap.ExternalIP.IPAddress} if err != nil { return } return}到此,关于"Bytom怎么实现P2P网络upnp端口映射"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!
网络
设备
端口
学习
信息
功能
地址
更多
类型
节点
帮助
支持
实用
接下来
事件
代码
对象
文件
文章
方法
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
蓝思科技飞鸽互联网
互联网金融监管科技数据
科技和互联网公司
互联网科技有限公司经营范围
圆梦互联网科技
朗新科技与工业互联网
北京互联网科技公司
有木互联网科技
伴你行互联网科技有限公司
互联网科技股有哪些
河南猎农互联网科技有限公司
岳阳华臻互联网科技有限公司
互联网行业科技股
深圳市罗太互联网科技有限公司
山东子淼互联网科技有限公司
山东星卡互联网科技有限公司官网
电子商务与互联网科技的关系
上海互联网科技公司ppt
下一代互联网重大应用科技园
盐城市攀科互联网科技有限公司
咖啡豆
博彦科技互联网金融
今日互联网科技
中盈科技互联网信息有限公司
千方科技属于互联网企业吗
银川新华互联网科技学校联系电话
浙南科技城互联网大厦招聘
互联网安防科技感
互联网硬科技公司
青岛易易互联网科技