美文网首页
P2P技术初窥

P2P技术初窥

作者: 小小混世魔王 | 来源:发表于2021-12-22 19:19 被阅读0次

    时间过的很快离上次更新文章已经有了两年之久,为了共同学习共同进步宗旨,绕网络模块主题开展一次技术分享,(回顾之前同事讲了一些主题,HTTP/HTTPS、DNS解析/DNS优化、网络安全加密、TCP/UDP/SOCKET)具体看看网络所包含的模块吧。


    网络.png

    内容还真不少,这些东西大多都偏向底层基础,在实际开发中大多数都是由系统或者优秀的三方框架来实现。本着了解底层实现细节知识更能快速掌握上层技术,那么这次分享就围绕P2P来展开,作为移动端开发者也为后续理解WebRTC等技术积累一点知识。
    1)P2P概述
    2)P2P应用的场景
    3)P2P简单原理
    4)NAT概述
    5)NAT实现方式
    6)NAT类型
    7)NAT类型探测
    8)内网穿透

    P2P概述

    P2P应用在金融、视频通话、文件下载,流媒体点播/直播等场景都有广泛应用,日常中我们微信视频通话,使用迅雷下载文件,中间都使用到了p2p技术。
    P2P,全称叫做“Peer-to-peer”对等互联网络技术(点对点网络技术),它让用户可以直接连接到其他用户的设备,进行数据的交换。
    举个简单例子,比如你喜欢一个女孩子,但是你们互相不认识,幸运的是刚好有这么一个人,你和女孩都认识她。你按捺不住对女孩的想念,你找到这个人拿到了女孩的联系方式,然后迫不及待的给这个女孩发送一条消息,然后你就焦急等待女孩给你回复,女孩接收你得消息开心回复了你。你和女孩之间聊天就可以理解点对点的方式聊天。当然在这里你们是依靠中间人建立的联系,在P2P中建立点对点联系是依赖集中服务器。

    P2P简单的原理
    网络环境.png

    我们大部分上网的设备都处于私网(局域网)环境内,内网客户端想要上网就需要经历网关转发访问数据。服务器返回数据是返回给网关,再由网关转发给客户端。为什么要设计成这样,出于两个原因的考虑,一是全球范围内上网的设备很多IP地址不够,二是对外隐藏客户端提高安全性(客户端只能向外访问,外边访问不到客户端),正因为网络环境的这种设计使得点对点通信变得尤为复杂。
    我们知道私网地址是不可以连接外网,需要对外访问只能通过公网地址。客户端在上网时通过网关做了NAT(私网地址与公网地址映射,网关维护映射表,此时从网关出去的IP数据包源地址替换成了公网地址)从上图可知道网关的出接口是公网地址,公网地址是可以被其他设备访问到,那么网关可以访问服务器,服务器也可以访问网关,网关与网关也是可以互相访问。


    p2p简单原理.png

    那么客户端A要直接访问客户端B,就可以利用网关访问到。可以简单理解成网关A与网关B在通信。要想知道P2P的建立过程,就不得不了解NAT,包括怎样去实现内网穿透的。

    NAT概述

    在这里我觉得百度百科讲的比我清楚,技术这个东西自己知道与要讲出来甚至写出来其实还是很不一样的,https://baike.baidu.com/item/nat/320024?fr=aladdin如果你不想点开没关系,那下面也会做一些NAT简单引用

    NAT技术诞生背景

    要真正了解NAT就必须先了解IP地址的使用情况,私有 IP 地址是指内部网络或主机的IP 地址,公有IP 地址是指在因特网上全球地址。RFC 1918 为私有网络预留出了三个IP 地址块,如下:

    A 类:10.0.0.0~10.255.255.255

    B 类:172.16.0.0~172.31.255.255

    C 类:192.168.0.0~192.168.255.255

    上述三个范围内的地址不会在因特网上被分配,因此可以不必向ISP 或注册中心申请而在公司或企业内部自由使用。
    随着接入Internet的计算机数量的不断猛增,IP地址资源也就愈加显得捉襟见肘。事实上,除了中国教育和科研计算机网(CERNET)外,一般用户几乎申请不到整段的C类IP地址。在其他ISP那里,即使是拥有几百台计算机的大型局域网用户,当他们申请IP地址时,所分配的地址也不过只有几个或十几个IP地址。显然,这样少的IP地址根本无法满足网络用户的需求,于是也就产生了NAT技术。

    NAT解释

    NAT(Network Address Translation),是指网络地址转换。当在专用网内部的一些主机本来已经分配到了本地IP地址(即仅在本专用网内使用的专用地址),但又想和因特网上的主机通信(并不需要加密)时,可使用NAT方法。
    这种方法需要在专用网(私网IP)连接到因特网(公网IP)的路由器上安装NAT软件。装有NAT软件的路由器叫做NAT路由器,它至少有一个有效的外部全球IP地址(公网IP地址)。这样,所有使用本地地址(私网IP地址)的主机在和外界通信时,都要在NAT路由器上将其本地地址转换成全球IP地址,才能和因特网连接。
    另外,这种通过使用少量的全球IP地址(公网IP地址)代表较多的私有IP地址的方式,将有助于减缓可用的IP地址空间的枯竭。在RFC 2663中有对NAT的说明。
    百度百科讲的很专业,让大家更直观了解组网有必要提供一个图

    园区组网.png A园区下面所有能上网设备都分配了一个10.0.197.*不重复的私网IP地址,A园区内的每台设备访问外网资源都要通过网关NAT将内部的私网地址转成A园区的公网IP地址59.36.211.209进行对外访问,外部服务返回数据给网关,网关通过查找NAT地址映射,把数据准确发送到内网下具体上网的设备。这样起到多台设备共用一个公网地址上网,起到减缓IPV4地址枯竭进程,有效的隐藏公网下的上网设备。
    NAT实现方式

    实现NAT的方式有三种 静态转换Static Nat、动态转换Dynamic Nat和端口多路复用OverLoad。

    静态转换Static Nat

    静态转换分两种,一种是IP静态转换,另一种是端口的静态转化。
    一、IP静态转换
    IP静态转换是指将内部网络的私有IP地址转换为公有IP地址,IP地址对是一对一的,是一成不变的,某个私有IP地址只转换为某个公有IP地址。即一个公网地址只能映射一个私网地址,所有外界访问公网地址都会访问到这台固定的设备上,公网资源全部分配给这个唯一的设备。对于静态NAT并不能节约公网IP地址使用,因为一对一静态的缘故,因此外界可以访问进来,内部也可访问出去。当设备要对外提供固定的某个服务就可以使用静态NAT。
    二、端口静态转换
    一个IP地址可以有65536个端口,0~1024端口一般分给系统使用,端口静态转换是指1024~65536端口每个端口对应唯一的私网IP地址某个固定端口,端口对应的私网IP地址端口是一成不变的。当外界访问公网地址的某个端口通过网关对应的NAT端口映射表就可以找到具体某个设备某个端口,因此外界可以访问某台设备固定端口,端口静态转化确实能够节省公网IP地址的使用,但是由于端口受限内网是无法访问出去的(由于设备访问外界发送数据包源端口地址是随机生成,因此你不知道端口号是多少,只有当私网地址端口和公网地址端口映射上了才可以访问外界)

    动态转换Dynamic Nat

    动态IP转化是指内部网络私有IP地址转化为公有IP地址,公网IP地址来源是从IP池中获取到。内网某台设备要向外发起访问路由到网关,网关从IP池中去获取公网IP地址,若IP池中没有IP地址就等待其它设备释放公网IP,如果能取到公网IP地址,该公网的所有资源内网都可以使用,这样私网设备就可以访问外界,当访问结束会释放公网IP,因此弊端在某时刻某些设备可以上网某些设备不能上网。

    端口多路复用OverLoad

    上面讲到端口的静态转换(简单说端口关系是静态绑定的),端口多路复用公网端口和私网端口是临时映射关系。内网私网地址某个端口向外访问会映射公网地址某个空闲端口,当访问结束连接断开,私网地址端口映射的公网地址端口会被释放出来给内网任意设备映射临时关系。这样很大程度节约了IP地址使用,由于零时端口映射关系,只能内网放完外界,外界不能访问到内网设备,满足了大批量设备需要上网的需求,一般园区网,家庭网,公司网都是这种组网形式。

    NAT类型

    了解NAT的实现方式,我们就可以对NAT进行分类。在做内网穿透我们就要判断NAT的类型。 NAT分类.png

    NAT类型可以分为对称NAT、完全锥形NAT、IP受限NAT、端口受限NAT
    一、对称型NAT
    内部私网地址访问外部不同的设备都会映射一个新的公网地址。(一台内网设备 对应一个公网地址 对应一台外网设备 产生一对一的关系)
    二、完全锥形NAT
    将来自内网私有IP地址同一个端口号映射到公网IP某个端口。任意外部IP地址与端口对其自己公网的IP这个映射后的端口访问,都将定位到内部私网地址端口。

    例子来源网络
    例如:
    A:192.168.8.100 ——NAT:1.2.3.4 ——C:292.88.88.88
    [ok] C(292.88.88.88:2000) ——> NAT(1.2.3.4 : 8000) ——> A(192.168.8.100:5000)
    [ok] C(292.88.88.88:3000) ——> NAT(1.2.3.4 : 8000) ——> A(192.168.8.100:5000)
    [ok] D(292.99.99.99:3000) ——> NAT(1.2.3.4 : 8000) ——> A(192.168.8.100:5000)
    任何发送到 NAT(202.100.100.100:8000) 的数据都可以到达 A(192.168.8.100:5000)
    

    三、IP地址受限锥形NAT
    IP地址受限锥形NAT大致可以理解在完全锥形NAT加上了IP访问限制,并不是所有外部设备都可以访问到内网设备,只有通过内网设备对某个外部设备主动发起过连接,然后这个外部设备就可以访问到内网这个设备,但端口不做限制。

    例子来源网络
    例如:
    A:192.168.8.100 ——NAT:1.2.3.4 ——C:292.88.88.88
    //可以建立通信
    [ok] C(292.88.88.88:2000) ——> NAT(1.2.3.4 : 8000) ——> A(192.168.8.100:5000)
    [ok] C(292.88.88.88:3000) ——> NAT(1.2.3.4 : 8000) ——> A(192.168.8.100:5000)
    //不能建立通信 如果要建立通信 必须由内网设备发送数据包到 292.99.99.99:3000 建立连接后
    [no] D(292.99.99.99:3000) ——> NAT(1.2.3.4 : 8000) ——> A(192.168.8.100:5000)
    任何从C发送到 NAT(1.2.3.4:8000)的数据都可以到达A(192.168.8.100:5000)
    

    四、端口受限锥形NAT
    端口受限锥形NAT它比IP地址受限锥形NAT受限更为严格,能接受到外界的数据报范围更加小了,除了IP受限外还添加了端口受限。内网设备只允许自己外网建立连接的地址端口给自己发送数据报

    例子来源网络
    例如:
    A:192.168.8.100 ——NAT:1.2.3.4 ——C:292.88.88.88
    //可以建立通信
    [ok] C(292.88.88.88:2000) ——> NAT(1.2.3.4 : 8000) ——> A(192.168.8.100:5000)
    //不能建立通信   必须由内网设备发送数据包到 292.88.88.88:3000 建立连接后
    [no] C(292.88.88.88:3000) ——> NAT(1.2.3.4 : 8000) ——> A(192.168.8.100:5000)
    C(202.88.88.88:2000)发送到 NAT(1.2.3.4:8000)的数据都可以到达A(192.168.8.100:5000)
    
    NAT类型探测与内网穿透

    对于NAT类型探测与内网穿透详细过程可以看 http://www.52im.net/thread-2872-1-1.htm
    在实际的网络情况中,我们上网的设备所处的网络环境不同。处在NAT网下的设备要进行点对点的通信,首先判断出设备各自所处的网络NAT类型。然后才能根据NAT的类型实现相应的UDP/TCP打洞。
    关于内网穿透建立点对点的连接,已经有了下面一些成熟的方法。STUN(Session Traversal Utilities for NAT,NAT会话穿越应用程序)技术就是其中比较重要的一种解决方法,并得到了广泛的应用。除此之外,还有UPNP技术,ICE交互式连接建立,TURN中继NAT穿越技术等。
    打洞技术是通过中间服务器的协助在各自的NAT网关上建立相关的表项,使P2P连接的双方发送的报文能够直接穿透对方的NAT网关,从而实现P2P客户端互连。如果两台位于NAT设备后面的P2P客户端希望在自己的NAT网关上打个洞,那么他们需要一个协助者——集中服务器,并且还需要一种用于打洞的Session建立机制。
    重点介绍一下 客户端怎么通过STUN(NAT回话穿越应用程序的原理)探测出自己的公网地址与NAT的内型。STUN协议 利用STUN客户端与STUN服务器(集中服务器)通信(利用上面所讲到NAT类型通信特点来判断设备的具体所处的什么NAT网络下)
    一、NAT类型探测
    文字描述不如上图来的直接

    NAT类型探测.png
    二、NAT穿越方法
    1)打洞技术(Hole Punching)
    介绍一下打洞原理:位于NAT后的内网设备节点需要向外发送数据包,通过NAT建立起内网IP地址端口和公网IP地址端口的映射关系。然后通过某种方式将映射后的外网地址和端口通知给对端节点设备。最后对端设备收到内网设备NAT后的公网地址端口,并向改公网地址端口发送数据包,然后该数据包就会被NAT转发给内网设备。
    在这里提出两个问题,怎么将自己公网地址通知个对端?对端知道自己的公网地址端口就一定能建立通信?
    建立点对点通信.png

    客户端通过STUN服务器获取到自己的公网地址端口NAT类型,再将自己身的信息注册到中继服务器,客户端1向中继服务器发起获取客户端2信息的请求,获取到客户端2的信息向客户端 2网关发起直连,获取对端公网地址已经解决了。怎么知道能否建立点对点的通信,其实上面已经讨论到了,STUN服务器探测到客户端各自的NAT类型,具体使用什么穿越方法参照下表(下图源于网络若侵权请联系删除)

    对应NAT类型穿越方法表.png
    感兴趣的可以自己去分析一下建立点对点通信的步骤。具体的打洞过程包括Relay(服务器中转)技术可以去看看http://www.52im.net/thread-2872-1-1.htm接下来挑几个例子来看看具体的打洞过程。
    例子1:
    客户端1 主动连接 客户端2 客户端1处于任意NAT类型环境 客户端2处于IP受限NAT型环境,客户端都获取到了对端信息情况下。
    任意型NAT-IP受限型NAT穿透过程.png
    例子2:客户端1处于任意NAT类型(除对称NAT外)环境 客户端2处于端口受限NAT型 任意型NAT-端口受限型NAT穿透过程.png
    最后介绍一下端口预测:
    端口预测,就是统计客户端多次连接的地址,总结出客户端外网端口变化的规律,然后把预测出的下一个端口和外网地址发给对方,然后促成双方通信。这个方法穿透成功率极低。一般P2P项目再建立点对点连接失败后都会利用服务器来进行数据转发。
    参考文献

    https://baike.baidu.com/item/nat/320024?fr=aladdin
    http://www.52im.net/thread-2872-1-1.html
    https://blog.csdn.net/WangZekun_wolf/article/details/89102996

    相关文章

      网友评论

          本文标题:P2P技术初窥

          本文链接:https://www.haomeiwen.com/subject/lnmvfrtx.html