P2P原理及UDP穿透简单说明



本文章出自cnntec.com的AZ猫著,如需要转发,请注明来自cnntec.com

Peer-To-Peer缩写P2P
中文称之为对等联网。
用途于交流,比如QQ,MSN等等。
文件传输、分布式数据计算等等。

这里我们主要是是简单讲解一下UDP实现NAT的穿透(俗称打洞)
当然TCP与之相似,可以以此类推。

NAT最开始出现在路由器上。详细的大家可以在网上查下资料
NAT的全称是Network Address Translator中文称之为网络地址转换
NAT分为两大类,NAT和NAPT(Network Address Port Translator)这个不用说了,端口地址转换。

用于实例,简单的说,实现P2P需要一个中转服务器。也就是需要一个第三方。(一会儿我们来说为什么需要一个第三方)

以简单的通迅来讲,首先我们来看一个示例图。

A<——————>B  A与B之间进行的通迅
A的IP地址为222.182.100.1
B的IP地址为222.182.100.2
如果这两个用户都是采用的全球唯一的IP地址,那么他们通迅很简单,也不需要实现P2P。
A<------------------>Nat<-------------------->B
如果其中一方为内网用户,及IP地址不为全球唯一IP
就会出现通过路由器进行通迅。
那么在经过路由器的时候,路由器会出现映射IP地址与端口的情况。
如:A为内网用户。B为外网用户。则B的IP地图为全球唯一IP地址。可以直接通迅。
A的IP地址为:192.168.1.100 端口为1025
经过路由器向B进行通迅,路由器将会产生一个一分钟到几小时不定的一个Session,这个Session映射了内网A的IP地址及其接收信息的端口。
那么路由向B发送信息的时候,IP地址及端口就变成了222.182.100.1:3645(假设)
这个时候实际上A就是在进行路由NAT的穿透,
如果我们在B向A发送信息的时候采用192.168.1.100:1025这样的IP和端口,是找不到A的,因为这个IP不是全球唯一IP。
那么B需要的是在收到A的信息的时候,获取其IP地址和端口,那么获取到的就是222.182.100.1:3645这个路由器的映射Session地址。
B现在只需要向这个映射地址发送消息,路由器就会自动将消息发送到对应的A方去。否则路由器将当作无用包,将这个消息丢弃。
那如,我们现在就实现了局域网向某单个固定外网机器发送消息。
如果再来一台C端,也是外网的IP。C通过222.182.100.1:3645向A发送消息,A是否能收到呢?答案是否定的,A不能收到。为什么?因为路由在映射A的穿透时就记录了B的地址,也就是除了B向这个映射点发送消息可以通向A,其它的地址是不行的。路由器此时会将其当作无用包消息给丢弃掉。
那怎么办呢?只有A再向C发送一个穿透,C才可以向A发送消息。

以上我们只是说了一点基本的理论。接下来我们要实现什么?不同内网通过internet网进行通迅。
再来,我们举个图例

A<----------->NatA<---------->NatB<---------->B
A的地址是:192.168.1.100端口4000
B的地址是:192.168.1.100端口4000
它们两个都是内网的地址。及局域网内部地址。并不是全球唯一地址。
两个路由:
NatA的地址是:222.182.100.1
NatB的地址是:222.182.100.2
这两个路由是外网的地址,及全球唯一地址。

现在我们要实现A与B的通迅。
因为A与B都不是外网地址。所以A不可能向192.168.1.100发送消息。这消息只会它自己收到,因为这个IP是它自己的。同样B也不可以。
那么A向NatB发送消息,B能收到吗?答案是否定的,不能收到。刚才我们提到过。因为路由没有映射B的地址。A并不知道这个Session就连NatB也不知道这个Session因为B没有向A发送消息,并不产生这个Session。
就算B和A同时向双方的路由发送消息,产生的Session,A和B也得不到。因为在路由上就把这个消息当做为无用包给丢弃掉了。

那么这样的情况我们要进行通迅怎么办呢?
对,就是刚才我们提到的第三方。第三方是个什么方呢?
第三方必须是一个拥有固定外网IP的服务方。及一个外网服务器。全唯一IP地址。

图例:
假定我们这个第三方为C
C  IP:222.182.100.3端口4001
A<----------->NatA<--------------->C<-------------------->NatB<------------->B
                    ↑______________________________↑                                                          

原理如下
A通过路由向C发送消息,C获取A的在路由上的Session地址,映射的IP和端口
B同样。
这时候C就有了A和B的地址。
C可以和A、B进行通迅,但是A和B还不行。
现在C需要通知A方B的映射IP和端口。也要通知B方A的映射IP和端口。
这样A就有了B的映射地址,B也有了A的。但是现在还不能进行通迅。
因为在路由上A和B都只有对C的穿透。并没有相互之前的穿透。
那么A要向B发送消息怎么办呢?需要C向B发送一个消息告诉B方A的地址让B向这个地址发送一个消息,对A进行一个穿透。
这样A就可以向B发送消息了。在A向B发送消息的同时,A也在向B进行穿透。
这样就可以实现相互的通迅了。如果有多个端点,也就以此类推了。
宗上所述就是P2P的UDP实现原理了。TCP也是一样的。提示一点。Session在路由上是有时限的,一分钟到几小时不定。不同的路由不同的时间,为了保持这个Session的存在,你需要在固定时间点进行通迅,保持这个穿透,否则就得重新穿透。

值得注意的一点。
路由上的映射有两种情况
第一种情况是:Cone NAT
第二种情况是:Symmetric NAT
我们以上的实现是以Cone Nat为基础的。为什么呢?因为Cone Nat在映射的时候端口是不变的。无论你内网有多少台机器,向外网发送消息在路由上映射的端口都是不变的。
而Symmetric Nat则相反,一个映射一个端口。如果碰到这种情况只有祝你好运了,最好不要猜。(十有八九猜不到。所以不推荐猜)





UDP打洞流程:

1、客户端A登录服务器,服务器将客户端A的私网和公网终结点记录下来。
2、客户端B登陆服务器,服务器将客户端B的私网和公网终结点记录下来。
3、服务器将A的公网终结点发给客户端B。
4、客户端B向客户端A发一个数据包
    (此数据包作用:在客户端B的NAT上建立一个session,
     该session为B分配一个端口,即打了一个往A方向的洞口,
     以后如果有数据包从公网到达此端口,NAT将会把此数据包直接转发给客户端B)。
     但此时客户端A收不到此数据包,因为A端的NAT拦截了这个未曾谋面的数据包。
5、客户端B向服务器报告:已经向A方向打洞,此时服务器将B的公网终结点发给A,
     并命令客户端A往B方向发一个数据包(作用同第4步)。
6、客户端A发送一个数据包到客户端B的公网终结点上。
     此时,客户端B已经接收到A发送过来的这个数据包,
     至此打洞成功,以后A和B可以直接互相发送信息了!

 
Server端打洞流程的编写:

1、 S启动两个网络侦听,一个叫【主连接】侦听,一个叫【协助打洞】的侦听。
2、 A和B分别与S的【主连接】保持联系。
3、 当A需要和B建立直接的TCP连接时,首先连接S的【协助打洞】端口,并发送协助连接申请。
    同时在该端口号上启动侦听。注意由于要在相同的网络终端上绑定到不同的套接字上,
    所以必须为这些套接字设置 SO_REUSEADDR 属性(即允许重用),否则侦听会失败。
4、 S的【协助打洞】连接收到A的申请后通过【主连接】通知B,
    并将A经过NAT-A转换后的公网IP地址和端口等信息告诉B。
5、 B收到S的连接通知后首先与S的【协助打洞】端口连接,
    随便发送一些数据后立即断开,这样做的目的是让S能知道B经过NAT-B转换后的公网IP和端口号。
6、 B尝试与A的经过NAT-A转换后的公网IP地址和端口进行connect,
    根据不同的路由器会有不同的结果,有些路由器在这个操作就能建立连接(例如我用的TPLink R402),
    大多数路由器对于不请自到的SYN请求包直接丢弃而导致connect失败,
    但NAT-A会纪录此次连接的源地址和端口号,为接下来真正的连接做好了准备,
    这就是所谓的打洞,即B向A打了一个洞,下次A就能直接连接到B刚才使用的端口号了。
7、 客户端B打洞的同时在相同的端口上启动侦听。
    B在一切准备就绪以后通过与S的【主连接】回复消息“我已经准备好”,
    S在收到以后将B经过NAT-B转换后的公网IP和端口号告诉给A。

8、 A收到S回复的B的公网IP和端口号等信息以后,开始连接到B公网IP和端口号,
    由于在步骤6中B曾经尝试连接过A的公网IP地址和端口,NAT-A纪录了此次连接的信息,
    所以当A主动连接B时,NAT-B会认为是合法的SYN数据,并允许通过,从而直接的TCP连接建立起来了

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PCB genesis 大孔扩孔(不用G84命令)实现方法

PCB钻孔时,当钻刀>6.3mm时,超出钻孔范围,钻孔工序是没有这么大的钻刀,当这种情况,工程CAM会都采用G84命令用小孔扩孔的方式制作, 在这里介绍一种如果不用G84命令,用程序实现将大孔生成小孔钻孔达到扩孔的目的。 一.我们先了解一下G84命令扩孔 孔尺寸大小 孔密度 连一篇文章有…

一年没做出量化策略_量化信念:如何做出更好的决定

一年没做出量化策略By Stuart George, Executive Director of Design Technology at MethodMethod设计技术执行总监Stuart George When Andrew Mason, founder of Groupon, wanted to improve his email conversion metrics, he turned to data analysis. His team tested the…

Android Jetpack组件之数据库Room详解(二)

本文涉及Library的版本如下&#xff1a; androidx.room:room-runtime:2.1.0-alpha03androidx.room:room-compiler:2.1.0-alpha03(注解编译器)回顾一下安卓的SQLiteOpenHelper相关类 首先放一个关于安卓数据库的类图: SQLiteOpenHelper是一个抽象类&#xff0c;通常自己实现数据…

图像识别中的深度学习

来源&#xff1a;《中国计算机学会通讯》第8期《专题》 作者&#xff1a;王晓刚 深度学习发展历史 深度学习是近十年来人工智能领域取得的重要突破。它在语音识别、自然语言处理、计算机视觉、图像与视频分析、多媒体等诸多领域的应用取得了巨大成功。现有的深度学习模型属于神…

多个css样式合并到一个“目录”css文件中

执行访问jsp后发现没有效果 同样的代码&#xff0c;在html中效果对比如下&#xff1a; 具体原因&#xff1a;不清楚&#xff0c;暂时记着~~~在jsp中不支持import这种css样式的引用 转载于:https://www.cnblogs.com/mangwusuozhi/p/10050108.html

Git 学习笔记之 merge

Merge: 1、Fast-forward&#xff08;快进式&#xff09; 2、recursice strategy (策略合并&#xff0c;三方合并) Fast-forward 策略合并 //创建一个文件夹&#xff0c;并初始化 Git mkdir GitDemo cd GitDemo git init//初次提交&#xff0c;创建 master 分支 touch master.tx…

熊猫直播 使用什么sdk_没什么可花的-但是16项基本操作才能让您开始使用熊猫

熊猫直播 使用什么sdkPython has become the go-to programming language for many data scientists and machine learning researchers. One essential data processing tool for them to make this choice is the pandas library. For sure, the pandas library is so versat…

萌新一手包App前后端开发日记(一)

从事Android移动端也有些日子了&#xff0c;还记得一开始选择这份工作&#xff0c;是憧憬着有朝一日能让亲朋好友用上自己开发的软件&#xff0c;但日子久了才发现&#xff0c;并不是所有的公司&#xff0c;所有的项目的适用群体都是“亲朋好友”&#xff0c;/无奈脸 摊手。当…

方差,协方差 、统计学的基本概念

一、统计学的基本概念 统计学里最基本的概念就是样本的均值、方差、标准差。首先&#xff0c;我们给定一个含有n个样本的集合&#xff0c;下面给出这些概念的公式描述&#xff1a; 均值&#xff1a; 标准差&#xff1a; 方差&#xff1a; 均值描述的是样本集合的中间点&#xf…

关系型数据库的核心单元是_核中的数据关系

关系型数据库的核心单元是Nucleoid is an open source (Apache 2.0), a runtime environment that provides logical integrity in declarative programming, and at the same time, it stores declarative statements so that it doesn’t require external database, in shor…

MongoDB第二天

集合的操作: db.表名称 show tables / collection db.表名.drop() 文档的操作: 插入数据 db.表名.insert({"name":"jerry"}) db.insertMany([{"name":"sb",...}]) var ul {"name":"sb"} db.sb.insert(ul) db.sb.…

Python 主成分分析PCA

Python 主成分分析PCA 主成分分析&#xff08;PCA&#xff09;是一种基于变量协方差矩阵对数据进行压缩降维、去噪的有效方法&#xff0c;PCA的思想是将n维特征映射到k维上&#xff08;k<n&#xff09;&#xff0c;这k维特征称为主元&#xff0c;是旧特征的线性组合&#xf…

小程序 国际化_在国际化您的应用程序时忘记的一件事

小程序 国际化The hidden bugs waiting to be found by your international users您的国际用户正在等待发现的隐藏错误 While internationalizing our applications, we focus on the things we can see: text, tool-tips, error messages, and the like. But, hidden in our …

三. 性能测试领域

能力验证&#xff1a; 概念&#xff1a;系统能否在A条件下具备B能力 应用&#xff1a;为客户进行系统上线后的验收测试&#xff0c;作为第三方对一个已经部署系统的性能验证 特点&#xff1a;需要在已确定的环境下运行 需要根据典型场景设计测试方案和用例 一个典型场景包括操…

PCA主成分分析Python实现

作者&#xff1a;拾毅者 出处&#xff1a;http://blog.csdn.net/Dream_angel_Z/article/details/50760130 Github源码&#xff1a;https://github.com/csuldw/MachineLearning/tree/master/PCA PCA&#xff08;principle component analysis&#xff09; &#xff0c;主成分分…

scp

将文件或目录从本地通过网络拷贝到目标端。拷贝目录要带 -r 参数 格式&#xff1a;scp 本地用户名IP地址:文件名1 远程用户名IP地址:文件名 2 例&#xff1a; scp media.repo root192.168.20.32:/etc/yum.repos.d/ 将远程主机文件或目录拷贝到本机&#xff0c;源和目的参数调换…

robo 3t连接_使用robo 3t studio 3t连接到地图集

robo 3t连接Robo 3T (formerly Robomongo) is a graphical application to connect to MongoDB. The newest version now includes support for TLS/SSL and SNI which is required to connect to Atlas M0 free tier clusters.Robo 3T(以前称为Robomongo )是用于连接MongoDB的…

JavaWeb--JavaEE

一、JavaEE平台安装1、升级eclipseEE插件2、MyEclipse二、配置Eclipse工作空间1.字体设置 2.工作空间编码 UTF-83.JDK版本指定 4.集成Tomcat Server运行环境5.配置server webapps目录 端口号 启动时间等三、创建第一个Web项目1.创建 Web Project2.设置 tomcat、创建web.xml3.目…

软件需求规格说明书通用模版_通用需求挑战和机遇

软件需求规格说明书通用模版When developing applications there will be requirements that are needed on more than one application. Examples of such common requirements are non-functional, cookie consent and design patterns. How can we work with these types of…

python版PCA(主成分分析)

python版PCA&#xff08;主成分分析&#xff09; 在用统计分析方法研究这个多变量的课题时&#xff0c;变量个数太多就会增加课题的复杂性。人们自然希望变量个数较少而得到的信息较多。在很多情形&#xff0c;变量之间是有一定的相关关系的&#xff0c;当两个变量之间有一定…