本文是《循序渐进比特币》系列第五篇文章-《P2P网络穿透技术在比特币中的应用》,希望对你有所帮助。
1 一个场景
你是否想过这样一个场景,同一个局域网内部的两部手机同时访问百度,百度怎么知道应该响应哪部手机,并且将响应内容分开?
2 打洞
上述问题就涉及到了“穿透内网”的技术,也叫打洞。打洞一般分为两种:
(1)路由器上做端口映射。这儿提供一篇参考文章,大家如果想弄,自己照着文章配置即可 https://blog.csdn.net/Andrewniu/article/details/75506723
(2)NAT打洞。意思是不在路由器上做映射了,而是在NAT上做映射。
那什么是NAT呢?什么又是NAT打洞呢?
3 NAT介绍
NAT: Network Address Translation. 网络地址转换。其是在 IPv4 地址不够,而IPv6 又推广不给力的场景下产生的。A/B/C 三类网络都留了一个地址端,用作局域网内的机器使用,局域网对外只有一个外网IP。
NAT很好,但是如果从外部想访问局域网内的某个服务,是很难的。那就需要NAT打洞。
4 NAT打洞
NAT打洞就是在NAT上 配置内网服务端口 跟对外输出时的映射关系, 这样如果外部请求想找内部的某个服务,只要知道内部服务对应的外网ip以及 在NAT上对应的转发端口 就可以直接访问内网服务了。
NAT打洞有多种实现技术(STUN、TURN、UPNP),由于比特币中使用了UPNP,所以我们这儿只讲一下UPNP的步骤:
(1) 发送查找消息:
- 一个设备添加到网络以后,会多播大量发现消息来通知其嵌入式设备和服务,所有的控制点都可以监听多播地址以接收通知,标准的多播地址是239.255.255.250:1900。
(2) 获得根设备描述url
- 如果网络中存在upnp设备,此设备会向发送了查找请求的多播通道的源IP地址和端口发送响应消息
(3) 通过(2)中找到的设备描述URL的地址得到设备描述URL得到XML文档。
(4) 进行端口映射
拿到设备的控制URL以后就可以发送控制信息了,比如添加本地节点到映射表等。
5 比特币中的UPNP应用
比特币网络中的 UPNP 实现了上述的流程。
Discover 过程:
- 首先是newServer 时,如果配置了upnp, 则会执行Discover方法。Discover中通过多播找到upnp设备, 然后组装一个upnpNAT对象,等待在server.start中使用。如果没有找到upnp设备,则返回nil.
upnpUpdateThread过程:
到了服务启动时(server.start ), 如果检查到第一步中Discover返回的NAT不为空,则执行upnpUpdateThread操作。
upnpUpdateThread 的核心逻辑是
(1)执行AddPortMapping : 利用内网的port 从upnp router上获取本地节点对应的外网port;并在外部UPNP设备上加载自己的映射信息。
(2)执行GetExternalAddress: 获取当前节点的外网IP
(3)执行 AddLocalAddress: 将映射信息也加载到本地的映射表。
6 总结
本文从一个场景出发,描述了P2P网络中的内网穿透问题,进而引出了NAT以及NAT打洞,接下来讲解了比特币网络中采用的打洞技术UPNP的原理,最后又简单描述了在比特币代码中是如何实现的。
7 参考文献
https://yq.aliyun.com/articles/683326
https://juejin.im/post/5b019ee66fb9a07ac85ab314
比特币源码
8 其他
本文是《循序渐进比特币》的第六篇-P2P网络穿透技术在比特币中的应用。
如果有疑问,可以直接留言,也可以关注公众号 “链人成长chainerup” 提问留言,或者加入知识星球“链人成长”~
网友评论