P2P网络概念的背景和基础认识
P2P网络概念的背景和基础认知
前言:
“2011年2月3日,IANA对外宣布IPv4地址空间最后5个地址块已经被分配给下属的5个地区委员会。”
“2011年4月15日,亚太区委员会APNIC对外宣布,除了个别保留地址外,本区域所有的IPv4地址基本耗尽。”
现2017已经过去大半年,离2011已有6年多,虽然IPv4的地址已经耗尽,但也并未影响我们一直沿用IPv4直到现在。
IPv6推出至今,也并未受到广泛应用,这是受制于NAT(Network Address Translation),我们还能继续使用IPv4也得益于NAT。
知乎中的某条评论<吴建平反思国内IPv6发展:为何“起了个大早,赶了个晚集”>。
为什么说是受制于NAT又得益于NAT?
0x01 NAT的起源
NAT英文全名为Network Address Translation,顾名思义,网络地址转换,早在上世纪就已提出了NAT的概念。NAT作为解决IPv4地址不够用的主要方式,还得了解IPv4的发展历程。
IPv4采用32位的整数来表示一个IP地址,诞生初期,按理论计算,可以分配的IP地址达42亿之多。这样的IP数量级在当时的网络环境下,是不可能一下子使用完的,所以,IANA当时对企业、组织、教育机构的IP分配也并没有得到真正的利用,导致IP地址浪费严重,不过这也不能怪IANA,现在对结果进行分析都是马后炮。历史给了我们惊喜,互联网的发展呈指数性的爆炸增长。除了过早的浪费很多地址,为了路由和方便管理,地址还分为了ABC类和保留地址,但这样的分配也并非不合理。
A类地址 :0******* -------- -------- -------- 126个网络,每个网络可以有16,777,214个主机
B类地址 :10****** -------- -------- -------- 16,384个网络,每个网络可以有65,534个主机
C类地址 :110***** -------- -------- -------- 2,097,152个网络,每个网络可以有254个主机。
保留地址:1110**** -------- -------- -------- 当计算机获取IP失败时,默认使用的地址
在80年代初IPv4被详细定下来,到90年代初NAT的出现也只经历了10多年的时间,在90年代初,为了替代新的IPv4,96年提出了IPv6,但是要普及IPv6需要更换许多沿用IPv4的设备,包括教育、军工等设施,这些都是极其庞大的工程,并不是简单的协议替换而已,并没有一个平滑的过度方式可以让互联网用户在无感知的情况下将IPv4取代,上面我们不是说了还有保留地址吗,对,NAT就催生了。
因为有了保留地址,所以大型企业中,会采用与广域网相隔离的局域网中使用保留的IPv4地址进行局域网通信,在局域网中只需要一台设备与互联网相连,那其它设备就可以通过这一台设备作为入/出口(网关),而广域网中的设备只有广域网的IP地址才能进行通信,所以,这台作为在局域网内的所有设备,在出口的时候,源地址都会被改写为网关所被分配的广域网IP地址,这就是NAT(Network Address Translation)– 网络地址转换。在同一个局域网中,与广域网的通信过程都共用一个广域网IP地址。
同时,NAT还能保护局域网内的主机不被发现,即安全,又解决了IPv4地址不够用的问题,所以一直沿用至今,甚至让我们忘了IPv4地址池已经用光的这样一个事实。换过来再说,对IPv4、NAT依赖越多,如果没有一个很平滑的过渡,IPv6也就越难以普及。
0x02 NAT转换到P2P通信
上面提到了,通过NAT网络地址转换过后,我们通过局域网访问外网的时候,别人是看不到我们的局域网IP地址的,他们只能看到我们局域网共用的出口那个IP地址。
假如现在有这么一条通信隧道:
/** host1 -->> host2 **/
host1:port = 192.168.1.101:1111 // 主机1的地址,在局域网中
getway:port = 192.168.1.1:60001 / 88.88.88.88:60001 // 网关地址
host2:port = 99.99.99.99:2222 // 主机2的地址,在广域网中
常规TCP通信中,host2主机开启监听2222端口,那么广域网中就能直接找到IP地址为99.99.99.99的主机,并且可以往这台主机的2222号端口塞数据进去。
在上述的例子中,host1与host2建立通信,首先由host1发起通信请求,请求访问host2主机的2222端口的流程,先找到本局域网的公网IP共用的主机192.168.1.1,即网关,把要发送的数据发给他,网关对数据包进行拆解,读到目的地址是99.99.99.99,需要将数据塞到目的地址的2222号端口,OK了,这样就完成了一次单向通信。在网关拆解数据包的时候,还会对数据包进行改写,会把源地址改写成自己的IP地址,并且开放一个新的端口号60001,告诉远端主机,“如果你要回复,那就往88.88.88.88这个地址的60001号端口给我塞回来。”这样就通过NAT建立了一个局域网与广域网之间的双向通信隧道。
这就存在了一些问题,在我和别人没有建立通信,别人需要主动访问我的时候,是无法访问的。
就是说,如果host1主机没有主动向host2主机发送数据,那么88.88.88.88网关就不会开放一个新的端口号,用于对应给host1主机的1111端口转发外部传递进来的数据。99.99.99.99也不知道该向目标的哪一个入口(端口)发送数据才会传递到host1主机,因为根本没有建立这个隧道。
既然可以从内部向外部建立通信隧道,我们又为什么非得需要从外部向里面建立呢?
举个例子,在实际应用中,假如我想搭建一个FTP服务共享我自己的文件访问,但是我又不想租服务器,而且同时我自己没有公网IP,或者我有公网IP,但不希望我自己的主机暴露在公网中,那么这个时候就需要别人通过外部向内部访问才能访问到我的FTP服务。这只是一个简单的例子,生活中有更多且比这个例子更需要用到地方。
在上面例子里,从外部向内部访问的主机,可能也是处于另一个局域网中,而不论它是否处于局域网中,它与我搭建在局域网内的FTP主机进行通信都可以称之为是P2P(peer-to-peer)通信,即对等网络通信。
0x03 小结
本来想写三个小结,来介绍P2P,分别介绍一下背景知识、NAT和P2P,感觉第二点好像也简单的把p2p和nat都一起讲了,整理了一个简单的大纲,计划之后还要至少再写两篇介绍并实现一个自己的P2P程序,此篇开篇都是理论,之后的可能更偏技术一些。懒人,懒更。
大纲:
《2、NAT工作原理以及P2P实现机制》
0x01 TCP/IP通信过程
0x02 NAT的原理
0x03 什么是NAT打洞
0x04 P2P的实现机制
0x05 P2P中可实现的可能性分析
0x06 小结
《3、NAT打洞的C/C++程序实现》
0x01 建立常规网络通信
0x02 打一个洞
0x03 通过“洞”建立通信隧道
0x04 小结
欢迎关注我的公众号
如果你懒得扫,其实,我…完全不在意
活着不是为了满足自己的虚荣心
世上还存在很多有趣的东西
如果你已不能够支撑你自己去挖掘你的兴趣
希望你也不会被现实打败
推荐阅读