Bytom怎么实现P2P网络upnp端口映射

免费建站   2024年05月10日 11:13  

这篇文章主要介绍“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代码

** /upnp/upnp.go **

发现网络中支持UPNP功能的设备

从网络中发现支持UPNP功能的设备,并得到该设备的location和url等相关信息

typeupnpNATstruct{serviceURLstring//设备的描述文件URL,用于得到该设备的描述信息ourIPstring//节点本地ip地址urnDomainstring//设备类型}funcDiscover()(natNAT,errerror){ssdp,err:=net.ResolveUDPAddr("udp4","239.255.255.250:1900")iferr!=nil{return}conn,err:=net.ListenPacket("udp4",":0")iferr!=nil{return}socket:=conn.(*net.UDPConn)defersocket.Close()err=socket.SetDeadline(time.Now().Add(3*time.Second))iferr!=nil{return}st:="InternetGatewayDevice:1"//多播请求:M-SEARCHSSDP协议定义的发现请求。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)fori:=0;i<3;i++{//向239.255.255.250:1900发送一条多播请求_,err=socket.WriteToUDP(message,ssdp)iferr!=nil{return}//如果从网络中发现UPNP设备则会从239.255.255.250:1900收到响应消息varnintn,_,err=socket.ReadFromUDP(answerBytes)for{n,_,err=socket.ReadFromUDP(answerBytes)iferr!=nil{break}answer:=string(answerBytes[0:n])ifstrings.Index(answer,st)<0{continue}//HTTPheaderfieldnamesarecase-insensitive.//http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2//获得设备locationlocString:="\r\nlocation:"answer=strings.ToLower(answer)locIndex:=strings.Index(answer,locString)iflocIndex<0{continue}loc:=answer[locIndex+len(locString):]endIndex:=strings.Index(loc,"\r\n")ifendIndex<0{continue}//获得设备的描述url和设备类型locURL:=strings.TrimSpace(loc[0:endIndex])varserviceURL,urnDomainstringserviceURL,urnDomain,err=getServiceURL(locURL)iferr!=nil{return}varourIPnet.IPourIP,err=localIPv4()iferr!=nil{return}nat=&upnpNAT{serviceURL:serviceURL,ourIP:ourIP.String(),urnDomain:urnDomain}return}}err=errors.New("UPnPportdiscoveryfailed.")return}添加端口映射

向upnp设备发送一条http post请求,将内部网络ip:port和外部网络ip:port做映射

func(n*upnpNAT)AddPortMapping(protocolstring,externalPort,internalPortint,descriptionstring,timeoutint)(mappedExternalPortint,errerror){//AsingleconcatenationwouldbreakARMcompilation.message:="<u:AddPortMappingxmlns:u=\"urn:"+n.urnDomain+":service:WANIPConnection:1\">\r\n"+"<NewRemoteHost></NewRemoteHost><NewExternalPort>"+strconv.Itoa(externalPort)message+="</NewExternalPort><NewProtocol>"+protocol+"</NewProtocol>"message+="<NewInternalPort>"+strconv.Itoa(internalPort)+"</NewInternalPort>"+"<NewInternalClient>"+n.ourIP+"</NewInternalClient>"+"<NewEnabled>1</NewEnabled><NewPortMappingDescription>"message+=description+"</NewPortMappingDescription><NewLeaseDuration>"+strconv.Itoa(timeout)+"</NewLeaseDuration></u:AddPortMapping>"varresponse*http.Responseresponse,err=soapRequest(n.serviceURL,"AddPortMapping",message,n.urnDomain)ifresponse!=nil{deferresponse.Body.Close()}iferr!=nil{return}//TODO:checkresponsetoseeiftheportwasforwarded//log.Println(message,response)//JAE://body,err:=ioutil.ReadAll(response.Body)//fmt.Println(string(body),err)mappedExternalPort=externalPort_=responsereturn}删除端口映射

向upnp设备发送一条http post请求,将内部网络ip:port和外部网络ip:port删除映射关系

func(n*upnpNAT)DeletePortMapping(protocolstring,externalPort,internalPortint)(errerror){message:="<u:DeletePortMappingxmlns:u=\"urn:"+n.urnDomain+":service:WANIPConnection:1\">\r\n"+"<NewRemoteHost></NewRemoteHost><NewExternalPort>"+strconv.Itoa(externalPort)+"</NewExternalPort><NewProtocol>"+protocol+"</NewProtocol>"+"</u:DeletePortMapping>"varresponse*http.Responseresponse,err=soapRequest(n.serviceURL,"DeletePortMapping",message,n.urnDomain)ifresponse!=nil{deferresponse.Body.Close()}iferr!=nil{return}//TODO:checkresponsetoseeiftheportwasdeleted//log.Println(message,response)_=responsereturn}获取映射后的公网地址func(n*upnpNAT)GetExternalAddress()(addrnet.IP,errerror){info,err:=n.getExternalIPAddress()iferr!=nil{return}addr=net.ParseIP(info.externalIpAddress)return}func(n*upnpNAT)getExternalIPAddress()(infostatusInfo,errerror){message:="<u:GetExternalIPAddressxmlns:u=\"urn:"+n.urnDomain+":service:WANIPConnection:1\">\r\n"+"</u:GetExternalIPAddress>"varresponse*http.Responseresponse,err=soapRequest(n.serviceURL,"GetExternalIPAddress",message,n.urnDomain)ifresponse!=nil{deferresponse.Body.Close()}iferr!=nil{return}varenvelopeEnvelopedata,err:=ioutil.ReadAll(response.Body)reader:=bytes.NewReader(data)xml.NewDecoder(reader).Decode(&envelope)info=statusInfo{envelope.Soap.ExternalIP.IPAddress}iferr!=nil{return}return}

到此,关于“Bytom怎么实现P2P网络upnp端口映射”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

域名注册
购买VPS主机

您或许对下面这些文章有兴趣:                    本月吐槽辛苦排行榜

看贴要回贴有N种理由!看帖不回贴的后果你懂得的!


评论内容 (*必填):
(Ctrl + Enter提交)   

部落快速搜索栏

各类专题梳理

网站导航栏

X
返回顶部