Loading... **引言** 本文的目的在于学习和了解 NAT 的基本知识,然后通过 P2P 组网 # 一、什么是NAT? ## **1、NAT** **简介** **NAT(Network Address Translation** ,网络地址转换) 是一种广泛应用的解决`IP` 短缺的有效方法, `NAT` 将内网地址转和端口号换成合法的公网地址和端口号,建立一个会话,与公网主机进行通信。 `NAT` 不仅实现地址转换,同时还起到防火墙的作用,隐藏内部网络的拓扑结构,保护内部主机。 此外还完美地解决了 `lP` 地址不足的问题,而且还能够有效地避免来自网络外部的攻击,隐藏并保护网络内部的计算机。 这样对于外部主机来说,内部主机是不可见的。但是,对于`P2P` 应用来说,却要求能够建立端到端的连接,所以如何穿透NAT 也是P2P 技术中的一个关键。 #### 1.1 为什么会有NAT 时光回到上个世纪80年代,当时的人们在设计网络地址的时候,觉得再怎么样也不会有超过32bits位长即2的32次幂台终端设备连入互联网,再加上增加ip的长度(即使是从4字节增到6字节)对当时设备的计算、存储、传输成本也是相当巨大的。后来逐渐发现IP地址不够用了,然后就NAT就诞生了!(虽然ipv6也是解决办法,但始终普及不开来,而且未来到底ipv6够不够用仍是未知)。 因此,NAT技术能够兴起的原因还是因为在我们国家公网IP地址太少了,不够用,所以才会采取这种地址转换的策略。可见,NAT的本质就是让一群机器公用同一个IP,这样就暂时解决了IP短缺的问题。 #### 1.2 NAT有什么优缺点 优势其实上面已经刚刚讨论过了,根据定义,比较容易看出,NAT可以同时让多个计算机同时联网,并隐藏其内网IP,因此也增加了内网的网络安全性;此外,NAT对来自外部的数据查看其NAT映射记录,对没有相应记录的数据包进行拒绝,提高了网络安全性。 那么,NAT与此同时也带来一些弊端:首先是,NAT设备会对数据包进行编辑修改,这样就降低了发送数据的效率;此外,各种协议的应用各有不同,有的协议是无法通过NAT的(不能通过NAT的协议还是蛮多的),这就需要通过穿透技术来解决。我们后面会重点讨论穿透技术。 简单的背景了解过后,下面介绍下NAT实现的主要方式,以及NAT都有哪些类型。 ## 2、NAT 分类 从表面上看有三种类型:静态 NAT 、动态地址 NAT 、地址端口转换 NAPT 。 #### **2.1 静态NAT** 静态地址转换将内部私网地址与合法公网地址进行一对一的转换,且每个内部地址的转换都是确定的。 | 内网IP | 外网IP | | ------------- | --------------- | | 192.168.1.55 | 219.123.234.110 | | 192.168.1.59 | 219.123.234.111 | | 192.168.1.211 | 219.123.234.112 | #### **2.2 动态NAT** 动态地址转换也是将内部本地地址与内部合法地址一对一的转换,但是动态地址转换是从合法地址池中动态选择一个未使用的地址来对内部私有地址进行转换。 | 内网IP | 资源池 | 外网IP | | ------------- | ------------------------- | ------ | | 192.168.1.55 | 219.123.234 - 219.123.250 | 分配后 | | 192.168.1.59 | | 分配后 | | 192.168.1.211 | | 分配后 | #### **2.3 NAPT** 它也是一种动态转换,而且多个内部地址被转换成同一个合法公网地址,使用不同的端口号来区分不同的主机,不同的进程。 | 内网IP | 外网IP | | ------------------ | -------------------- | | 192.168.1.55:8877 | 219.123.234.110:9200 | | 192.168.1.59:6652 | 219.123.234.111:9201 | | 192.168.1.211:1232 | 219.123.234.112:9202 | 通过上面实现方式的介绍,不难看出,现实环境中 **NAPT** 的应用显然是更广泛的,因此下面就重点介绍下 **NAPT** 的主要类型有哪些。 **从实现的技术角度,又可以将 NAPT 分成如下几类:** 对于`NAPT`我们主要分为两大类:锥型`NAT`和对称型`NAT`。 其中锥型NAT又分:完全锥型,受限锥型和端口受限锥型。概括的说:对称型NAT是一个请求对应一个端口;锥型NAT(非对称NAT)是多个请求(外部发向内部)对应一个端口,只要源IP端口不变,无论发往的目的IP是否相同,在NAT上都映射为同一个端口,形象的看起来就像锥子一样,下面分别介绍这四种类型及其差异。 - 全锥 NAT(Full Cone NAT) - 限制性锥 NAT (Restricted Cone NAT ) - 端口限制性锥 NAT( Port Restricted Cone NAT) - 对称 NAT ( Symmetric NAT) ##### (1)全锥 NAT(Full Cone NAT) 全锥NAT 把所有来自相同内部IP 地址和端口的请求映射到相同的外部IP 地址和端口。任何一个外部主机均可通过该映射发送数据包到该内部主机。 特点:IP和端口都不受限 表现形式:将来自内部同一个IP地址同一个端口号(IP_IN_A : PORT_IN_A)的主机监听/请求,映射到公网IP某个端口(IP_OUT_B : PORT_OUT_B)的监听。任意外部IP地址与端口对其自己公网的IP这个映射后的端口访问(IP_OUT_B : PORT_OUT_B),都将重新定位到内部这个主机(IP_IN_A : PORT_IN_A)。该技术中,基于C/S架构的应用可以在任何一端发起连接。是不是很绕啊。再简单一点的说,就是,只要客户端,由内到外建立一个映射(NatIP:NatPort -> A:P1)之后,其他IP的主机B或端口A:P2都可以使用这个洞给客户端发送数据。 <svg id="SvgjsSvg1335" xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svgjs="http://svgjs.com/svgjs" width="100%" height="356"><rect fill="url(#pattern_mark)" transform="translate(-0.399993896484375,7)" width="700" height="100%" id="rect_mark" pointer-events="none"></rect><defs id="SvgjsDefs1336"><pattern id="SvgjsPattern1339" x="0" y="0" width="64" height="64" patternUnits="userSpaceOnUse"><image id="SvgjsImage1340" xlink:href="https://img8.file.cache.docer.com/storage/image/1638348423287/d/3/4/f/d/7545dea13aeedffb48bceaa8f81e98d5.png" width="64" height="64" preserveAspectRatio="none" crossOrigin="anonymous" x="0" y="0"></image></pattern><pattern id="SvgjsPattern1343" x="0" y="0" width="87" height="88" patternUnits="userSpaceOnUse"><image id="SvgjsImage1344" xlink:href="https://img8.file.cache.docer.com/storage/image/1637754713062/9/9/b/e/2/68169bf99dd22d70ba7baab4e568a82f.png" width="87" height="88" preserveAspectRatio="none" crossOrigin="anonymous" x="0" y="0"></image></pattern><pattern id="SvgjsPattern1347" x="0" y="0" width="64" height="64" patternUnits="userSpaceOnUse"><image id="SvgjsImage1348" xlink:href="https://img8.file.cache.docer.com/storage/image/1638352865811/c/d/5/2/2/ab77cbebdabcbfc250a47349253c6e20.png" width="64" height="64" preserveAspectRatio="none" crossOrigin="anonymous" x="0" y="0"></image></pattern><pattern id="SvgjsPattern1357" x="0" y="0" width="64" height="64" patternUnits="userSpaceOnUse"><image id="SvgjsImage1358" xlink:href="https://img8.file.cache.docer.com/storage/image/1638352865811/c/d/5/2/2/ab77cbebdabcbfc250a47349253c6e20.png" width="64" height="64" preserveAspectRatio="none" crossOrigin="anonymous" x="0" y="0"></image></pattern><marker id="SvgjsMarker1379" markerWidth="14" markerHeight="10" refX="10" refY="5" viewBox="0 0 14 10" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1380" d="M0 0L14 5L0 10L0 0 " fill="#81c784" stroke="#81c784" stroke-width="1"></path></marker><marker id="SvgjsMarker1383" markerWidth="14" markerHeight="10" refX="10" refY="5" viewBox="0 0 14 10" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1384" d="M0 0L14 5L0 10L0 0 " fill="#81c784" stroke="#81c784" stroke-width="1"></path></marker><marker id="SvgjsMarker1387" markerWidth="14" markerHeight="10" refX="4" refY="5" viewBox="0 0 14 10" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1388" d="M14 0L0 5L14 10L14 0 " fill="#81c784" stroke="#81c784" stroke-width="1"></path></marker><marker id="SvgjsMarker1389" markerWidth="14" markerHeight="10" refX="10" refY="5" viewBox="0 0 14 10" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1390" d="M0 0L14 5L0 10L0 0 " fill="#81c784" stroke="#81c784" stroke-width="1"></path></marker><marker id="SvgjsMarker1397" markerWidth="14" markerHeight="10" refX="4" refY="5" viewBox="0 0 14 10" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1398" d="M14 0L0 5L14 10L14 0 " fill="#81c784" stroke="#81c784" stroke-width="1"></path></marker><marker id="SvgjsMarker1399" markerWidth="14" markerHeight="10" refX="10" refY="5" viewBox="0 0 14 10" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1400" d="M0 0L14 5L0 10L0 0 " fill="#81c784" stroke="#81c784" stroke-width="1"></path></marker><marker id="SvgjsMarker1407" markerWidth="14" markerHeight="10" refX="4" refY="5" viewBox="0 0 14 10" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1408" d="M14 0L0 5L14 10L14 0 " fill="#81c784" stroke="#81c784" stroke-width="1"></path></marker><marker id="SvgjsMarker1409" markerWidth="14" markerHeight="10" refX="10" refY="5" viewBox="0 0 14 10" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1410" d="M0 0L14 5L0 10L0 0 " fill="#81c784" stroke="#81c784" stroke-width="1"></path></marker><pattern patternUnits="userSpaceOnUse" id="pattern_mark" width="300" height="300"><text x="-50" y="150" fill="rgba(229,229,229,0.8)" font-size="18" transform="rotate(-45, 150, 150)"></text></pattern></defs><g id="SvgjsG1337" transform="translate(61,170)"><path id="SvgjsPath1338" d="M0 0L64 0L64 64L0 64Z " stroke="none" fill="url(#SvgjsPattern1339)"></path></g><g id="SvgjsG1341" transform="translate(262,158)"><path id="SvgjsPath1342" d="M0 0L87 0L87 88L0 88Z " stroke="none" fill="url(#SvgjsPattern1343)"></path></g><g id="SvgjsG1345" transform="translate(443,62)"><path id="SvgjsPath1346" d="M0 0L64 0L64 64L0 64Z " stroke="none" fill="url(#SvgjsPattern1347)"></path></g><g id="SvgjsG1349" transform="translate(25,148)"><path id="SvgjsPath1350" d="M0 0L120 0L120 40L0 40Z " stroke="none" fill="none"></path><g id="SvgjsG1351"><text id="SvgjsText1352" font-family="微软雅黑" text-anchor="middle" font-size="13px" width="120px" fill="#323232" font-weight="400" align="middle" lineHeight="125%" font-style="" opacity="1" y="10.375" transform="rotate(0)"><tspan id="SvgjsTspan1353" dy="16" x="60"><tspan id="SvgjsTspan1354" style="text-decoration:;font-weight: bold;">Client</tspan></tspan></text></g></g><g id="SvgjsG1355" transform="translate(464,267)"><path id="SvgjsPath1356" d="M0 0L64 0L64 64L0 64Z " stroke="none" fill="url(#SvgjsPattern1357)"></path></g><g id="SvgjsG1359" transform="translate(247.5,130)"><path id="SvgjsPath1360" d="M0 0L120 0L120 40L0 40Z " stroke="none" fill="none"></path><g id="SvgjsG1361"><text id="SvgjsText1362" font-family="微软雅黑" text-anchor="middle" font-size="13px" width="120px" fill="#323232" font-weight="700" align="middle" lineHeight="125%" font-style="" opacity="1" y="10.375" transform="rotate(0)"><tspan id="SvgjsTspan1363" dy="16" x="60"><tspan id="SvgjsTspan1364" style="text-decoration:;">Full Cone</tspan></tspan></text></g></g><g id="SvgjsG1365" transform="translate(408,25)"><path id="SvgjsPath1366" d="M0 0L120 0L120 40L0 40Z " stroke="none" fill="none"></path><g id="SvgjsG1367"><text id="SvgjsText1368" font-family="微软雅黑" text-anchor="middle" font-size="13px" width="120px" fill="#323232" font-weight="700" align="middle" lineHeight="125%" font-style="" opacity="1" y="10.375" transform="rotate(0)"><tspan id="SvgjsTspan1369" dy="16" x="60"><tspan id="SvgjsTspan1370" style="text-decoration:;">A</tspan></tspan></text></g></g><g id="SvgjsG1371" transform="translate(436,234)"><path id="SvgjsPath1372" d="M0 0L120 0L120 40L0 40Z " stroke="none" fill="none"></path><g id="SvgjsG1373"><text id="SvgjsText1374" font-family="微软雅黑" text-anchor="middle" font-size="13px" width="120px" fill="#323232" font-weight="700" align="middle" lineHeight="125%" font-style="" opacity="1" y="10.375" transform="rotate(0)"><tspan id="SvgjsTspan1375" dy="16" x="60"><tspan id="SvgjsTspan1376" style="text-decoration:;">B</tspan></tspan></text></g></g><g id="SvgjsG1377"><path id="SvgjsPath1378" d="M126 202L193.5 202L193.5 202L258.4 202 " stroke="#81c784" stroke-width="2" fill="none" marker-end="url(#SvgjsMarker1379)"></path></g><g id="SvgjsG1381"><path id="SvgjsPath1382" d="M261 202L193.5 202L193.5 202L128.6 202 " stroke="#81c784" stroke-width="2" fill="none" marker-end="url(#SvgjsMarker1383)"></path></g><g id="SvgjsG1385"><path id="SvgjsPath1386" d="M351.36348812088426 199.28450301004787L440.63651187911574 96.71549698995211 " stroke="#81c784" stroke-width="2" fill="none" marker-start="url(#SvgjsMarker1387)" marker-end="url(#SvgjsMarker1389)"></path><rect id="SvgjsRect1391" width="32" height="16" x="380" y="140" fill="#ffffff"></rect><text id="SvgjsText1392" font-family="微软雅黑" text-anchor="middle" font-size="13px" width="32px" fill="#323232" font-weight="700" align="top" lineHeight="16px" font-style="" opacity="1" y="138.375" transform="rotate(0)"><tspan id="SvgjsTspan1393" dy="16" x="396"><tspan id="SvgjsTspan1394" style="text-decoration:;">A-P1</tspan></tspan></text></g><g id="SvgjsG1395"><path id="SvgjsPath1396" d="M352.0826487107812 200.14062458714787L471.9173512892188 127.85937541285216 " stroke="#81c784" stroke-width="2" fill="none" marker-start="url(#SvgjsMarker1397)" marker-end="url(#SvgjsMarker1399)"></path><rect id="SvgjsRect1401" width="32" height="16" x="396" y="156" fill="#ffffff"></rect><text id="SvgjsText1402" font-family="微软雅黑" text-anchor="middle" font-size="13px" width="32px" fill="#323232" font-weight="700" align="top" lineHeight="16px" font-style="" opacity="1" y="154.375" transform="rotate(0)"><tspan id="SvgjsTspan1403" dy="16" x="412"><tspan id="SvgjsTspan1404" style="text-decoration:;">A-P2</tspan></tspan></text></g><g id="SvgjsG1405"><path id="SvgjsPath1406" d="M351.75181786213153 204.3210985445805L461.24818213786847 296.67890145541946 " stroke="#81c784" stroke-width="2" fill="none" marker-start="url(#SvgjsMarker1407)" marker-end="url(#SvgjsMarker1409)"></path><rect id="SvgjsRect1411" width="31" height="16" x="391" y="242.5" fill="#ffffff"></rect><text id="SvgjsText1412" font-family="微软雅黑" text-anchor="middle" font-size="13px" width="31px" fill="#323232" font-weight="700" align="top" lineHeight="16px" font-style="" opacity="1" y="240.875" transform="rotate(0)"><tspan id="SvgjsTspan1413" dy="16" x="406.5"><tspan id="SvgjsTspan1414" style="text-decoration:;">B-P1</tspan></tspan></text></g></svg> ##### (2)受限锥型NAT(Restricted Cone NAT) 把所有来自相同内部IP 地址和端口的请求映射到相同的外部IP 地址和端,但是和全锥NAT 不同的是:只有当内部主机先给外部主机发送数据包, 该外部主机才能向该内部主机发送数据包。 特点:IP受限,端口不受限。 表现形式:与完全锥形NAT不同的是,在公网映射端口后,并不允许所有IP进行对于该端口的访问,要想通信必需内部主机对某个外部IP主机发起过连接,然后这个外部IP主机就可以与该内部主机通信了,但端口不做限制。举个栗子。当客户端由内到外建立映射(NatIP:NatPort –> A:P1),A机器可以使用他的其他端口(P2)主动连接客户端,但B机器则不被允许。因为IP受限啦,但是端口随便。见下图(绿色是允许通信,红色是禁止通信) <svg id="SvgjsSvg1415" xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svgjs="http://svgjs.com/svgjs" width="100%" height="356"><rect fill="url(#pattern_mark)" transform="translate(-0.399993896484375,7)" width="100%" height="500" id="rect_mark" pointer-events="none"></rect><defs id="SvgjsDefs1416"><pattern id="SvgjsPattern1419" x="0" y="0" width="64" height="64" patternUnits="userSpaceOnUse"><image id="SvgjsImage1420" xlink:href="https://img8.file.cache.docer.com/storage/image/1638348423287/d/3/4/f/d/7545dea13aeedffb48bceaa8f81e98d5.png" width="64" height="64" preserveAspectRatio="none" crossOrigin="anonymous" x="0" y="0"></image></pattern><pattern id="SvgjsPattern1423" x="0" y="0" width="87" height="88" patternUnits="userSpaceOnUse"><image id="SvgjsImage1424" xlink:href="https://img8.file.cache.docer.com/storage/image/1637754713062/9/9/b/e/2/68169bf99dd22d70ba7baab4e568a82f.png" width="87" height="88" preserveAspectRatio="none" crossOrigin="anonymous" x="0" y="0"></image></pattern><pattern id="SvgjsPattern1427" x="0" y="0" width="64" height="64" patternUnits="userSpaceOnUse"><image id="SvgjsImage1428" xlink:href="https://img8.file.cache.docer.com/storage/image/1638352865811/c/d/5/2/2/ab77cbebdabcbfc250a47349253c6e20.png" width="64" height="64" preserveAspectRatio="none" crossOrigin="anonymous" x="0" y="0"></image></pattern><pattern id="SvgjsPattern1437" x="0" y="0" width="64" height="64" patternUnits="userSpaceOnUse"><image id="SvgjsImage1438" xlink:href="https://img8.file.cache.docer.com/storage/image/1638352865811/c/d/5/2/2/ab77cbebdabcbfc250a47349253c6e20.png" width="64" height="64" preserveAspectRatio="none" crossOrigin="anonymous" x="0" y="0"></image></pattern><marker id="SvgjsMarker1459" markerWidth="14" markerHeight="10" refX="10" refY="5" viewBox="0 0 14 10" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1460" d="M0 0L14 5L0 10L0 0 " fill="#81c784" stroke="#81c784" stroke-width="1"></path></marker><marker id="SvgjsMarker1463" markerWidth="14" markerHeight="10" refX="10" refY="5" viewBox="0 0 14 10" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1464" d="M0 0L14 5L0 10L0 0 " fill="#81c784" stroke="#81c784" stroke-width="1"></path></marker><marker id="SvgjsMarker1467" markerWidth="14" markerHeight="10" refX="4" refY="5" viewBox="0 0 14 10" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1468" d="M14 0L0 5L14 10L14 0 " fill="#81c784" stroke="#81c784" stroke-width="1"></path></marker><marker id="SvgjsMarker1469" markerWidth="14" markerHeight="10" refX="10" refY="5" viewBox="0 0 14 10" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1470" d="M0 0L14 5L0 10L0 0 " fill="#81c784" stroke="#81c784" stroke-width="1"></path></marker><marker id="SvgjsMarker1477" markerWidth="14" markerHeight="10" refX="4" refY="5" viewBox="0 0 14 10" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1478" d="M14 0L0 5L14 10L14 0 " fill="#81c784" stroke="#81c784" stroke-width="1"></path></marker><marker id="SvgjsMarker1479" markerWidth="14" markerHeight="10" refX="10" refY="5" viewBox="0 0 14 10" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1480" d="M0 0L14 5L0 10L0 0 " fill="#81c784" stroke="#81c784" stroke-width="1"></path></marker><marker id="SvgjsMarker1487" markerWidth="14" markerHeight="10" refX="4" refY="5" viewBox="0 0 14 10" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1488" d="M14 0L0 5L14 10L14 0 " fill="#f44336" stroke="#f44336" stroke-width="1"></path></marker><marker id="SvgjsMarker1489" markerWidth="14" markerHeight="10" refX="10" refY="5" viewBox="0 0 14 10" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1490" d="M0 0L14 5L0 10L0 0 " fill="#f44336" stroke="#f44336" stroke-width="1"></path></marker><pattern patternUnits="userSpaceOnUse" id="pattern_mark" width="300" height="300"><text x="-50" y="150" fill="rgba(229,229,229,0.8)" font-size="18" transform="rotate(-45, 150, 150)"></text></pattern></defs><g id="SvgjsG1417" transform="translate(61,170)"><path id="SvgjsPath1418" d="M0 0L64 0L64 64L0 64Z " stroke="none" fill="url(#SvgjsPattern1419)"></path></g><g id="SvgjsG1421" transform="translate(262,158)"><path id="SvgjsPath1422" d="M0 0L87 0L87 88L0 88Z " stroke="none" fill="url(#SvgjsPattern1423)"></path></g><g id="SvgjsG1425" transform="translate(443,62)"><path id="SvgjsPath1426" d="M0 0L64 0L64 64L0 64Z " stroke="none" fill="url(#SvgjsPattern1427)"></path></g><g id="SvgjsG1429" transform="translate(25,148)"><path id="SvgjsPath1430" d="M0 0L120 0L120 40L0 40Z " stroke="none" fill="none"></path><g id="SvgjsG1431"><text id="SvgjsText1432" font-family="微软雅黑" text-anchor="middle" font-size="13px" width="120px" fill="#323232" font-weight="400" align="middle" lineHeight="125%" font-style="" opacity="1" y="10.375" transform="rotate(0)"><tspan id="SvgjsTspan1433" dy="16" x="60"><tspan id="SvgjsTspan1434" style="text-decoration:;font-weight: bold;">Client</tspan></tspan></text></g></g><g id="SvgjsG1435" transform="translate(464,267)"><path id="SvgjsPath1436" d="M0 0L64 0L64 64L0 64Z " stroke="none" fill="url(#SvgjsPattern1437)"></path></g><g id="SvgjsG1439" transform="translate(247.5,130)"><path id="SvgjsPath1440" d="M0 0L120 0L120 40L0 40Z " stroke="none" fill="none"></path><g id="SvgjsG1441"><text id="SvgjsText1442" font-family="微软雅黑" text-anchor="middle" font-size="13px" width="120px" fill="#323232" font-weight="700" align="middle" lineHeight="125%" font-style="" opacity="1" y="10.375" transform="rotate(0)"><tspan id="SvgjsTspan1443" dy="16" x="60"><tspan id="SvgjsTspan1444" style="text-decoration:;">Restricted Cone </tspan></tspan></text></g></g><g id="SvgjsG1445" transform="translate(408,25)"><path id="SvgjsPath1446" d="M0 0L120 0L120 40L0 40Z " stroke="none" fill="none"></path><g id="SvgjsG1447"><text id="SvgjsText1448" font-family="微软雅黑" text-anchor="middle" font-size="13px" width="120px" fill="#323232" font-weight="700" align="middle" lineHeight="125%" font-style="" opacity="1" y="10.375" transform="rotate(0)"><tspan id="SvgjsTspan1449" dy="16" x="60"><tspan id="SvgjsTspan1450" style="text-decoration:;">A</tspan></tspan></text></g></g><g id="SvgjsG1451" transform="translate(436,234)"><path id="SvgjsPath1452" d="M0 0L120 0L120 40L0 40Z " stroke="none" fill="none"></path><g id="SvgjsG1453"><text id="SvgjsText1454" font-family="微软雅黑" text-anchor="middle" font-size="13px" width="120px" fill="#323232" font-weight="700" align="middle" lineHeight="125%" font-style="" opacity="1" y="10.375" transform="rotate(0)"><tspan id="SvgjsTspan1455" dy="16" x="60"><tspan id="SvgjsTspan1456" style="text-decoration:;">B</tspan></tspan></text></g></g><g id="SvgjsG1457"><path id="SvgjsPath1458" d="M126 202L193.5 202L193.5 202L258.4 202 " stroke="#81c784" stroke-width="2" fill="none" marker-end="url(#SvgjsMarker1459)"></path></g><g id="SvgjsG1461"><path id="SvgjsPath1462" d="M261 202L193.5 202L193.5 202L128.6 202 " stroke="#81c784" stroke-width="2" fill="none" marker-end="url(#SvgjsMarker1463)"></path></g><g id="SvgjsG1465"><path id="SvgjsPath1466" d="M351.36348812088426 199.28450301004787L440.63651187911574 96.71549698995211 " stroke="#81c784" stroke-width="2" fill="none" marker-start="url(#SvgjsMarker1467)" marker-end="url(#SvgjsMarker1469)"></path><rect id="SvgjsRect1471" width="32" height="16" x="380" y="140" fill="#ffffff"></rect><text id="SvgjsText1472" font-family="微软雅黑" text-anchor="middle" font-size="13px" width="32px" fill="#323232" font-weight="700" align="top" lineHeight="16px" font-style="" opacity="1" y="138.375" transform="rotate(0)"><tspan id="SvgjsTspan1473" dy="16" x="396"><tspan id="SvgjsTspan1474" style="text-decoration:;">A-P1</tspan></tspan></text></g><g id="SvgjsG1475"><path id="SvgjsPath1476" d="M352.0826487107812 200.14062458714787L471.9173512892188 127.85937541285216 " stroke="#81c784" stroke-width="2" fill="none" marker-start="url(#SvgjsMarker1477)" marker-end="url(#SvgjsMarker1479)"></path><rect id="SvgjsRect1481" width="32" height="16" x="396" y="156" fill="#ffffff"></rect><text id="SvgjsText1482" font-family="微软雅黑" text-anchor="middle" font-size="13px" width="32px" fill="#323232" font-weight="700" align="top" lineHeight="16px" font-style="" opacity="1" y="154.375" transform="rotate(0)"><tspan id="SvgjsTspan1483" dy="16" x="412"><tspan id="SvgjsTspan1484" style="text-decoration:;">A-P2</tspan></tspan></text></g><g id="SvgjsG1485"><path id="SvgjsPath1486" d="M351.75181786213153 204.3210985445805L461.24818213786847 296.67890145541946 " stroke="#f44336" stroke-width="2" fill="none" marker-start="url(#SvgjsMarker1487)" marker-end="url(#SvgjsMarker1489)"></path><rect id="SvgjsRect1491" width="31" height="16" x="391" y="242.5" fill="#ffffff"></rect><text id="SvgjsText1492" font-family="微软雅黑" text-anchor="middle" font-size="13px" width="31px" fill="#323232" font-weight="700" align="top" lineHeight="16px" font-style="" opacity="1" y="240.875" transform="rotate(0)"><tspan id="SvgjsTspan1493" dy="16" x="406.5"><tspan id="SvgjsTspan1494" style="text-decoration:;">B-P1</tspan></tspan></text></g></svg> ##### (3)端口受限型NAT(Port Restricted Cone NAT) 端口限制性锥NAT 与限制性锥NAT 类似, 只是多了端口号的限制, 即只有内部主机先向外部地址:端口号对发送数据包, 该外部主机才能使用特定的端口号向内部主机发送数据包。 特点:IP和端口都受限。 表现形式:该技术与受限锥形NAT相比更为严格。除具有受限锥形NAT特性,对于回复主机的端口也有要求。也就是说:只有当内部主机曾经发送过报文给外部主机(假设其IP地址为A且端口为P1)之后,外部主机才能以公网IP:PORT中的信息作为目标地址和目标端口,向内部主机发送UDP报文,同时,其请求报文的IP必须是A,端口必须为P1(使用IP地址为A,端口为P2,或者IP地址为B,端口为P1都将通信失败)。例子见下图。这一要求进一步强化了对外部报文请求来源的限制,从而较Restrictd Cone更具安全性。 <svg id="SvgjsSvg1655" xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svgjs="http://svgjs.com/svgjs" width="100%" height="356"><rect fill="url(#pattern_mark)" transform="translate(-0.399993896484375,7)" width="100%" height="500" id="rect_mark" pointer-events="none"></rect><defs id="SvgjsDefs1656"><pattern id="SvgjsPattern1659" x="0" y="0" width="64" height="64" patternUnits="userSpaceOnUse"><image id="SvgjsImage1660" xlink:href="https://img8.file.cache.docer.com/storage/image/1638348423287/d/3/4/f/d/7545dea13aeedffb48bceaa8f81e98d5.png" width="64" height="64" preserveAspectRatio="none" crossOrigin="anonymous" x="0" y="0"></image></pattern><pattern id="SvgjsPattern1663" x="0" y="0" width="87" height="88" patternUnits="userSpaceOnUse"><image id="SvgjsImage1664" xlink:href="https://img8.file.cache.docer.com/storage/image/1637754713062/9/9/b/e/2/68169bf99dd22d70ba7baab4e568a82f.png" width="87" height="88" preserveAspectRatio="none" crossOrigin="anonymous" x="0" y="0"></image></pattern><pattern id="SvgjsPattern1667" x="0" y="0" width="64" height="64" patternUnits="userSpaceOnUse"><image id="SvgjsImage1668" xlink:href="https://img8.file.cache.docer.com/storage/image/1638352865811/c/d/5/2/2/ab77cbebdabcbfc250a47349253c6e20.png" width="64" height="64" preserveAspectRatio="none" crossOrigin="anonymous" x="0" y="0"></image></pattern><pattern id="SvgjsPattern1677" x="0" y="0" width="64" height="64" patternUnits="userSpaceOnUse"><image id="SvgjsImage1678" xlink:href="https://img8.file.cache.docer.com/storage/image/1638352865811/c/d/5/2/2/ab77cbebdabcbfc250a47349253c6e20.png" width="64" height="64" preserveAspectRatio="none" crossOrigin="anonymous" x="0" y="0"></image></pattern><marker id="SvgjsMarker1699" markerWidth="14" markerHeight="10" refX="10" refY="5" viewBox="0 0 14 10" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1700" d="M0 0L14 5L0 10L0 0 " fill="#81c784" stroke="#81c784" stroke-width="1"></path></marker><marker id="SvgjsMarker1703" markerWidth="14" markerHeight="10" refX="10" refY="5" viewBox="0 0 14 10" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1704" d="M0 0L14 5L0 10L0 0 " fill="#81c784" stroke="#81c784" stroke-width="1"></path></marker><marker id="SvgjsMarker1707" markerWidth="14" markerHeight="10" refX="4" refY="5" viewBox="0 0 14 10" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1708" d="M14 0L0 5L14 10L14 0 " fill="#f44336" stroke="#f44336" stroke-width="1"></path></marker><marker id="SvgjsMarker1709" markerWidth="14" markerHeight="10" refX="10" refY="5" viewBox="0 0 14 10" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1710" d="M0 0L14 5L0 10L0 0 " fill="#f44336" stroke="#f44336" stroke-width="1"></path></marker><marker id="SvgjsMarker1717" markerWidth="14" markerHeight="10" refX="4" refY="5" viewBox="0 0 14 10" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1718" d="M14 0L0 5L14 10L14 0 " fill="#81c784" stroke="#81c784" stroke-width="1"></path></marker><marker id="SvgjsMarker1719" markerWidth="14" markerHeight="10" refX="10" refY="5" viewBox="0 0 14 10" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1720" d="M0 0L14 5L0 10L0 0 " fill="#81c784" stroke="#81c784" stroke-width="1"></path></marker><marker id="SvgjsMarker1727" markerWidth="14" markerHeight="10" refX="4" refY="5" viewBox="0 0 14 10" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1728" d="M14 0L0 5L14 10L14 0 " fill="#f44336" stroke="#f44336" stroke-width="1"></path></marker><marker id="SvgjsMarker1729" markerWidth="14" markerHeight="10" refX="10" refY="5" viewBox="0 0 14 10" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1730" d="M0 0L14 5L0 10L0 0 " fill="#f44336" stroke="#f44336" stroke-width="1"></path></marker><pattern patternUnits="userSpaceOnUse" id="pattern_mark" width="300" height="300"><text x="-50" y="150" fill="rgba(229,229,229,0.8)" font-size="18" transform="rotate(-45, 150, 150)"></text></pattern></defs><g id="SvgjsG1657" transform="translate(61,170)"><path id="SvgjsPath1658" d="M0 0L64 0L64 64L0 64Z " stroke="none" fill="url(#SvgjsPattern1659)"></path></g><g id="SvgjsG1661" transform="translate(262,158)"><path id="SvgjsPath1662" d="M0 0L87 0L87 88L0 88Z " stroke="none" fill="url(#SvgjsPattern1663)"></path></g><g id="SvgjsG1665" transform="translate(443,62)"><path id="SvgjsPath1666" d="M0 0L64 0L64 64L0 64Z " stroke="none" fill="url(#SvgjsPattern1667)"></path></g><g id="SvgjsG1669" transform="translate(25,148)"><path id="SvgjsPath1670" d="M0 0L120 0L120 40L0 40Z " stroke="none" fill="none"></path><g id="SvgjsG1671"><text id="SvgjsText1672" font-family="微软雅黑" text-anchor="middle" font-size="13px" width="120px" fill="#323232" font-weight="400" align="middle" lineHeight="125%" font-style="" opacity="1" y="10.375" transform="rotate(0)"><tspan id="SvgjsTspan1673" dy="16" x="60"><tspan id="SvgjsTspan1674" style="text-decoration:;font-weight: bold;">Client</tspan></tspan></text></g></g><g id="SvgjsG1675" transform="translate(464,267)"><path id="SvgjsPath1676" d="M0 0L64 0L64 64L0 64Z " stroke="none" fill="url(#SvgjsPattern1677)"></path></g><g id="SvgjsG1679" transform="translate(215,126)"><path id="SvgjsPath1680" d="M0 0L148 0L148 35L0 35Z " stroke="none" fill="none"></path><g id="SvgjsG1681"><text id="SvgjsText1682" font-family="微软雅黑" text-anchor="middle" font-size="13px" width="148px" fill="#323232" font-weight="700" align="middle" lineHeight="125%" font-style="" opacity="1" y="7.875" transform="rotate(0)"><tspan id="SvgjsTspan1683" dy="16" x="74"><tspan id="SvgjsTspan1684" style="text-decoration:;">Port Restricted Cone</tspan></tspan></text></g></g><g id="SvgjsG1685" transform="translate(408,25)"><path id="SvgjsPath1686" d="M0 0L120 0L120 40L0 40Z " stroke="none" fill="none"></path><g id="SvgjsG1687"><text id="SvgjsText1688" font-family="微软雅黑" text-anchor="middle" font-size="13px" width="120px" fill="#323232" font-weight="700" align="middle" lineHeight="125%" font-style="" opacity="1" y="10.375" transform="rotate(0)"><tspan id="SvgjsTspan1689" dy="16" x="60"><tspan id="SvgjsTspan1690" style="text-decoration:;">A</tspan></tspan></text></g></g><g id="SvgjsG1691" transform="translate(436,234)"><path id="SvgjsPath1692" d="M0 0L120 0L120 40L0 40Z " stroke="none" fill="none"></path><g id="SvgjsG1693"><text id="SvgjsText1694" font-family="微软雅黑" text-anchor="middle" font-size="13px" width="120px" fill="#323232" font-weight="700" align="middle" lineHeight="125%" font-style="" opacity="1" y="10.375" transform="rotate(0)"><tspan id="SvgjsTspan1695" dy="16" x="60"><tspan id="SvgjsTspan1696" style="text-decoration:;">B</tspan></tspan></text></g></g><g id="SvgjsG1697"><path id="SvgjsPath1698" d="M126 202L193.5 202L193.5 202L258.4 202 " stroke="#81c784" stroke-width="2" fill="none" marker-end="url(#SvgjsMarker1699)"></path></g><g id="SvgjsG1701"><path id="SvgjsPath1702" d="M261 202L193.5 202L193.5 202L128.6 202 " stroke="#81c784" stroke-width="2" fill="none" marker-end="url(#SvgjsMarker1703)"></path></g><g id="SvgjsG1705"><path id="SvgjsPath1706" d="M351.36348812088426 199.28450301004787L440.63651187911574 96.71549698995211 " stroke="#f44336" stroke-width="2" fill="none" marker-start="url(#SvgjsMarker1707)" marker-end="url(#SvgjsMarker1709)"></path><rect id="SvgjsRect1711" width="32" height="16" x="380" y="140" fill="#ffffff"></rect><text id="SvgjsText1712" font-family="微软雅黑" text-anchor="middle" font-size="13px" width="32px" fill="#323232" font-weight="700" align="top" lineHeight="16px" font-style="" opacity="1" y="138.375" transform="rotate(0)"><tspan id="SvgjsTspan1713" dy="16" x="396"><tspan id="SvgjsTspan1714" style="text-decoration:;">A-P1</tspan></tspan></text></g><g id="SvgjsG1715"><path id="SvgjsPath1716" d="M352.0826487107812 200.14062458714787L471.9173512892188 127.85937541285216 " stroke="#81c784" stroke-width="2" fill="none" marker-start="url(#SvgjsMarker1717)" marker-end="url(#SvgjsMarker1719)"></path><rect id="SvgjsRect1721" width="32" height="16" x="396" y="156" fill="#ffffff"></rect><text id="SvgjsText1722" font-family="微软雅黑" text-anchor="middle" font-size="13px" width="32px" fill="#323232" font-weight="700" align="top" lineHeight="16px" font-style="" opacity="1" y="154.375" transform="rotate(0)"><tspan id="SvgjsTspan1723" dy="16" x="412"><tspan id="SvgjsTspan1724" style="text-decoration:;">A-P2</tspan></tspan></text></g><g id="SvgjsG1725"><path id="SvgjsPath1726" d="M351.75181786213153 204.3210985445805L461.24818213786847 296.67890145541946 " stroke="#f44336" stroke-width="2" fill="none" marker-start="url(#SvgjsMarker1727)" marker-end="url(#SvgjsMarker1729)"></path><rect id="SvgjsRect1731" width="31" height="16" x="391" y="242.5" fill="#ffffff"></rect><text id="SvgjsText1732" font-family="微软雅黑" text-anchor="middle" font-size="13px" width="31px" fill="#323232" font-weight="700" align="top" lineHeight="16px" font-style="" opacity="1" y="240.875" transform="rotate(0)"><tspan id="SvgjsTspan1733" dy="16" x="406.5"><tspan id="SvgjsTspan1734" style="text-decoration:;">B-P1</tspan></tspan></text></g></svg> ##### (4) 对称 NAT ( Symmetric NAT) 对称NAT 与上述3 种类型都不同, 不管是全锥NAT ,限制性锥NAT 还是端口限制性锥NAT ,它们都属于锥NAT (Cone NAT )。当同一内部主机使用相同的端口与不同地址的外部主机进行通信时, 对称NAT 会重新建立一个Session ,为这个Session 分配不同的端口号,或许还会改变IP 地址。 特点:对每个外部主机或端口的会话都会映射为不同的端口(洞) 表现形式:只有来自同一内部IP:PORT、且针对同一目标IP:PORT的请求才被NAT转换至同一个公网(外部)IP:PORT,否则的话,NAT将为之分配一个新的外部(公网)IP:PORT。并且,只有曾经收到过内部主机请求的外部主机才能向内部主机发送数据包。内部主机用同一IP与同一端口与外部多IP通信。客户端想和服务器A(IP_A:PORT_A)建立连接,是通过NAT映射为NatIP:NatPortA来进行的。而客户端和服务器B(IP_B:PORT_B)建立连接,是通过NAT映射为NatIP:NatPortB来进行的。即同一个客户端和不同的目标IP:PORT通信,经过NAT映射后的公网IP:PORT是不同的。此时,如果B想要和客户端通信,也只能通过NatIP:NatPortB(也就是紫色的洞洞)来进行,而不能通过NatIP:NatPortA(也就是黄色的洞洞) <svg id="SvgjsSvg1735" xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svgjs="http://svgjs.com/svgjs" width="100%" height="356"><rect fill="url(#pattern_mark)" transform="translate(-0.399993896484375,7)" width="100%" height="500" id="rect_mark" pointer-events="none"></rect><defs id="SvgjsDefs1736"><pattern id="SvgjsPattern1739" x="0" y="0" width="64" height="64" patternUnits="userSpaceOnUse"><image id="SvgjsImage1740" xlink:href="https://img8.file.cache.docer.com/storage/image/1638348423287/d/3/4/f/d/7545dea13aeedffb48bceaa8f81e98d5.png" width="64" height="64" preserveAspectRatio="none" crossOrigin="anonymous" x="0" y="0"></image></pattern><pattern id="SvgjsPattern1743" x="0" y="0" width="87" height="88" patternUnits="userSpaceOnUse"><image id="SvgjsImage1744" xlink:href="https://img8.file.cache.docer.com/storage/image/1637754713062/9/9/b/e/2/68169bf99dd22d70ba7baab4e568a82f.png" width="87" height="88" preserveAspectRatio="none" crossOrigin="anonymous" x="0" y="0"></image></pattern><pattern id="SvgjsPattern1747" x="0" y="0" width="64" height="64" patternUnits="userSpaceOnUse"><image id="SvgjsImage1748" xlink:href="https://img8.file.cache.docer.com/storage/image/1638352865811/c/d/5/2/2/ab77cbebdabcbfc250a47349253c6e20.png" width="64" height="64" preserveAspectRatio="none" crossOrigin="anonymous" x="0" y="0"></image></pattern><pattern id="SvgjsPattern1757" x="0" y="0" width="64" height="64" patternUnits="userSpaceOnUse"><image id="SvgjsImage1758" xlink:href="https://img8.file.cache.docer.com/storage/image/1638352865811/c/d/5/2/2/ab77cbebdabcbfc250a47349253c6e20.png" width="64" height="64" preserveAspectRatio="none" crossOrigin="anonymous" x="0" y="0"></image></pattern><marker id="SvgjsMarker1779" markerWidth="14" markerHeight="10" refX="10" refY="5" viewBox="0 0 14 10" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1780" d="M0 0L14 5L0 10L0 0 " fill="#81c784" stroke="#81c784" stroke-width="1"></path></marker><marker id="SvgjsMarker1783" markerWidth="14" markerHeight="10" refX="10" refY="5" viewBox="0 0 14 10" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1784" d="M0 0L14 5L0 10L0 0 " fill="#81c784" stroke="#81c784" stroke-width="1"></path></marker><marker id="SvgjsMarker1787" markerWidth="14" markerHeight="10" refX="4" refY="5" viewBox="0 0 14 10" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1788" d="M14 0L0 5L14 10L14 0 " fill="#f57f17" stroke="#f57f17" stroke-width="1"></path></marker><marker id="SvgjsMarker1789" markerWidth="14" markerHeight="10" refX="10" refY="5" viewBox="0 0 14 10" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1790" d="M0 0L14 5L0 10L0 0 " fill="#f57f17" stroke="#f57f17" stroke-width="1"></path></marker><marker id="SvgjsMarker1793" markerWidth="14" markerHeight="10" refX="4" refY="5" viewBox="0 0 14 10" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1794" d="M14 0L0 5L14 10L14 0 " fill="#f57f17" stroke="#f57f17" stroke-width="1"></path></marker><marker id="SvgjsMarker1795" markerWidth="14" markerHeight="10" refX="10" refY="5" viewBox="0 0 14 10" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1796" d="M0 0L14 5L0 10L0 0 " fill="#f57f17" stroke="#f57f17" stroke-width="1"></path></marker><marker id="SvgjsMarker1799" markerWidth="14" markerHeight="10" refX="4" refY="5" viewBox="0 0 14 10" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1800" d="M14 0L0 5L14 10L14 0 " fill="#7b1fa2" stroke="#7b1fa2" stroke-width="1"></path></marker><marker id="SvgjsMarker1801" markerWidth="14" markerHeight="10" refX="10" refY="5" viewBox="0 0 14 10" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1802" d="M0 0L14 5L0 10L0 0 " fill="#7b1fa2" stroke="#7b1fa2" stroke-width="1"></path></marker><marker id="SvgjsMarker1805" markerWidth="14" markerHeight="10" refX="4" refY="5" viewBox="0 0 14 10" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1806" d="M14 0L0 5L14 10L14 0 " fill="#7b1fa2" stroke="#7b1fa2" stroke-width="1"></path></marker><marker id="SvgjsMarker1807" markerWidth="14" markerHeight="10" refX="10" refY="5" viewBox="0 0 14 10" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1808" d="M0 0L14 5L0 10L0 0 " fill="#7b1fa2" stroke="#7b1fa2" stroke-width="1"></path></marker><pattern patternUnits="userSpaceOnUse" id="pattern_mark" width="300" height="300"><text x="-50" y="150" fill="rgba(229,229,229,0.8)" font-size="18" transform="rotate(-45, 150, 150)"></text></pattern></defs><g id="SvgjsG1737" transform="translate(61,170)"><path id="SvgjsPath1738" d="M0 0L64 0L64 64L0 64Z " stroke="none" fill="url(#SvgjsPattern1739)"></path></g><g id="SvgjsG1741" transform="translate(262,158)"><path id="SvgjsPath1742" d="M0 0L87 0L87 88L0 88Z " stroke="none" fill="url(#SvgjsPattern1743)"></path></g><g id="SvgjsG1745" transform="translate(443,62)"><path id="SvgjsPath1746" d="M0 0L64 0L64 64L0 64Z " stroke="none" fill="url(#SvgjsPattern1747)"></path></g><g id="SvgjsG1749" transform="translate(25,148)"><path id="SvgjsPath1750" d="M0 0L120 0L120 40L0 40Z " stroke="none" fill="none"></path><g id="SvgjsG1751"><text id="SvgjsText1752" font-family="微软雅黑" text-anchor="middle" font-size="13px" width="120px" fill="#323232" font-weight="400" align="middle" lineHeight="125%" font-style="" opacity="1" y="10.375" transform="rotate(0)"><tspan id="SvgjsTspan1753" dy="16" x="60"><tspan id="SvgjsTspan1754" style="text-decoration:;font-weight: bold;">Client</tspan></tspan></text></g></g><g id="SvgjsG1755" transform="translate(464,267)"><path id="SvgjsPath1756" d="M0 0L64 0L64 64L0 64Z " stroke="none" fill="url(#SvgjsPattern1757)"></path></g><g id="SvgjsG1759" transform="translate(215,126)"><path id="SvgjsPath1760" d="M0 0L148 0L148 35L0 35Z " stroke="none" fill="none"></path><g id="SvgjsG1761"><text id="SvgjsText1762" font-family="微软雅黑" text-anchor="middle" font-size="13px" width="148px" fill="#323232" font-weight="700" align="middle" lineHeight="125%" font-style="" opacity="1" y="7.875" transform="rotate(0)"><tspan id="SvgjsTspan1763" dy="16" x="74"><tspan id="SvgjsTspan1764" style="text-decoration:;">Port Restricted Cone</tspan></tspan></text></g></g><g id="SvgjsG1765" transform="translate(408,25)"><path id="SvgjsPath1766" d="M0 0L120 0L120 40L0 40Z " stroke="none" fill="none"></path><g id="SvgjsG1767"><text id="SvgjsText1768" font-family="微软雅黑" text-anchor="middle" font-size="13px" width="120px" fill="#323232" font-weight="700" align="middle" lineHeight="125%" font-style="" opacity="1" y="10.375" transform="rotate(0)"><tspan id="SvgjsTspan1769" dy="16" x="60"><tspan id="SvgjsTspan1770" style="text-decoration:;">A</tspan></tspan></text></g></g><g id="SvgjsG1771" transform="translate(436,234)"><path id="SvgjsPath1772" d="M0 0L120 0L120 40L0 40Z " stroke="none" fill="none"></path><g id="SvgjsG1773"><text id="SvgjsText1774" font-family="微软雅黑" text-anchor="middle" font-size="13px" width="120px" fill="#323232" font-weight="700" align="middle" lineHeight="125%" font-style="" opacity="1" y="10.375" transform="rotate(0)"><tspan id="SvgjsTspan1775" dy="16" x="60"><tspan id="SvgjsTspan1776" style="text-decoration:;">B</tspan></tspan></text></g></g><g id="SvgjsG1777"><path id="SvgjsPath1778" d="M126 202L193.5 202L193.5 202L258.4 202 " stroke="#81c784" stroke-width="2" fill="none" marker-end="url(#SvgjsMarker1779)"></path></g><g id="SvgjsG1781"><path id="SvgjsPath1782" d="M261 202L193.5 202L193.5 202L128.6 202 " stroke="#81c784" stroke-width="2" fill="none" marker-end="url(#SvgjsMarker1783)"></path></g><g id="SvgjsG1785"><path id="SvgjsPath1786" d="M335.0820637878129 159.13965519113998L439.9179362121871 95.86034480886003 " stroke="#f57f17" stroke-width="2" fill="none" marker-start="url(#SvgjsMarker1787)" marker-end="url(#SvgjsMarker1789)"></path></g><g id="SvgjsG1791"><path id="SvgjsPath1792" d="M352.00339263984694 200.01514921192722L464 126 " stroke="#f57f17" stroke-width="2" fill="none" marker-start="url(#SvgjsMarker1793)" marker-end="url(#SvgjsMarker1795)"></path></g><g id="SvgjsG1797"><path id="SvgjsPath1798" d="M351.75181786213153 204.3210985445805L461.24818213786847 296.67890145541946 " stroke="#7b1fa2" stroke-width="2" fill="none" marker-start="url(#SvgjsMarker1799)" marker-end="url(#SvgjsMarker1801)"></path></g><g id="SvgjsG1803"><path id="SvgjsPath1804" d="M333.65854777814127 161.4273697104768L469 285 " stroke="#7b1fa2" stroke-width="2" fill="none" marker-start="url(#SvgjsMarker1805)" marker-end="url(#SvgjsMarker1807)"></path></g></svg> ## 3、NAT路由类型判断 根据上面的介绍,我们可以了解到,在实际的网络情况中,各个设备所处的网络环境是不同的。那么,如果这些设备想要进行通信,首先判断出设备所处的网络类型就是非常重要的一步。举个例子来说:对于视频会议和VoIP软件,对位于不同NAT内部的主机通信需要靠服务器来转发完成,这样就会增加服务器的负担。 为了解决这种问题,要尽量使位于不同NAT内部的主机建立直接通信,其中,最重要的一点就是要判断出NAT的类型,然后才能根据NAT的类型,设计出直接通信方案。不然的话,两个都在NAT的终端怎么通信呢?我们不知道对方的内网IP,即使把消息发到对方的网关,然后呢?网关怎么知道这条消息给谁,而且谁允许网关这么做了? 为了解决这个问题,也就是处于内网的主机之间能够穿越它们之间的NAT建立直接通信,STUN(Session Traversal Utilities for NAT,NAT会话穿越应用程序)技术就是其中比较重要的一种解决方法,并得到了广泛的应用(PS:除此之外,还有UPNP技术,ALG应用层网关识别技术,SBC会话边界控制,ICE交互式连接建立,TURN中继NAT穿越技术等等,本文不一一做介绍) 对于 STUN 这部分内容在本文最后的延伸阅读里,篇幅较长,有兴趣的可以阅读。 #### 测试工具 **NatTypeTester** (NAT路由类型检测工具)是一款帮助用户检测NAT路由类型的工具,打开即可使用,非常方便。NAT类型会影响我们平时使用网络的情况,如果不清楚自己路由的NAT的话,就用这个工具来试试吧。[工具下载](https://www.kdocs.cn/view/l/sbqlNBgN1kJD) RFC支持 RFC 3489 RFC 5389 RFC 5769 RFC 5780 RFC 7350 RFC 7443 RFC 7635 RFC 8489 互联网协议 IPv4 IPv6 传输协议 UDP TCP TLS-over-TCP DTLS-over-UDP 增加 SOCKS5 支持 ## 4、P2P网络 p2p网络,即对等计算机网络,是一种在对等者(Peer)之间分配任务和工作负载的分布式应用架构,是对等计算模型在应用层形成的一种组网或网络形式。网络的参与者共享他们所拥有的一部分硬件资源(处理能力、存储能力、网络连接能力、打印机等),这些共享资源通过网络提供服务和内容,能被其它对等节点(Peer)直接访问而无需经过中间实体。在此网络中的参与者既是资源、服务和内容的提供者(Server),又是资源、服务和内容的获取者(Client)。 在P2P网络环境中,彼此连接的多台计算机之间都处于对等的地位,各台计算机有相同的功能,无主从之分,一台计算机既可作为服务器,设定共享资源供网络中其他计算机所使用,又可以作为工作站,整个网络一般来说不依赖专用的集中服务器,也没有专用的工作站。网络中的每一台计算机既能充当网络服务的请求者,又对其它计算机的请求做出响应,提供资源、服务和内容。通常这些资源和服务包括:信息的共享和交换、计算资源(如CPU计算能力共享)、存储共享(如缓存和磁盘空间的使用)、网络共享、打印机共享等 <svg id="SvgjsSvg1000" xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svgjs="http://svgjs.com/svgjs" width="363.4125061035156" height="317.0874938964844"><rect fill="url(#pattern_mark)" transform="translate(37.875,8.912490844726562)" width="400" height="320" id="rect_mark" pointer-events="none"></rect><defs id="SvgjsDefs1001"><pattern id="SvgjsPattern1009" x="0" y="0" width="37.27274391867894" height="43.81818181818184" patternUnits="userSpaceOnUse"><image id="SvgjsImage1010" xlink:href="https://img7.file.cache.docer.com/storage/image/1637754951839/f/4/b/9/6/2fcaf7b447e7f49dbf7615a29dc88b6f.png" width="37.27274391867894" height="43.81818181818184" preserveAspectRatio="none" crossOrigin="anonymous" x="0" y="0"></image></pattern><pattern id="SvgjsPattern1013" x="0" y="0" width="37.27274391867894" height="43.81818181818184" patternUnits="userSpaceOnUse"><image id="SvgjsImage1014" xlink:href="https://img7.file.cache.docer.com/storage/image/1637754951839/f/4/b/9/6/2fcaf7b447e7f49dbf7615a29dc88b6f.png" width="37.27274391867894" height="43.81818181818184" preserveAspectRatio="none" crossOrigin="anonymous" x="0" y="0"></image></pattern><pattern id="SvgjsPattern1017" x="0" y="0" width="37.27274391867894" height="43.81818181818184" patternUnits="userSpaceOnUse"><image id="SvgjsImage1018" xlink:href="https://img7.file.cache.docer.com/storage/image/1637754951839/f/4/b/9/6/2fcaf7b447e7f49dbf7615a29dc88b6f.png" width="37.27274391867894" height="43.81818181818184" preserveAspectRatio="none" crossOrigin="anonymous" x="0" y="0"></image></pattern><pattern id="SvgjsPattern1021" x="0" y="0" width="37.27274391867894" height="43.81818181818184" patternUnits="userSpaceOnUse"><image id="SvgjsImage1022" xlink:href="https://img7.file.cache.docer.com/storage/image/1637754951839/f/4/b/9/6/2fcaf7b447e7f49dbf7615a29dc88b6f.png" width="37.27274391867894" height="43.81818181818184" preserveAspectRatio="none" crossOrigin="anonymous" x="0" y="0"></image></pattern><pattern id="SvgjsPattern1025" x="0" y="0" width="37.27274391867894" height="43.81818181818184" patternUnits="userSpaceOnUse"><image id="SvgjsImage1026" xlink:href="https://img7.file.cache.docer.com/storage/image/1637754951839/f/4/b/9/6/2fcaf7b447e7f49dbf7615a29dc88b6f.png" width="37.27274391867894" height="43.81818181818184" preserveAspectRatio="none" crossOrigin="anonymous" x="0" y="0"></image></pattern><pattern id="SvgjsPattern1029" x="0" y="0" width="37.27274391867894" height="43.81818181818184" patternUnits="userSpaceOnUse"><image id="SvgjsImage1030" xlink:href="https://img7.file.cache.docer.com/storage/image/1637754951839/f/4/b/9/6/2fcaf7b447e7f49dbf7615a29dc88b6f.png" width="37.27274391867894" height="43.81818181818184" preserveAspectRatio="none" crossOrigin="anonymous" x="0" y="0"></image></pattern><pattern id="SvgjsPattern1033" x="0" y="0" width="37.27274391867894" height="43.81818181818184" patternUnits="userSpaceOnUse"><image id="SvgjsImage1034" xlink:href="https://img7.file.cache.docer.com/storage/image/1637754951839/f/4/b/9/6/2fcaf7b447e7f49dbf7615a29dc88b6f.png" width="37.27274391867894" height="43.81818181818184" preserveAspectRatio="none" crossOrigin="anonymous" x="0" y="0"></image></pattern><pattern id="SvgjsPattern1037" x="0" y="0" width="37.27274391867894" height="43.81818181818184" patternUnits="userSpaceOnUse"><image id="SvgjsImage1038" xlink:href="https://img7.file.cache.docer.com/storage/image/1637754951839/f/4/b/9/6/2fcaf7b447e7f49dbf7615a29dc88b6f.png" width="37.27274391867894" height="43.81818181818184" preserveAspectRatio="none" crossOrigin="anonymous" x="0" y="0"></image></pattern><pattern id="SvgjsPattern1041" x="0" y="0" width="37.27274391867894" height="43.81818181818184" patternUnits="userSpaceOnUse"><image id="SvgjsImage1042" xlink:href="https://img7.file.cache.docer.com/storage/image/1637754951839/f/4/b/9/6/2fcaf7b447e7f49dbf7615a29dc88b6f.png" width="37.27274391867894" height="43.81818181818184" preserveAspectRatio="none" crossOrigin="anonymous" x="0" y="0"></image></pattern><pattern id="SvgjsPattern1045" x="0" y="0" width="37.27274391867894" height="43.81818181818184" patternUnits="userSpaceOnUse"><image id="SvgjsImage1046" xlink:href="https://img7.file.cache.docer.com/storage/image/1637754951839/f/4/b/9/6/2fcaf7b447e7f49dbf7615a29dc88b6f.png" width="37.27274391867894" height="43.81818181818184" preserveAspectRatio="none" crossOrigin="anonymous" x="0" y="0"></image></pattern><pattern id="SvgjsPattern1049" x="0" y="0" width="37.27274391867894" height="43.81818181818184" patternUnits="userSpaceOnUse"><image id="SvgjsImage1050" xlink:href="https://img7.file.cache.docer.com/storage/image/1637754951839/f/4/b/9/6/2fcaf7b447e7f49dbf7615a29dc88b6f.png" width="37.27274391867894" height="43.81818181818184" preserveAspectRatio="none" crossOrigin="anonymous" x="0" y="0"></image></pattern><marker id="SvgjsMarker1053" markerWidth="12" markerHeight="8" refX="3" refY="4" viewBox="0 0 12 8" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1054" d="M12 0L0 4L12 8L12 0 " fill="#81c784" stroke="#81c784" stroke-width="1"></path></marker><marker id="SvgjsMarker1055" markerWidth="12" markerHeight="8" refX="9" refY="4" viewBox="0 0 12 8" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1056" d="M0 0L12 4L0 8L0 0 " fill="#81c784" stroke="#81c784" stroke-width="1"></path></marker><marker id="SvgjsMarker1059" markerWidth="12" markerHeight="8" refX="3" refY="4" viewBox="0 0 12 8" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1060" d="M12 0L0 4L12 8L12 0 " fill="#81c784" stroke="#81c784" stroke-width="1"></path></marker><marker id="SvgjsMarker1061" markerWidth="12" markerHeight="8" refX="9" refY="4" viewBox="0 0 12 8" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1062" d="M0 0L12 4L0 8L0 0 " fill="#81c784" stroke="#81c784" stroke-width="1"></path></marker><marker id="SvgjsMarker1065" markerWidth="12" markerHeight="8" refX="3" refY="4" viewBox="0 0 12 8" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1066" d="M12 0L0 4L12 8L12 0 " fill="#81c784" stroke="#81c784" stroke-width="1"></path></marker><marker id="SvgjsMarker1067" markerWidth="12" markerHeight="8" refX="9" refY="4" viewBox="0 0 12 8" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1068" d="M0 0L12 4L0 8L0 0 " fill="#81c784" stroke="#81c784" stroke-width="1"></path></marker><marker id="SvgjsMarker1071" markerWidth="12" markerHeight="8" refX="3" refY="4" viewBox="0 0 12 8" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1072" d="M12 0L0 4L12 8L12 0 " fill="#81c784" stroke="#81c784" stroke-width="1"></path></marker><marker id="SvgjsMarker1073" markerWidth="12" markerHeight="8" refX="9" refY="4" viewBox="0 0 12 8" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1074" d="M0 0L12 4L0 8L0 0 " fill="#81c784" stroke="#81c784" stroke-width="1"></path></marker><marker id="SvgjsMarker1077" markerWidth="12" markerHeight="8" refX="3" refY="4" viewBox="0 0 12 8" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1078" d="M12 0L0 4L12 8L12 0 " fill="#81c784" stroke="#81c784" stroke-width="1"></path></marker><marker id="SvgjsMarker1079" markerWidth="12" markerHeight="8" refX="9" refY="4" viewBox="0 0 12 8" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1080" d="M0 0L12 4L0 8L0 0 " fill="#81c784" stroke="#81c784" stroke-width="1"></path></marker><marker id="SvgjsMarker1083" markerWidth="12" markerHeight="8" refX="3" refY="4" viewBox="0 0 12 8" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1084" d="M12 0L0 4L12 8L12 0 " fill="#81c784" stroke="#81c784" stroke-width="1"></path></marker><marker id="SvgjsMarker1085" markerWidth="12" markerHeight="8" refX="9" refY="4" viewBox="0 0 12 8" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1086" d="M0 0L12 4L0 8L0 0 " fill="#81c784" stroke="#81c784" stroke-width="1"></path></marker><marker id="SvgjsMarker1089" markerWidth="12" markerHeight="8" refX="3" refY="4" viewBox="0 0 12 8" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1090" d="M12 0L0 4L12 8L12 0 " fill="#81c784" stroke="#81c784" stroke-width="1"></path></marker><marker id="SvgjsMarker1091" markerWidth="12" markerHeight="8" refX="9" refY="4" viewBox="0 0 12 8" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1092" d="M0 0L12 4L0 8L0 0 " fill="#81c784" stroke="#81c784" stroke-width="1"></path></marker><marker id="SvgjsMarker1095" markerWidth="12" markerHeight="8" refX="3" refY="4" viewBox="0 0 12 8" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1096" d="M12 0L0 4L12 8L12 0 " fill="#81c784" stroke="#81c784" stroke-width="1"></path></marker><marker id="SvgjsMarker1097" markerWidth="12" markerHeight="8" refX="9" refY="4" viewBox="0 0 12 8" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1098" d="M0 0L12 4L0 8L0 0 " fill="#81c784" stroke="#81c784" stroke-width="1"></path></marker><marker id="SvgjsMarker1101" markerWidth="12" markerHeight="8" refX="3" refY="4" viewBox="0 0 12 8" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1102" d="M12 0L0 4L12 8L12 0 " fill="#81c784" stroke="#81c784" stroke-width="1"></path></marker><marker id="SvgjsMarker1103" markerWidth="12" markerHeight="8" refX="9" refY="4" viewBox="0 0 12 8" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1104" d="M0 0L12 4L0 8L0 0 " fill="#81c784" stroke="#81c784" stroke-width="1"></path></marker><marker id="SvgjsMarker1107" markerWidth="12" markerHeight="8" refX="3" refY="4" viewBox="0 0 12 8" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1108" d="M12 0L0 4L12 8L12 0 " fill="#81c784" stroke="#81c784" stroke-width="1"></path></marker><marker id="SvgjsMarker1109" markerWidth="12" markerHeight="8" refX="9" refY="4" viewBox="0 0 12 8" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1110" d="M0 0L12 4L0 8L0 0 " fill="#81c784" stroke="#81c784" stroke-width="1"></path></marker><marker id="SvgjsMarker1113" markerWidth="12" markerHeight="8" refX="3" refY="4" viewBox="0 0 12 8" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1114" d="M12 0L0 4L12 8L12 0 " fill="#81c784" stroke="#81c784" stroke-width="1"></path></marker><marker id="SvgjsMarker1115" markerWidth="12" markerHeight="8" refX="9" refY="4" viewBox="0 0 12 8" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1116" d="M0 0L12 4L0 8L0 0 " fill="#81c784" stroke="#81c784" stroke-width="1"></path></marker><marker id="SvgjsMarker1119" markerWidth="12" markerHeight="8" refX="3" refY="4" viewBox="0 0 12 8" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1120" d="M12 0L0 4L12 8L12 0 " fill="#81c784" stroke="#81c784" stroke-width="1"></path></marker><marker id="SvgjsMarker1121" markerWidth="12" markerHeight="8" refX="9" refY="4" viewBox="0 0 12 8" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1122" d="M0 0L12 4L0 8L0 0 " fill="#81c784" stroke="#81c784" stroke-width="1"></path></marker><marker id="SvgjsMarker1125" markerWidth="12" markerHeight="8" refX="3" refY="4" viewBox="0 0 12 8" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1126" d="M12 0L0 4L12 8L12 0 " fill="#81c784" stroke="#81c784" stroke-width="1"></path></marker><marker id="SvgjsMarker1127" markerWidth="12" markerHeight="8" refX="9" refY="4" viewBox="0 0 12 8" orient="auto" markerUnits="userSpaceOnUse" stroke-dasharray="0,0"><path id="SvgjsPath1128" d="M0 0L12 4L0 8L0 0 " fill="#81c784" stroke="#81c784" stroke-width="1"></path></marker><pattern patternUnits="userSpaceOnUse" id="pattern_mark" width="300" height="300"><text x="-50" y="150" fill="rgba(229,229,229,0.8)" font-size="18" transform="rotate(-45, 150, 150)"></text></pattern></defs><g id="SvgjsG1007" transform="translate(40.51135253906254,25.003402709960966)"><path id="SvgjsPath1008" d="M0 0L37.27274391867894 0L37.27274391867894 43.81818181818184L0 43.81818181818184Z " stroke="none" fill="url(#SvgjsPattern1009)"></path></g><g id="SvgjsG1011" transform="translate(153.23862526633528,153.18522089177904)"><path id="SvgjsPath1012" d="M0 0L37.27274391867894 0L37.27274391867894 43.81818181818184L0 43.81818181818184Z " stroke="none" fill="url(#SvgjsPattern1013)"></path></g><g id="SvgjsG1015" transform="translate(175.05680708451712,31.367039073597304)"><path id="SvgjsPath1016" d="M0 0L37.27274391867894 0L37.27274391867894 43.81818181818184L0 43.81818181818184Z " stroke="none" fill="url(#SvgjsPattern1017)"></path></g><g id="SvgjsG1019" transform="translate(301.4204434481538,176.09431180087014)"><path id="SvgjsPath1020" d="M0 0L37.27274391867894 0L37.27274391867894 43.81818181818184L0 43.81818181818184Z " stroke="none" fill="url(#SvgjsPattern1021)"></path></g><g id="SvgjsG1023" transform="translate(273.23862526633536,94.82158452814268)"><path id="SvgjsPath1024" d="M0 0L37.27274391867894 0L37.27274391867894 43.81818181818184L0 43.81818181818184Z " stroke="none" fill="url(#SvgjsPattern1025)"></path></g><g id="SvgjsG1027" transform="translate(60.51135253906256,132.27612998268825)"><path id="SvgjsPath1028" d="M0 0L37.27274391867894 0L37.27274391867894 43.81818181818184L0 43.81818181818184Z " stroke="none" fill="url(#SvgjsPattern1029)"></path></g><g id="SvgjsG1031" transform="translate(137.7840631658382,248.0943118008699)"><path id="SvgjsPath1032" d="M0 0L37.27274391867894 0L37.27274391867894 43.81818181818184L0 43.81818181818184Z " stroke="none" fill="url(#SvgjsPattern1033)"></path></g><g id="SvgjsG1035" transform="translate(112.32951771129268,80.63976634632462)"><path id="SvgjsPath1036" d="M0 0L37.27274391867894 0L37.27274391867894 43.81818181818184L0 43.81818181818184Z " stroke="none" fill="url(#SvgjsPattern1037)"></path></g><g id="SvgjsG1039" transform="translate(44.147716175426204,235.00340270996088)"><path id="SvgjsPath1040" d="M0 0L37.27274391867894 0L37.27274391867894 43.81818181818184L0 43.81818181818184Z " stroke="none" fill="url(#SvgjsPattern1041)"></path></g><g id="SvgjsG1043" transform="translate(212.32955100319606,204.2761299826881)"><path id="SvgjsPath1044" d="M0 0L37.27274391867894 0L37.27274391867894 43.81818181818184L0 43.81818181818184Z " stroke="none" fill="url(#SvgjsPattern1045)"></path></g><g id="SvgjsG1047" transform="translate(205.05680708451717,94.82158452814265)"><path id="SvgjsPath1048" d="M0 0L37.27274391867894 0L37.27274391867894 43.81818181818184L0 43.81818181818184Z " stroke="none" fill="url(#SvgjsPattern1049)"></path></g><g id="SvgjsG1051"><path id="SvgjsPath1052" d="M80.08365666823622 46.957469593854604C116.77635435686608 46.91249361905188 136.06454918539254 53.27612998268822 172.7572468740224 53.23115400788549 " stroke="#81c784" stroke-width="1" fill="none" marker-start="url(#SvgjsMarker1053)" marker-end="url(#SvgjsMarker1055)"></path></g><g id="SvgjsG1057"><path id="SvgjsPath1058" d="M79.86703550159201 47.8878730014478C103.97964138664264 46.91249361905187 86.13397278239152 102.54885725541554 110.24657866744215 101.57347787301963 " stroke="#81c784" stroke-width="1" fill="none" marker-start="url(#SvgjsMarker1059)" marker-end="url(#SvgjsMarker1061)"></path></g><g id="SvgjsG1063"><path id="SvgjsPath1064" d="M130.43361655812362 126.69551052871009C130.96588967063215 142.27812614173078 115.60427443496582 154.18522089177918 100.04701108844863 153.77386049731757 " stroke="#81c784" stroke-width="1" fill="none" marker-start="url(#SvgjsMarker1065)" marker-end="url(#SvgjsMarker1067)"></path></g><g id="SvgjsG1069"><path id="SvgjsPath1070" d="M171.59307469200616 199.28605898829318C171.87499722567475 240.40132424773083 124.8183816318751 256.9124936190518 83.71835047001645 256.81400595335595 " stroke="#81c784" stroke-width="1" fill="none" marker-start="url(#SvgjsMarker1071)" marker-end="url(#SvgjsMarker1073)"></path></g><g id="SvgjsG1075"><path id="SvgjsPath1076" d="M78.85807169843832 178.37600004764553C79.14772449840203 200.55014819802273 62.78408813476568 210.54756631280824 63.073740934729386 232.72171446318544 " stroke="#81c784" stroke-width="1" fill="none" marker-start="url(#SvgjsMarker1077)" marker-end="url(#SvgjsMarker1079)"></path></g><g id="SvgjsG1081"><path id="SvgjsPath1082" d="M58.88656567928024 71.10670948560026C59.14772449840203 102.96703907359736 25.002269952947465 154.18522089177918 56.92592832114205 153.59055985663983 " stroke="#81c784" stroke-width="1" fill="none" marker-start="url(#SvgjsMarker1083)" marker-end="url(#SvgjsMarker1085)"></path></g><g id="SvgjsG1087"><path id="SvgjsPath1088" d="M193.46965518969878 77.47433362089986C193.6931790438566 107.58283329232799 171.87499722567475 120.7876084912302 172.09852107983255 150.89610816265832 " stroke="#81c784" stroke-width="1" fill="none" marker-start="url(#SvgjsMarker1089)" marker-end="url(#SvgjsMarker1091)"></path></g><g id="SvgjsG1093"><path id="SvgjsPath1094" d="M223.409886678043 140.92225302437362C223.69317904385665 190.0299126314003 156.4204351251777 196.7041655157941 156.70372749099133 245.81182512282078 " stroke="#81c784" stroke-width="1" fill="none" marker-start="url(#SvgjsMarker1095)" marker-end="url(#SvgjsMarker1097)"></path></g><g id="SvgjsG1099"><path id="SvgjsPath1100" d="M214.62885391157818 53.33275272993235C248.22607519843632 53.27612998268822 291.87499722567486 58.925060332902405 291.4832971256254 92.55518407111367 " stroke="#81c784" stroke-width="1" fill="none" marker-start="url(#SvgjsMarker1101)" marker-end="url(#SvgjsMarker1103)"></path></g><g id="SvgjsG1105"><path id="SvgjsPath1106" d="M292.73912862172267 140.77126275269362C291.87499722567486 157.3888798239893 320.0568154074933 157.34519832320535 319.19268401144546 173.96281539450104 " stroke="#81c784" stroke-width="1" fill="none" marker-start="url(#SvgjsMarker1107)" marker-end="url(#SvgjsMarker1109)"></path></g><g id="SvgjsG1111"><path id="SvgjsPath1112" d="M319.34896978480464 222.1008616352779C320.0568154074932 248.2057763958424 277.8955776986654 226.18522089177898 251.8906459352907 226.4164126723408 " stroke="#81c784" stroke-width="1" fill="none" marker-start="url(#SvgjsMarker1113)" marker-end="url(#SvgjsMarker1115)"></path></g><g id="SvgjsG1117"><path id="SvgjsPath1118" d="M177.150534715036 269.05140239000195C198.06738029625149 270.0034027099609 189.31897779146172 226.185220891779 210.2358233726772 227.13722121173797 " stroke="#81c784" stroke-width="1" fill="none" marker-start="url(#SvgjsMarker1119)" marker-end="url(#SvgjsMarker1121)"></path></g><g id="SvgjsG1123"><path id="SvgjsPath1124" d="M83.66551725694252 256.4127753628388C124.9673336438585 256.9124936190518 109.69175171658193 175.09431180086995 150.9935681034979 175.594030057083 " stroke="#81c784" stroke-width="1" fill="none" marker-start="url(#SvgjsMarker1125)" marker-end="url(#SvgjsMarker1127)"></path></g></svg> **P2P网络技术的特点体现在以下几个方面:** **非中心化**:网络中的资源和服务分散在所有节点上,信息的传输和服务的实现都直接在节点之间进行,可以无需中间环节和服务器的介入,避免了可能的瓶颈。P2P的非中心化基本特点,带来了其在可扩展性、健壮性等方面的优势。 **可扩展性**:在P2P网络中,随着用户的加入,不仅服务的需求增加了,系统整体的资源和服务能力也在同步地扩充,始终能比较容易地满足用户的需要。理论上其可扩展性几乎可以认为是无限的。P2P网络加入的用户越多,P2P网络中提供的资源就越多,下载的速度反而越快。 **健壮性**:P2P架构天生具有耐攻击、高容错的优点。由于服务是分散在各个节点之间进行的,部分节点或网络遭到破坏对其它部分的影响很小。P2P网络一般在部分节点失效时能够自动调整整体拓扑,保持其它节点的连通性。P2P网络通常都是以自组织的方式建立起来的,并允许节点自由地加入和离开。 **高性价比**:性能优势是P2P被广泛关注的一个重要原因。随着硬件技术的发展,个人计算机的计算和存储能力以及网络带宽等性能依照摩尔定理高速增长。采用P2P架构可以有效地利用互联网中散布的大量普通结点,将计算任务或存储资料分布到所有节点上。利用其中闲置的计算能力或存储空间,达到高性能计算和海量存储的目的。目前,P2P在这方面的应用多在学术研究方面,一旦技术成熟,能够在工业领域推广,则可以为许多企业节省购买大型服务器的成本。 **隐私保护**:在P2P网络中,由于信息的传输分散在各节点之间进行而无需经过某个集中环节,用户的隐私信息被窃听和泄漏的可能性大大缩小。此外,目前解决Internet隐私问题主要采用中继转发的技术方法,从而将通信的参与者隐藏在众多的网络实体之中。在P2P中,所有参与者都可以提供中继转发的功能,因而大大提高了匿名通讯的灵活性和可靠性,能够为用户提供更好的隐私保护。 **应用场景**: - 大流量传输,不经过服务器,直接点对点传输,速度取决本地网络宽带速度 - 远程局域网,提升网络环境 - 局域网文件共享 - 流媒体直播 **所以要实现P2P的网络组建成功,本地环境下的 NAT 是有关键性的因素,下文主要讲解对于不同 NAT 下穿透的条件和成功率进行研究。** #### 4.1 穿透条件 - 中间服务器保存信息、并能发出建立UDP隧道的命令 - 网关均要求为Cone NAT类型。Symmetric NAT不适合。 - 完全圆锥型网关可以无需建立udp隧道,但这种情况非常少,要求双方均为这种类型网关的更少。 - 假如X1网关为Symmetric NAT, Y1为Address Restricted Cone NAT 或Full Cone NAT型网关,各自建立隧道后,A1可通过X1发送数据报给Y1到B1(因为Y1最多只进行IP级别的甄别),但B2发送给X1的将会被丢弃(因为发送来的数据报中端口与X1上存在会话的端口不一致,虽然IP地址一致),所以同样没有什么意义。 - 假如双方均为Symmetric NAT的情形,新开了端口,对方可以在不知道的情况下尝试猜解,也可以达到目的,但这种情形成功率很低,且带来额外的系统开支,不是个好的解决办法。pwnat工具据说可以实现。 - 不同网关型设置的差异在于,对内会采用替换IP的方式、使用不同端口不同会话的方式,使用相同端口不同会话的方式;对外会采用什么都不限制、限制IP地址、限制IP地址及端口。 - 这里还没有考虑同一内网不同用户同时访问同一服务器的情形,如果此时网关采用AddressRestricted Cone NAT 或Full Cone NAT型,有可能导致不同用户客户端可收到别人的数据包,这显然是不合适的。 #### 4.2 穿透流程 不同的网络拓扑 NAT 穿透的方法和流程有所区别,具体如下。 ##### (1)同一个NAT设备下 <img src="https://img-1259793745.itggg.cn/20211213223437.png" alt="同一个NAT设备下" style="zoom:50%;" style=""> - clinet A与Server S建立UDP连接,公共NAT(155.99.25.11)给client A分配一个公网端口62000; - client B与Server S建立UDP连接,公共NAT(155.99.25.11)给client A分配一个公网端口62005; - client A通过Server S发送一个消息要求连接client B,S给A回应B的公网和私网地址,并转发A的公网和私网地址给B; - A和B根据获取的地址试图直接发送UDP数据报文;是否成功取决于NAT设备是否支持hairpin translation(端口回流)。——打开端口回流相当于与client A的数据经过NAT设备转发后才到达client B,即从外网NAT接口绕了一圈再访问到同一个子网里的client B。(优点是可以防止内部攻击) ##### (2)不同NAT设备下 <img src="https://img-1259793745.itggg.cn/20211213223439.png" alt="不同NAT设备下" style="zoom:50%;" style=""> - A使用4321端口与S连接,NAT给回话在NAT分配外网62000端口(155.99.25.11:62000)与S连接;同理B以相同的方式与S连接,分配的外网地址端口是138.76.29.7:31000。 - A往S注册消息包里包含里A的私有地址10.0.0.1:4321,此时S保存了A的地址;S给A临时分配了一个用于公网的地址(155.99.25.11:62000),同时用于观察外网数据包。 - 同理B往S注册的消息包里也包含里B的地址,NAT同样给B临时分类了一个外网地址(138.76.29.7:31000) - Client A根据以上已知信息通过穿透的方式与B连接UDP通信: - Client A发送请求消息,寻求连接B; - S给A回应B的外网和内网地址,通给给B发送A的外网和内网地址; - A和B开始利用这些地址尝试直接发送UDP报文给彼此,不幸的是,此时A和B都无法接收对应的消息。因为A和B都是在不同的私有网络中,A和B之前都是与S通信回话,并没有与对方建立回话;即A没有为B打开一个洞,B也没有为A打开一个洞。这个过程的第一个报文需要会被拒绝同时打开对应的“洞”,随后才可以直接通信,具体如下: **1**. A给B公网地址(10.0.0.1:4321 to 138.76.29.7:31000)发送的第一个报文,实际上是在A的NAT私有网络上“穿透”来为新识别的地址(10.0.0.1:4321 138.76.29.7:31000) 建立UDP会话,并经主网地址(155.99.25.11:62000 138.76.29.7:31000)来传送。 **2**. 如果A发送到B的公网地址的消息在B发送到A的第一个消息越过B自己的NAT之前到达B的NAT,那么B的NAT可能会将A的入站消息解释为非请求的传入通信量并丢弃它。 **3**. 同理,B给A公网地址方法的第一个消息也会在B的NAT上“穿透”来为地址(10.1.1.3:4321, 155.99.25.11:62000)建立回话。 **4**. 随后可以正常P2P通信。 ##### (3)多层NAT下 <img src="https://img-1259793745.itggg.cn/20211213223440.png" alt="多层NAT下" style="zoom:50%;" style=""> **说明**:NAT C 是一个大型的工业NAT设备,由ISP(Internet Service Provider,互联网服务提供商)部署,用于将许多客户多路复用到几个公共IP地址上。 - Client A和client B无法通道NAT A和NAT A进行P2P通信,因为它们属于NAT C的局域网地址,因此client A和client B只能通道NAT C的hairpin translation进行P2P通信,如果NAT C不支持hairpin translation,则它们很难进行P2P通信。 - 每个客户机像前面方式一样启动到服务器S的连接,引起NAT A和B各自创建一个单独的公共/私有转化——session A-S(18.181.0.31:1234 10.0.0.1:4321)和session B-S(18.181.0.31:1234 10.1.1.3:4321),并引起NAT C为每个会话建立一个公共/私有翻译——session A-S(18.181.0.31:1234 10.0.1.1:45000)和session B-S(18.181.0.31:1234 10.0.1.2:5500)。 **1.** 首先client A给client B的公网地址(155.99.25.11:62005)发送消息; **2.** NAT A翻译原数据报文从10.0.0.1:4321带10.0.0.1:45000; **3.** 数据报现在到达NAT C,它识别出数据报的目标地址是NAT C自己翻译的公共地址之一; **4.** 如果NAT C是好的,那么其能翻译出数据报文的源地址和目标地址(155.99.25.11:62000和10.0.1.2:55000)同时通过“回环”返回数据包到私有网络; **5.** NAT B 翻译数据报文得到NAT B私网地址,最终到达client B。 **6.** Client B给client A发送数据报文与上述步骤类似。 #### 4.3 NAT穿透成功率 不同的NAT组合穿透的方式也有所不同,有点可以穿透,有的则不能穿透,如两个都是对称型设备则无法实现穿透,不同组合穿透测试结果如下。 | Peer A | Peer B | 是否可以穿透 | | ------------ | ------------ | ------------ | | 全锥型 | 全锥型 | 是 | | 全锥型 | 受限锥型 | 是 | | 全锥型 | 端口受限锥型 | 是 | | 全锥型 | 对称型 | 是 | | 受限锥型 | 受限锥型 | 是 | | 受限锥型 | 端口受限锥型 | 是 | | 受限锥型 | 对称型 | 是 | | 端口受限锥型 | 端口受限锥型 | 是 | | 端口受限锥型 | 对称型 | 否 | | 对称型 | 对称型 | 否 | ## 5、ZeroTier-One Zerotier 可以组建虚拟局域网,官方声称是P2P直连的。想要实现P2P访问必须先通过一个中介进行连接,官方的节点在网络高峰期不是很好使,并且根节点都在国外,所以最好自己找台国内服务器搭建moon节点,保证p2p的稳定性。Zerotier 怎么使用这里就不讲了,请自行百度,教学很多,这里只讲下moon节点的搭建和使用。 #### 5.1 安装配置ZeroTier客户端 执行命令: curl -s [https://install.zerotier.com/](https://link.zhihu.com/?target=https%3A//install.zerotier.com/) | sudo bash **启动安装好的ZeroTier** 执行命令:sudo systemctl start zerotier-one.service 执行命令:sudo systemctl enable zerotier-one.service **将安装好ZeroTier的加入你事先注册好的ZeroTier虚拟局域网中** 执行命令:sudo zerotier-cli join NETWORK ID 此处的 **NETWORK ID** 请更改为你己的 ID **以上两个步骤如果成功会反馈如图**  **然后去zerotier管理页面,对加入的设备进行打钩,这样你的服务器就已经加入你的网络中了** <img src="https://img-1259793745.itggg.cn/20211213223442.png" alt="image-20211213215352065" style="zoom:50%;" style=""> #### 5.2 搭建ZeroTier的Moon中转服务器,生成moon配置文件 执行命令:cd /var/lib/zerotier-one/ 执行命令:sudo zerotier-idtool initmoon identity.public > moon.json **然后修改配置文件 moon.json** 添加IP,IP是服务器的IP,9993 是 zerotier 的默认端口,服务器防火墙上需要开放 UDP:9993 ,否则是连接不上Moon <img src="https://img-1259793745.itggg.cn/20211213223443.png" alt="image-20211213215803307" style="zoom:50%;" style=""> **生成签名文件** 执行命令:zerotier-idtool genmoon moon.json 执行之后会生产一个*000000xxxx.moon*的文件,将这个文件下载本地,*xxxx*是随机的,这个后面要用 **将moon节点加入网络。创建moons.d文件夹,并把签名文件移动到文件夹内** 执行命令:sudo mkdir moons.d 执行命令:sudo mv 000000448c38987b.moon moons.d/ 此处的 000000448c38987b.moon 是上一步生成的文件名,改成你自己生成的文件名的,这里只是演示,不要无脑复制粘贴。 **然后重启中转服务器的 zerotier-one** 执行命令:sudo systemctl restart zerotier-one **到这里,服务器的moon就配置完成了。** 对客户端安装zerotier后,将配置好的moon文件配置到客户端,并重启zerotier完成与moon的连接。 #### 5.3 配置客户端 **LINUX 下** 使用之前步骤中 moon.json 文件中的 id 值 (10 位的字符串,就是xxxxxx),不知道的话在服务器上执行如下命令可以得到id。 执行命令:grep id /var/lib/zerotier-one/moon.json | head -n 1 然后在客户端机器里执行命令: 执行命令:zerotier-cli orbit ed2c88f24 ed2c88f24 此处的ed2c88f24刚刚在服务器得到的ID值 **Windows下** 打开服务程序 services.msc , 找到服务 "ZeroTier One" , 并且在属性内找到该服务可执行文件路径,并且在其下建立 moons.d 文件夹,然后将 moon 服务器下生成的 000xxxx.moon 文件,拷贝到此文件夹内.再重启服务 <img src="https://img-1259793745.itggg.cn/20211213223444.png" alt="image-20211213221314442" style="zoom:33%;" style=""> **路径一般是 Windows: C:\ProgramData\ZeroTier\One** 测试是否成功(客户端cmd管理员运行)若有出现服务器IP地址,即可证明moon连接成功 执行命令:zerotier-cli listpeers (下图就是链接成功到moon的样子,截图内创建了两个moon ) <img src="https://img-1259793745.itggg.cn/20211213223445.png" alt="image-20211213220847333" style="zoom:33%;" style=""> ## 6、总结 连上节点的新设备去管理页面打勾就行了,我自己是建立了2个moon节点,一个在贵州,一个在南京,现在里面有差不多几十台设备,地域分布的很广,跨通4个省份,2个月的期间,也做了很久的穿透测试和观察,p2p的直连成功率大概是80%左右,ping 值一半小于30MS 就是穿透成功了的,大于就基本走的服务器中转了。 中转速度就看服务器的公网带宽了,设备在同一 NAT 下的穿透成功几乎100% ,跨域NAT的情况下,可以先用测试工具看看上面的 NAT 类型,可以估计是否能成功。ZeroTier 的功能还有很多,不止于用来组网,管理端还支持自定义路由,和网关,更多用法待测试后再补充,没测试过这里就不先瞎 BB了,误导人~ # STUN协议 (延伸阅读) STUN是一种网络协议,它允许位于NAT(或多重NAT)后的客户端找出自己的公网地址,查出自己位于哪种类型的NAT之后以及NAT为某一个本地端口所绑定的Internet端端口。这些信息被用来在两个同时处于NAT路由器之后的主机之间建立UDP通信。该协议由RFC 5389定义。STUN由三部分组成:STUN客户端、STUN服务器端、NAT路由器。STUN服务端部署在一台有着两个公网IP的服务器上。STUN客户端通过向服务器端发送不同的消息类型,根据服务器端不同的响应来做出相应的判断,一旦客户端得知了Internet端的UDP端口,通信就可以开始了。 <img src="https://img-1259793745.itggg.cn/20211213223447.png" style="zoom:33%;" /> **STUN协议定义了三类测试过程来检测NAT类型。** - **Test1**:STUN Client通过端口{IP-C1:Port-C1}向STUN Server{IP-S1:Port-S1}发送一个Binding Request(没有设置任何属性)。STUN Server收到该请求后,通过端口{IP-S1:Port-S1}把它所看到的STUN Client的IP和端口{IP-M1,Port-M1}作为Binding Response的内容回送给STUN Client。 Test1#2:STUN Client通过端口{IP-C1:Port-C1}向STUN Server{IP-S2:Port-S2}发送一个Binding Request(没有设置任何属性)。STUN Server收到该请求后,通过端口{IP-S2:Port-S2}把它所看到的STUN Client的IP和端口{IP-M1#2,Port-M1#2}作为Binding Response的内容回送给STUN Client。 - **Test2**:STUN Client通过端口{IP-C1:Port-C1}向STUN Server{IP-S1:Port-S1}发送一个Binding Request(设置了Change IP和Change Port属性)。STUN Server收到该请求后,通过端口{IP-S2:Port-S2}把它所看到的STUN Client的IP和端口{IP-M2,Port-M2}作为Binding Response的内容回送给STUN Client。 - **Test3**:STUN Client通过端口{IP-C1:Port-C1}向STUN Server{IP-S1:Port-S1}发送一个Binding Request(设置了Change Port属性)。STUN Server收到该请求后,通过端口{IP-S1:Port-S2}把它所看到的STUN Client的IP和端口{IP-M3,Port-M3}作为Binding Response的内容回送给STUN Client。 **STUN协议的输出是: 1)公网IP和Port 2)防火墙是否设置 3)客户端是否在NAT之后,及所处的NAT的类型** 因此我们进而整理出,通过STUN协议,我们可以检测的类型一共有以下七种: **A**:公开的互联网IP。主机拥有公网IP,并且没有防火墙,可自由与外部通信 **B**:完全锥形NAT。 **C**:受限制锥形NAT。 **D**:端口受限制形NAT。 **E**:对称型UDP防火墙。主机出口处没有NAT设备,但有防火墙,且防火墙规则如下:从主机UDP端口A发出的数据包保持源地址,但只有从之前该主机发出包的目的IP/PORT发出到该主机端口A的包才能通过防火墙。 **F**:对称型NAT **G**:防火墙限制UDP通信。 **STEP1**:检测客户端是否有能力进行UDP通信以及客户端是否位于NAT后 -- Test1 客户端建立UDP socket,然后用这个socket向服务器的(IP-1,Port-1)发送数据包要求服务器返回客户端的IP和Port,客户端发送请求后立即开始接受数据包。重复几次。 a)如果每次都超时收不到服务器的响应,则说明客户端无法进行UDP通信,可能是:G防火墙阻止UDP通信 b)如果能收到回应,则把服务器返回的客户端的(IP:PORT)同(Local IP: Local Port)比较: 如果完全相同则客户端不在NAT后,这样的客户端是:A具有公网IP可以直接监听UDP端口接收数据进行通信或者E。 否则客户端在NAT后要做进一步的NAT类型检测(继续) **STEP2**:检测客户端防火墙类型 -- Test2 STUN客户端向STUN服务器发送请求,要求服务器从其他IP和PORT向客户端回复包: a)收不到服务器从其他IP地址的回复,认为包前被前置防火墙阻断,网络类型为E b)收到则认为客户端处在一个开放的网络上,网络类型为A **STEP3**:检测客户端NAT是否是FULL CONE NAT -- Test2 客户端建立UDP socket然后用这个socket向服务器的(IP-1,Port-1)发送数据包要求服务器用另一对(IP-2,Port-2)响应客户端的请求往回发一个数据包,客户端发送请求后立即开始接受数据包。 重复这个过程若干次。 a)如果每次都超时,无法接受到服务器的回应,则说明客户端的NAT不是一个Full Cone NAT,具体类型有待下一步检测(继续)。 b)如果能够接受到服务器从(IP-2,Port-2)返回的应答UDP包,则说明客户端是一个Full Cone NAT,这样的客户端能够进行UDP-P2P通信。 **STEP4**:检测客户端NAT是否是SYMMETRIC NAT -- Test1#2 客户端建立UDP socket然后用这个socket向服务器的(IP-1,Port-1)发送数据包要求服务器返回客户端的IP和Port, 客户端发送请求后立即开始接受数据包。 重复这个过程直到收到回应(一定能够收到,因为第一步保证了这个客户端可以进行UDP通信)。 用同样的方法用一个socket向服务器的(IP-2,Port-2)发送数据包要求服务器返回客户端的IP和Port。 比较上面两个过程从服务器返回的客户端(IP,Port),如果两个过程返回的(IP,Port)有一对不同则说明客户端为Symmetric NAT,这样的客户端无法进行UDP-P2P通信(检测停止)因为对称型NAT,每次连接端口都不一样,所以无法知道对称NAT的客户端,下一次会用什么端口。否则是Restricted Cone NAT,是否为Port Restricted Cone NAT有待检测(继续) **STEP5**:检测客户端NAT是Restricted Cone 还是 Port Restricted Cone -- Test3 客户端建立UDP socket然后用这个socket向服务器的(IP-1,Port-1)发送数据包要求服务器用IP-1和一个不同于Port-1的端口发送一个UDP 数据包响应客户端, 客户端发送请求后立即开始接受数据包。重复这个过程若干次。如果每次都超时,无法接受到服务器的回应,则说明客户端是一个Port Restricted Cone NAT,如果能够收到服务器的响应则说明客户端是一个Restricted Cone NAT。以上两种NAT都可以进行UDP-P2P通信。 通过以上过程,至此,就可以分析和判断出客户端是否处于NAT之后,以及NAT的类型及其公网IP,以及判断客户端是否具备P2P通信的能力了。 Last modification:June 6, 2022 © Allow specification reprint Support Appreciate the author AliPayWeChat Like 0 如果你想请我喝奶茶的话
One comment
太深奥了 老哥,文章看不懂,非常好奇你文章里面的拓扑图是怎么画的?既不是图片也不是html 强的一批!!