区块链入门系列之P2P

区块链入门系列文章

区块链基本概念和名词解释
P2P
共识算法
梅克尔-帕特里夏树
从零开始搭建区块链

前言

为什么前面讲过P2P的概念了这里还要单独起一篇文章来讲解,因为前面只是讲解了P2P的基本概念,即各网络节点间是直接或间接连接起来的。但这里面还涉及到很多网络知识,如果不清楚,是没办法构建一个P2P网络的。

中心化架构

现在所处的Web2时代,绝大部分应用都是中心化架构,比如微X、淘X、百X、京X、抖X、美X、滴X等。这些应用都有个显著特点,那就是服务提供入口是固定的,也就是他们使用的服务域名地址是固定的。需要使用这些服务的用户可以通过DNS进行域名地址解析得到服务的IP地址,然后才能将流量发送到对应的服务器。不知道大家有没有思考过一个问题,我们在浏览器输入www.xx.com敲下回车到渲染完页面期间发生了上面事情呢?
下面我通过一个时序图来对这个过程进行简要叙述。

客户端 中继设备... DNS 服务端 查询Hosts解析域名地址 查找DNS服务IP配置 向DNS对应IP的服务器发送IP数据报文 对客户端所在子网进行地址映射 查找路由表经过若干次转发 且每经过一次转发都会在中继设备对应的子网中进行地址映射 将域名地址解析的IP报文转发到DNS服务器 根据域名情况进行递归解析 (最差时会在根服务获取到结果,简化掉中继设备的转发步骤) 向客户端所在的IP(地址映射后得出的) 发送域名地址解析后的数据报文 根据之前发送时每次转发映射的地址 查找路由表经过若干次转发 将域名地址得到的数据报文发送给客户端 仅仅是一个DNS域名解析 如果把网络层也考虑进去其步骤也是较为繁琐的 根据解析到的服务端IP向服务端发送请求数据报文 查找路由表经过若干次转发 且每经过一次转发都会在中继设备对应的子网中进行地址映射 将数据请求报文转发到服务端所在IP 内部经过复杂的处理后向客户端所在IP响应数据 根据之前发送时每次转发映射的地址 查找路由表经过若干次转发 将服务端的响应数据转发到客户端 客户端 中继设备... DNS 服务端

以上仅简要画出了网络层的转发规则,不涉及具体的转发算法、查表算法甚至传输层的网络协议握手步骤等。可以看出我们在访问中心服务器时,都需要经过很多中继设备的转发。什么是中继设备?就是数据报文在传输过程中每一次转发的物理或逻辑设备,比如路由器、信号放大器等。对于路由器来说,其管理着一个子网络。

端口1
端口2
端口...
端口n
路由器
节点1
节点2
节点...
节点n

子网络中,每个路由端口对应着一个终端节点,如果路由器有公网IP,进行地址映射时就会对该公网IP的某一个端口绑定上某个终端。而如果路由器没有公网IP,说明这是一个内网路由器,则会在路由器所在子网的IP上的某个端口绑定上某个终端。这个过程就对应上述时序图中中继设备间的跳转。现在问大家一个灵魂拷问的问题,为什么要进行地址映射?其实它也不想,它也想直接进行转发,可是…
在这里插入图片描述
因为IPv4的地址已经枯竭,无法满足海量互联设备的联网需求,所以只能设计出子网掩码将大量有联网需求的设备放到某个子网中,分配一个IP就对其进行管理,而且子网还能嵌套子网,理论上甚至可以无限套娃🤣

去中心化架构

既然中心化架构的情况下能进行地址映射,那去中心化架构同样也能实现呀,只要按照同样的套路就能实现既定结果。我只能说TYTS,中心化架构下,由于中心服务器都是有固定公网IP的,在进行地址映射时映射的结果相对比较固定。而放到去中心化架构中时就是另外一番光景了,因为网络中的节点不全是有公网IP的。对于存在公网IP的情况,其通信流程大致和上述时序图描述的类似,但对于两边没有公网IP时通信情况就不一样了。因为互相都不知道对方的IP地址,也就没办法率先发起请求,也就没办法进行地址映射。

无法感知到对方
非公网节点A
非公网节点B

这就需要用到NAT技术了。

NAT

即Network Address Translation,网络地址转换。其实吧,严格来说,上述中心化架构来说也使用到了NAT技术,只是该场景由于通信的另一端具有公网IP,使的该技术重要性降低了。
简要阐述NAT的步骤

节点A 路由器 节点B 向节点B发送数据 此时路由器就会对节点A进行地址映射 比如69.10.123.8:51636 转发请求数据 收到数据后进行处理 处理后向节点A响应数据 转发响应数据 节点A 路由器 节点B

通过上述时序图,我们可以知道网络地址转换其实在数据报文转发时是一个很常见的情况。NAT按照不同的维度有不同的类型分法,比如按照是否动态维度来说,分为静态NAT和动态NAT。本文都是基于动态NAT进行展开的,接下来我们就针对动态NAT的转发种类进行一个简单的区分说明。

NAT
锥型NAT
对称NAT
完全锥型NAT
非完全锥型NAT
地址受限NAT
端口受限NAT

锥型NAT

初看这个定义可能会有点懵逼,和锥型有什么关系,其实想象一下锥型是形状可能就能明白了。
在这里插入图片描述

图源自网络(侵删)

可以看到锥型的顶部是一个点,通过这个点向某个子网络打了一个洞,这个点就是我们映射出来的网络地址,外部网络通过该地址就能和子网中的某一台特定终端进行通信。即一个内部地址可以对应N个外部地址,如果把这些通联设备用线连接起来,就像是一个锥型,故名锥型NAT。

完全锥型NAT

完全锥型NAT首先得是锥型NAT,也就说具备锥型NAT的所有特征,而且前面加入的修饰词是“完全”,所以没有其他任何额外的限制。
在进行NAT时,大致的时序图如下。

内网节点A 公网节点B 内网节点C 向节点B发送数据 此时内网节点A所在的路由设备就会生成地址映射 比如69.10.123.8:51636 这里不是指必须要有固定公网IP的节点 而是泛指所有获取到公网IP的节点 也就说可以是P2P网络中已知路由表中的某个节点 告知内网节点A映射的公网IP和端口 根据映射的公网IP和端口直接进行通信 内网节点A 公网节点B 内网节点C

非完全锥型NAT

非完全锥型NAT也叫受限锥型NAT,什么受限呢,也就是映射时的IP地址受限,或者端口受限。

IP受限NAT

顾名思义就是在进行NAT时,映射出的公网地址只能和固定的IP进行通信,也就是通过该点打出的洞是有限制的,所限制的范围就是某个IP的所有流量(不限制端口)。由于和不同的外部IP通信会映射出不同的公网地址,所以其NAT的步骤和完全锥型NAT相比要复杂一点。IP受限NAT有个特点,就是单个Socket(或FD)映射出的公网地址是固定的,只要内网节点通过这个映射地址向外发送过数据,对应的外部地址(不限端口)就可以通过该映射地址向内网节点发送数据。这里就拿两边都是IP受限NAT进行通信来举例。

内网节点A 公网节点B 内网节点C 向节点B发送数据 此时内网节点A所在的路由设备就会针对公网节点B生成地址映射 比如69.10.123.8:51636 告知内网节点A映射的公网IP和端口 根据映射的公网IP和端口直接向内网节点A发送数据 但是由于是IP受限NAT映射的地址只能和公网节点B进行通信 此时内网节点C所在的路由设备就会针对内网节点A映射出的公网IP生成地址映射 比如111.19.23.10:32097 向节点B发送数据 此时内网节点C所在的路由设备就会针对公网节点B生成地址映射 比如111.19.23.10:32098 告知内网节点C映射的公网IP和端口 根据映射的公网IP和端口直接向内网节点C发送数据 且由于前面内网节点C已经向内网节点A发送过数据 所以本次发送的数据就不会被限制,至此NAT已打通 内网节点A 公网节点B 内网节点C
端口受限NAT

对于端口受限NAT就会在IP受限NAT的基础上再加上端口号的限制,限制条件更为苛刻,所以对应的NAT过程相对于IP受限NAT而言又要更加复杂。端口相对于IP受限NAT增加了限制条件,就是单个Socket(或FD)映射出的公网地址是固定的,只要内网节点通过这个映射地址向外发送过数据,对应的外部地址(发送过数据的特定IP+端口)就可以通过该映射地址向内网节点发送数据。为了方便说明问题,就拿一边是完全锥型NAT一边是端口受限NAT进行通信来举例。

完全锥型内网节点A 公网节点B 端口受限内网节点C 公网节点B1 向公网节点B发送数据 此时节点A所在的路由设备就会针对公网节点B生成地址映射 比如69.10.123.8:51636 告知内网节点A映射的公网IP和端口 向公网节点B发送数据 此时获取到节点C对于节点B的地址映射 此时节点C所在的路由设备就会针对节点B生成地址映射 比如111.19.23.10:32097 根据映射的公网IP和端口直接向内网节点A发送数据 此时节点C所在的路由设备就会针对节点A映射出的IP和端口生成地址映射 比如111.19.23.10:xxx 但问题是现在谁都不知道具体的端口号是多少 向公网节点B1发送数据 此时获取到节点C对于节点B1的地址映射 此时节点C所在的路由设备就会针对节点B1生成地址映射 比如111.19.23.10:32099 是不是可以猜测xxx就是32098呢 告知端口受限内网节点C映射的公网IP和猜测的端口(32098) 如果猜测正确,则两个节点之间就可以互相通信 完全锥型内网节点A 公网节点B 端口受限内网节点C 公网节点B1

可以看到,这里面用到了夹逼原理,即我连续映射几个不同的端口,看看映射出地址的端口变化规律,进而确定目标地址对应的映射端口是多少。该场景有很大的限制性,比如路由设备必须是单网卡,如果是两个网卡,甚至是网卡池,存在许多个IP,就无法通过该原理进行。还有映射的算法如果不是自增,而是随机,也无法通过该方法进行NAT。所以实际使用中NAT的成功率不是100%,往往只有80%~95%左右。

对称NAT

即Symmetric NAT,这个类型的NAT限制就更为苛刻了。每次主动向外通信会生成一个对应的映射地址,准确来说单个Socket(或FD)映射出的公网地址不是固定的,会随着访问的外部地址而变化(根据NAT设备是否存在多个网卡确定IP是否会变,端口是否会变,总之IP+端口的组合结果肯定会变)。所以看起来就像是一次次完全对称的映射关系,故名对称NAT。针对这个特性,这里不再赘述对称NAT的穿透时序图,各位看官可自行拓展研究。

总结

如果要开发一套用于生产环境的公链型区块链产品,则必不可少需要用到NAT的相关技术。但是对于只开发Demo用于教学,或者联盟链、私链的区块链产品,由于其节点之间都是预知IP和端口的,也就不需要关注NAT技术点。专门开篇将这部分内容,是为了对现在耳熟能详的公链能有一个更为细致的技术认知。最后的最后,抛一个简单的问题给大家,P2P网络由于没有固定的服务地址,新加入时要如何获得连接地址呢?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值