【网络】P2P打洞原理(简单描述)

本文首发于 ❄️慕雪的寒舍

引入

如果你折腾过NAS或者BT下载等等玩意,可能听说过“P2P打洞”这一技术名词。简单来说,P2P打洞可以让我们直接在外网访问内网的设备,从而让没有公网IP的家庭设备也能获得“公网直连”的速度。

比如绿联、极空间等国产NAS的客户端,在外网访问的时候,都会先尝试P2P打洞让你和你的NAS实现P2P直连,打洞失败的时候才会采用服务器转发的方式;

P2P打洞后:你的当前设备和家里的NAS直接通信
采用服务器转发:报文从家里NAS - 服务器 - 你的当前设备

因为服务器转发的速度直接依赖于服务器的出口带宽,所以使用服务器转发的用户越多,速度也就越慢,有的时候你会发现服务器转发的速度甚至不如没开会员的某度云盘。

前置技术了解

在学习P2P打洞之前,你需要了解以下知识点。注意,本文只是对P2P打洞的简单理解和说明,深入了解底层原理请自行百度其他更详细的文章!

什么是P2P?

P2P即 Peer to Peer,是一种对等连接方式,纯P2P架构包含如下内容

  • 没有总是在线的服务器
  • 任意端之间直接通信
  • 对等方之间可以间断链接,并可以动态改变IP地址

P2P技术的实际的用例如下:

  • 文件分发(BT下载)
  • 流媒体
  • VolP
  • 内网穿透式访问(建立P2P链接,直接和内网主机通信)即本文即将要讲述的P2P打洞。

NAT类型

参考本站 IP层和数据链路层 博客中4.3节对NAT技术的解析。

NAT2:地址限制锥形NAT

所谓地址限制锥形NAT,即NAT映射之后的外网端口和IP地址对请求具有一定的限制,这个限制体现为它只允许已建立链接的主机与之进行通信。

  • 局域网主机C需要和公网服务器S1进行通信
  • 局域网主机C发送请求报文,通过运营商路由器转发,抵达S1服务器
  • 这个过程中每一层的路由器都建立了一个NAT转发表
  • 如果是限制锥形NAT,运营商的路由器将会限制该NAT地址的外网访问IP地址:
    • 只有S1服务器发来的报文能被正常往内网转发(端口不限制),发送给给局域网主机C;
    • 其他公网服务器(和S1不同IP地址)如果企图向该NAT地址发送报文,会被运营商路由器拒绝;

举个具体的的例子,在地址限制锥形NAT下

  • C请求1.1.1.1:8080,会建立一个NAT映射,假设是 2.2.2.2:9000
  • 只有1.1.1.1这个IP能发送报文给NAT地址,对来源端口不限制;
  • 其他来源IP都会被NAT地址拒绝

NAT3:端口限制锥形NAT

在限制锥形NAT的基础上,添加了端口的限制,即只有局域网设备C请求过的S1的端口才能发送信息给局域网主机。

端口限制锥形NAT下
C请求 1.1.1.1:8080
只有 1.1.1.1:8080 能发送报文给NAT地址
其他来源IP或者1.1.1.1上不同的端口发来的报文都会被拒绝

NAT1:完全锥形NAT

完全锥形NAT的映射过程同上,但是不会对外网访问做任何限制。

即NAT地址建立后,任何外网主机都可以发送信息给这个NAT地址

NAT4:对称式NAT(动态NAT)

对称式NAT把内网IP和端口到相同目的地址和端口的所有请求,都映射到同一个公网地址和端口;同一个内网主机,用相同的内网IP和端口向另外一个目的地址发送报文,则会用不同的映射(比如映射到不同的端口)。

和端口限制式NAT不同的是,端口限制式NAT是所有请求映射到相同的公网IP地址和端口,而对称式NAT是为不同的请求建立不同的映射。它具有端口受限锥型的受限特性,内部地址每一次请求一个特定的外部地址,都可能会绑定到一个新的端口号。也就是请求不同的外部地址映射的端口号是可能不同的,甚至请求同一个主机的不同端口也会映射到不同的NAT地址上。

说白了就是,客户端请求目标的端口不同就会更换映射;甚至端口相同的时候都有可能更换映射。

NAT类型IP端口映射示意图

根据NAT类型,可能产生如下映射表,表中<->符号左侧表示内网主机IP和端口,<->符号右侧表示NAT的外网IP和端口,@符号右表示限制条件:外网主机地址IP和端口。

image.png

如何验证NAT类型

通过这个表,也能反推出我们应该如何验证一个NAT的类型

  • 局域网客户端C向服务器S1发起请求,服务器S1能得到一个C的NAT地址和端口
  • 服务器S1让C向自己的另外几个端口发起请求,如果这些请求的来源IP和端口都一致,则代表C是锥形NAT,如果出现了不同的端口,则代表是对称NAT
  • 服务器S1将这个地址和端口交给服务器S2,S2向C发送一个报文
  • 如果C收到了这个S2发来的报文,代表是完全锥形NAT,不对外网来源做限制
  • 如果C没有收到,说明是限制锥形NAT;
  • 服务器S1换一个端口向C的NAT地址和端口发起请求;
  • 如果C收到了,则代表是地址限制锥形NAT,对端口不做限制;
  • 如果C没有收到,则代表是端口限制锥形NAT,对地址和端口都做了限制;
  • 服务器S1尝试让客户端C用相同的本地端口,给S1的另外一个端口发送请求,如果两次请求的来源端口出现了变化,说明是对称式NAT

这里客户端和服务器都是我们单独实现的程序,所以可以通过自定义特定的字段来让客户端、服务器做不同的操作。验证客户端的NAT类型至少需要两个不同IP的公网服务器。

博客:NAT打洞_nat1打洞-CSDN博客 中有一个不错的流程图,在此引用一下

image.png

现在假设 192.168.0.100 通过 8000 端口 访问 114.135.246.90 的 9001 端口

经过NAT之后,会形成这样一种结果:

  • 内网的 192.168.0.100:8000 ↔ 120.230.117.10:9999 NAT公网IP,形成绑定关系
  • 服务端 114.135.246.90:9001 被 120.230.117.10:9999 NAT公网IP,访问

然后如果客户端 192.168.0.100 的8000端口:

  • 8000 端口 能收到 紫色 发来的消息,就是 NAT1
  • 8000 端口 收不到 紫色 发来的消息,却能收到 浅蓝色 线发来的消息,就是 NAT2
  • 8000 端口 收不到 紫色 和 浅蓝色 线发来的消息,只能收到 绿色 线返回来的消息,就是 NAT3 | NAT4

NAT3 和 NAT4 的区别:

  • NAT3 是 8000 端口与 9999 端口形成绑定关系,不管通过 8000 端口访问谁,·都是从 9999 端口出去
  • NAT4 是 8000 端口与 9999 端口形成的绑定关系是有条件的,8000 端口访问同一 ip:port 时,都会从 9999 端口出去;但通过 8000 端口访问其他 ip:port 时,就会绑定 NAT 其他端口,比如 9990(目标端口变化NAT就会变化)

有流程图片,看起来会更清楚一点。

P2P打洞过程

如果想实现P2P打洞,那么当前局域网内设备必须是在锥形NAT下,才能实现直接通信。因为在对称NAT下,NAT的端口地址会经常变化,很难实现稳定的连接。

对于锥形NAT,比较好打洞的自然是完全锥形NAT了,因为它对外网的来源IP和端口都不做限制,那么就可以用下面的流程来实现打洞

  • 需要中间服务器S
  • 客户端C1和C2都是完全锥形NAT
  • 客户端C1请求和C2实现P2P连接
  • 客户端C1向中间服务器S发起请求,NAT会为C1维护一个端口和地址
  • 服务器S收到C1的请求,并对内网客户端C2下发一个通知,让C2也来请求S
  • C2也向服务器发起一个请求,NAT为C2也维护了一个地址
  • 此时服务器S就同时知道C1和C2通过NAT出来的一个公网端口和IP地址
  • 服务器S将C1/C2的IP:端口互相告知对方
  • C1和C2都得到了对方的IP和端口,因为是完全锥形NAT,双方可以直接通信
  • 打洞完成

这个过程中,中间服务器S是不可或缺的,如果没有这个中间服务器,C1和C2就很难知道对方的NAT公网IP和端口,也就没有办法直接实现通信。

个人理解,只要C1和C2有一方是完全锥形NAT,那么P2P打洞就是比较容易实现的,假设C1是完全锥形NAT,C2是有限制的NAT:

  • 服务器S知道了C1的NAT的公网IP地址和端口后,将其告知C2;
  • C2重新对C1的完全锥形NAT发送请求,限制锥形NAT会对C2的新请求更新自己的限制表中的白名单,将C1的IP地址和端口也加入到了这个白名单中
  • 此时限制锥形NAT的限制就消失了,C1和C2依旧可以点对点发起通信。

上述过程还是比较好弄明白的。

NAT穿透性表格

下表展示了不同NAT组合的穿透性。

image.png

但是我没想明白两边都是端口限制型NAT如何打洞?百度也没找到好的说明。

  • 关于端口受限型 NAT 打洞可行性的思考 - 糯米PHP
  • 双方都是端口限制NAT能实现P2P打洞吗?

搞清楚这个问题后我会回来补充本文。

打洞失败

如果打洞失败,C1和C2就得借助中间服务器S的转发来实现通信,此时通信的速度就会出现限制。同时,中间服务器S的带宽/流量资费也比较感人。

这也是为什么绿联和极空间虽然提供了中间服务器转发的方式,但依旧会想办法让你和你的NAS能实现P2P直接通信。除了能提高连接速度,更多的是节省它们服务器的带宽和资费。

The end

P2P打洞的大概原理就是如此,更深层次的就不再研究了~你看明白了吗?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/530299.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

创建个人百度百科需要什么条件?

互联网时代&#xff0c;创建百度百科词条可以给个人带来更多的曝光和展现&#xff0c;相当于一个镀金的网络名片&#xff0c;人人都想上百度百科&#xff0c;但并不是人人都能创建上去的。 个人百度百科词条的创建需要满足一定的条件&#xff0c;今天伯乐网络传媒就来给大家聊聊…

神经网络解决回归问题(更新ing)

神经网络应用于回归问题 神经网络是处理回归问题的强大工具&#xff0c;它们能够学习输入数据和输出之间的复杂关系。 神经网络提供了一种灵活且强大的框架&#xff0c;用于建模和预测回归问题。通过 适当的 网络结构、训练策略和正则化技术&#xff0c;可以有效地从数据中学…

在Linux系统上实现TCP(socket)通信

一.什么TCP TCP&#xff08;传输控制协议&#xff09;是一种面向连接的、可靠的、基于字节流的传输层通信协议。 二.TCP通信流程 三. TCP 服务器端 1 创建socket int sockfd socket(AF_INET, SOCK_STREAM, 0); //SOCK_STREAM tcp通信2 绑定(bind) struct sockaddr_in myad…

系统架构最佳实践 -- 智慧图书管理系统架构设计

随着数字化时代的到来&#xff0c;智慧图书管理系统在图书馆和机构中扮演着重要的角色。一个优秀的图书管理系统不仅需要满足基本的借阅管理需求&#xff0c;还需要具备高效的性能、良好的扩展性和稳定的安全性。本文将讨论智慧图书管理系统的架构设计与实现&#xff0c;以满足…

计算机视觉异常检测——PatchCore面向全召回率的工业异常检测

1. 概述 异常检测问题在工业图像数据分析中扮演着至关重要的角色&#xff0c;其目的是从大量正常数据中识别出异常行为或模式。这一任务的挑战在于&#xff0c;正常数据的样本相对容易获取&#xff0c;而异常情况却因其稀有性和多样性而难以收集。为了解决这一问题&#xff0c…

裸机开发之汇编、寄存器

一、什么是汇编&#xff1f;为什么学汇编&#xff1f; 在之前写控制代码的时候就在想&#xff1a;底层是怎么控制的&#xff1f;后来经过学习知道之前所编写的代码都是应用层代码&#xff0c;顾名思义就是在系统写好的底层之上调用系统函数。原以为底层是指写系统写好的底层函数…

苹果电脑(Mac)怎么清理 itunes 备份?

苹果电脑用户广泛利用 iTunes 应用程序对 iPhone 或 iPad进行定期备份&#xff0c;以确保珍贵的数据安全无虞。然而&#xff0c;随着备份历史的增长&#xff0c;它们会在磁盘上积累大量空间&#xff0c;尤其当您频繁为多台设备备份时&#xff0c;存储资源可能会迅速消耗殆尽。为…

3D Web轻量化引擎HOOPS Commuicator如何从整体装配中创建破碎的装配零件和XML?

前言 虽然可以从某些本机CAD格式&#xff08;其子组件驻留在单独的文件中&#xff0c;例如CATIA V5、Creo - Pro/E、NX或SolidWorks&#xff09;创建破碎装配&#xff0c;但无法从整体装配文件&#xff08;例如IFC、Revit&#xff09;创建或3DXML。 本文介绍了一个示例&#…

学习Rust的第一天:基础知识

Introduction 介绍 I am Shafin Murani is a software development student and I am documenting every single day of my progress in learning rust. This is the first article of the series. Shafin Muranishi 是一名软件开发专业的学生&#xff0c;这是他在30天内记录学…

无影云电脑不能连接到本机的调试串口的解决方案

目录 概述 解决方案 云端电脑中的操作 本地USBDK驱动程序的更新 概述 我从1月份开始使用阿里的无影云电脑进行嵌入式开发板的测试&#xff0c;主要的原因有两个&#xff1a;一是平时使用的笔记本资源过于紧张&#xff0c;二是方便移动办公&#xff0c;这样我只要平时拿着开…

UDP简单总结

UDP&#xff1a;用户数据报协议 特点: 无连接、不可靠通信 不事先建立连接&#xff0c;数据按照包发&#xff0c;一包数据包含&#xff1a;自己的IP、程序端口、目的地IP、程序端口和数据(限制在64KB内) 发送方不管对方是否在线&#xff0c;数据在中间丢失也不管&#xff0c;…

备考分享丨云计算HCIE实验考试需要注意什么

去年九月底我在朋友的推荐下报考了誉天的云计算方向&#xff0c;在此期间我非常感谢田sir、苗苗老师和凡凡老师&#xff0c;每次我遇见问题找他们都能给我完完全全的解决&#xff0c;给我这个非科班出身的学员很大的鼓励与帮助。 我是经济学专业&#xff0c;毕业之后没有考研&…

java数据结构与算法刷题-----LeetCode785. 判断二分图

java数据结构与算法刷题目录&#xff08;剑指Offer、LeetCode、ACM&#xff09;-----主目录-----持续更新(进不去说明我没写完)&#xff1a;https://blog.csdn.net/grd_java/article/details/123063846 文章目录 深度优先广度优先 二分图&#xff1a;将所有结点分成两个集合&am…

​如何使用 ArcGIS Pro 制作带贴图建筑

对于用GIS软件制作三维建筑&#xff0c;很多时候都是制作的建筑体块&#xff0c;这里为大家介绍一下怎么使用 ArcGIS Pro 制作带贴图的建筑&#xff0c;希望能对你有所帮助。 数据来源 教程所使用的数据是从水经微图中下载的建筑数据&#xff0c;除了建筑数据&#xff0c;常见…

Simple_SSTI_2

Simple_SSTI_2 破解思路 1、启动场景2、用kali的tplmap扫一下 1、启动场景 http://114.67.175.224:18040/ 然后机会发现 页面啥也不是&#xff0c;查看源码后&#xff0c;看了好像又没看 2、用kali的tplmap扫一下 安装tplmap【已安装,可略过】&#xff1a;在kali终端安装git…

GitHub 仓库 (repository) Branch - SSH clone URL - Clone in Desktop - Download ZIP

GitHub 仓库 [repository] Branch - SSH clone URL - Clone in Desktop - Download ZIP 1. Branch2. SSH clone URL3. Clone in Desktop4. Download ZIPReferences 1. Branch 显示当前分支的名称。从这里可以切换仓库内分支&#xff0c;查看其他分支的文件。 2. SSH clo…

A Learning-Based Approach for IP Geolocation

下载地址:Towards IP geolocation using delay and topology measurements | Proceedings of the 6th ACM SIGCOMM conference on Internet measurement 被引次数:185 Abstract 定位IP主机地理位置的能力对于在线广告和网络攻击诊断等应用程序是非常吸引力的。虽然先前的方…

CSS-浮动文字环绕布局、隐藏属性display、overflow、三角形制作、鼠标样式

文字环绕布局 CSS文字环绕布局是指在网页中让文字环绕在图片或其他元素周围的布局方式。这通常通过CSS中的float属性来实现。你可以将图片设置为float: left;或float: right;&#xff0c;然后在文本元素中使用clear属性来清除浮动&#xff0c;以确保文字不会覆盖图片。另外&am…

React路由快速入门:Class组件和函数式组件的使用

1. 介绍 在开始学习React路由之前&#xff0c;先了解一下什么是React路由。React Router是一个为React应用程序提供声明式路由的库。它可以帮助您在应用程序中管理不同的URL&#xff0c;并在这些URL上呈现相应的组件。 2. 安装 要在React应用程序中使用React路由&#xff0c;…

使用pytorch构建控制生成GAN(Controllable GAN)网络模型

本文为此系列的第四篇Controllable GAN&#xff0c;上一篇为Conditional GAN。文中使用训练好的模型和优化噪声向量来操纵生成图像的特定属性&#xff0c;若有不懂的无监督知识点可以看本系列第一篇。 原理 本文主要讲什么是控制生成&#xff0c;以及如何做到控制生成。 什么是…