P2P就是端到端

我发一条微信给你,这不是P2P。因为消息并不是直接从我手机发送到你的手机,而是从我手机先发送到微信的服务器,服务器再转发到你的手机上(当然,转发给你之前,还会把数据存到服务器),像下边这样:
在这里插入图片描述
P2P是这样:
在这里插入图片描述

P2P技术要解决的问题

目前使用的终端设备(如手机),绝大部分都仅仅拥有特定网络下的内网IP,而处在不同内网环境中的设备并不能够使用内网IP直接进行通信。如何通过一定的手段让这两个处在不同内网环境的设备进行直接通信呢?

P2P的知识点

我们的终端设备(比如手机),一定是存在于某个内网环境下边的,当设备与内网之外的其他设备进行通信时,需要将内网IP转换为一个可以被全球任意设备访问到的公网IP,这种技术叫做NAT,全称是Network Address Translation,即网络地址转换。

根据转换方式的不同,出现了不同的NAT,理论上有基本NAT,也有一对多NAT,但是现实中基本都是一对多NAT,根据内网设备与外网进行通信时不同的映射规则,又分为以下几种类型:

类型阐述
锥型NAT(Full-cone NAT)内网ip1:port1会映射到公网ip2:port2,ip1:port1发往外网的包都将通过ip2:port2发出;外部任何ip3:port3都可以通过发送数据包给ip2:port2从而与ip1:port1进行通信。
(地址)限制型锥型NAT((Address)-restricted-cone NAT)内网ip1:port1会映射到ip2:port2,ip1:port1发往外网的包都将通过ip2:port2发出;外部只有收到过ip2:port2数据包的ip3才可以发送数据包给ip2:port2从而与ip1:port1进行通信。
端口限制型锥型NAT(Port-restricted cone NAT)内网ip1:port1会映射到ip2:port2,ip1:port1任何发往外网的包都将通过ip2:port2发出;外部只有收到过ip2:port2数据包的ip3:port3才可以发送数据包给ip2:port2从而与ip1:port1进行通信。
对称性NAT(Symmetric NAT)内网ip1:port1任何一个发往外网ip3:port3的请求,都将使用独有的公网ip2:port2;外部只有收到过ip1:port1数据包的服务才能返回数据。

总的来说,我们程序发出的包有源地址和源端口,经过NAT之后,映射出的公网地址和端口是否会随着目的地址和目的端口的变化而变化,决定了它是锥型还是对称型。这句话有点拗口,但我觉得说的很清楚。同时,只有锥型NAT才能进行P2P,原因是由P2P连接的建立过程决定的。

P2P连接建立过程

P2P连接的建立首先需要一个拥有公网IP的中间服务器S,两个结点P1和P2。

1、结点P1和P2分别发送数据包给S,数据包在经过NAT时,ip和port进行转换,ip转换为公网ip,port是否转换需要看NAT的具体实现。S拿到转换后的P1和P2的地址。
2、S将P1的地址发给P2,将P2的地址发给P1。这里的地址都是NAT地址。
3、P1收到P2地址后,尝试建立连接,首先发送消息包给P2(其实是P2的NAT),P2也同样这样做,在两个结点都收到对方的消息包之后,就可以进行通信了。这个过程也叫做打洞。

之所以需要有打洞这个过程,是因为,NAT会丢弃自己不认识的地址包,让NAT认识它的方法,就是发出一个到这个地址的数据包。比如让A认识B,那就让A发一个数据包给B,不然,B发给A的数据包就会被丢弃。所以打洞的过程不是为了收到对方的数据包,而是为了发送数据包给对方,从而认识对方。这样,之后的通信就可以正常进行了。

刚才之所以说只有锥型NAT才可以进行P2P,原因在第三步可以看出来。结点进行打洞的地址,是通过服务器拿到的,而这个地址在对称型NAT的情况下,并不是一定的,可能会随时发生变化。也就是说,P1与服务器通信使用的NAT地址和P2与P1通信使用的NAT地址是不同的(一般情况都是端口不同)。甚至P1与服务器通信使用的NAT地址都在不断的发生变化。这样让我们没办法拿到隐藏在NAT后边内网设备的NAT入口,也就没办法进行P2P通信了。

P2P也用到了一个服务器,跟微信一样。但是不同的是,P2P中的服务器只作为结点地址的中转站,而微信的服务器是数据的聚宝盆。P2P让我们的数据仅通过P2P连接发送,而不经过任何第三方的服务器。

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐