`
星海孤舟
  • 浏览: 69000 次
  • 性别: Icon_minigender_1
  • 来自: 哈尔滨
社区版块
存档分类
最新评论

两内网之间访问,P2P原理

阅读更多

P2P之UDP穿透NAT原理
首先先介绍一些基本概念:  
  NAT(Network Address Translators),网络地址转换:网络地址转换是在IP地址日益缺乏的情况下产生的,它的主要目的就是为了能够地址重用。NAT分为两大类,基本 的NAT和NAPT(Network Address/Port Translator)。  
  最开始NAT是运行在路由器上的一个功能模块。  
   
  最先提出的是基本的NAT,它的产生基于如下事实:一个私有网络(域)中的节点中只有很少的节点需要与外网连接(呵呵,这是在上世纪90年代中期提出 的)。那么这个子网中其实只有少数的节点需要全球唯一的IP地址,其他的节点的IP地址应该是可以重用的。  
  因此,基本的NAT实现的功能很简单,在子网内使用一个保留的IP子网段,这些IP对外是不可见的。子网内只有少数一些IP地址可以对应到真正全球唯一的 IP地址。如果这些节点需要访问外部网络,那么基本NAT就负责将这个节点的子网内IP转化为一个全球唯一的IP然后发送出去。(基本的NAT会改变IP 包中的原IP地址,但是不会改变IP包中的端口)  
  关于基本的NAT可以参看RFC 1631  
   
  另外一种NAT叫做NAPT,从名称上我们也可以看得出,NAPT不但会改变经过这个NAT设备的IP数据报的IP地址,还会改变IP数据报的 TCP/UDP端口。基本NAT的设备可能我们见的不多(呵呵,我没有见到过),NAPT才是我们真正讨论的主角。看下图:  
  Server S1  
  18.181.0.31:1235 |  
  ^ Session 1 (A-S1) ^ |  
  | 18.181.0.31:1235 | |  
  v 155.99.25.11:62000 v |  
  |  
  NAT  
  155.99.25.11  
  |  
  ^ Session 1 (A-S1) ^ |  
  | 18.181.0.31:1235 | |  
  v 10.0.0.1:1234 v |  
  |  
  Client A  
  10.0.0.1:1234  
  有一个私有网络10.*.*.*,Client A是其中的一台计算机,这个网络的网关(一个NAT设备)的外网IP是155.99.25.11(应该还有一个内网的IP地址,比如 10.0.0.10)。如果Client A中的某个进程(这个进程创建了一个UDP Socket,这个Socket绑定1234端口)想访问外网主机18.181.0.31的1235端口,那么当数据包通过NAT时会发生什么事情呢?  
  首先NAT会改变这个数据包的原IP地址,改为155.99.25.11。接着NAT会为这个传输创建一个Session(Session是一个抽象的概 念,如果是TCP,也许Session是由一个SYN包开始,以一个FIN包结束。而UDP呢,以这个IP的这个端口的第一个UDP开始,结束呢,呵呵, 也许是几分钟,也许是几小时,这要看具体的实现了)并且给这个Session分配一个端口,比如62000,然后改变这个数据包的源端口为62000。所 以本来是(10.0.0.1:1234->18.181.0.31:1235)的数据包到了互联网上变为了 (155.99.25.11:62000->18.181.0.31:1235)。  
  一旦NAT创建了一个Session后,NAT会记住62000端口对应的是10.0.0.1的1234端口,以后从18.181.0.31发送到 62000端口的数据会被NAT自动的转发到10.0.0.1上。(注意:这里是说18.181.0.31发送到62000端口的数据会被转发,其他的 IP发送到这个端口的数据将被NAT抛弃)这样Client A就与Server S1建立以了一个连接。
上面的比较基础,下面是关键的部分了。  
  看看下面的情况:  
  Server S1 Server S2  
  18.181.0.31:1235 138.76.29.7:1235  
  | |  
  | |  
  +----------------------+----------------------+  
  |  
  ^ Session 1 (A-S1) ^ | ^ Session 2 (A-S2) ^  
  | 18.181.0.31:1235 | | | 138.76.29.7:1235 |  
  v 155.99.25.11:62000 v | v 155.99.25.11:62000 v  
  |  
  Cone NAT  
  155.99.25.11  
  |  
  ^ Session 1 (A-S1) ^ | ^ Session 2 (A-S2) ^  
  | 18.181.0.31:1235 | | | 138.76.29.7:1235 |  
  v 10.0.0.1:1234 v | v 10.0.0.1:1234 v  
  |  
  Client A  
  10.0.0.1:1234  
  接上面的例子,如果Client A的原来那个Socket(绑定了1234端口的那个UDP Socket)又接着向另外一个Server S2发送了一个UDP包,那么这个UDP包在通过NAT时会怎么样呢?  
  这时可能会有两种情况发生,一种是NAT再次创建一个Session,并且再次为这个Session分配一个端口号(比如:62001)。另外一种是 NAT再次创建一个Session,但是不会新分配一个端口号,而是用原来分配的端口号62000。前一种NAT叫做Symmetric NAT,后一种叫做Cone NAT。我们期望我们的NAT是第二种,呵呵,如果你的NAT刚好是第一种,那么很可能会有很多P2P软件失灵。(可以庆幸的是,现在绝大多数的NAT属 于后者,即Cone NAT)  
   
  好了,我们看到,通过NAT,子网内的计算机向外连结是很容易的(NAT相当于透明的,子网内的和外网的计算机不用知道NAT的情况)。  
  但是如果外部的计算机想访问子网内的计算机就比较困难了(而这正是P2P所需要的)。  
  那么我们如果想从外部发送一个数据报给内网的计算机有什么办法呢?首先,我们必须在内网的NAT上打上一个“洞”(也就是前面我们说的在NAT上建立一个 Session),这个洞不能由外部来打,只能由内网内的主机来打。而且这个洞是有方向的,比如从内部某台主机(比如:192.168.0.10)向外部 的某个IP(比如:219.237.60.1)发送一个UDP包,那么就在这个内网的NAT设备上打了一个方向为219.237.60.1的“洞”,(这 就是称为UDP Hole Punching的技术)以后219.237.60.1就可以通过这个洞与内网的192.168.0.10联系了。(但是其他的IP不能利用这个洞)。  
   
  呵呵,现在该轮到我们的正题P2P了。有了上面的理论,实现两个内网的主机通讯就差最后一步了:那就是鸡生蛋还是蛋生鸡的问题了,两边都无法主动发出连接 请求,谁也不知道谁的公网地址,那我们如何来打这个洞呢?我们需要一个中间人来联系这两个内网主机。  
  现在我们来看看一个P2P软件的流程,以下图为例:  
   
  Server S (219.237.60.1)  
  |  
  |  
  +----------------------+----------------------+  
  | |  
  NAT A (外网IP:202.187.45.3) NAT B (外网IP:187.34.1.56)  
  | (内网IP:192.168.0.1) | (内网IP:192.168.0.1)  
  | |  
  Client A (192.168.0.20:4000) Client B (192.168.0.10:40000)  
   
  首先,Client A登录服务器,NAT A为这次的Session分配了一个端口60000,那么Server S收到的Client A的地址是202.187.45.3:60000,这就是Client A的外网地址了。同样,Client B登录Server S,NAT B给此次Session分配的端口是40000,那么Server S收到的B的地址是187.34.1.56:40000。  
  此时,Client A与Client B都可以与Server S通信了。如果Client A此时想直接发送信息给Client B,那么他可以从Server S那儿获得B的公网地址187.34.1.56:40000,是不是Client A向这个地址发送信息Client B就能收到了呢?答案是不行,因为如果这样发送信息,NAT B会将这个信息丢弃(因为这样的信息是不请自来的,为了安全,大多数NAT都会执行丢弃动作)。现在我们需要的是在NAT B上打一个方向为202.187.45.3(即Client A的外网地址)的洞,那么Client A发送到187.34.1.56:40000的信息,Client B就能收到了。这个打洞命令由谁来发呢,呵呵,当然是Server S。  
  总结一下这个过程:如果Client A想向Client B发送信息,那么Client A发送命令给Server S,请求Server S命令Client B向Client A方向打洞。呵呵,是不是很绕口,不过没关系,想一想就很清楚了,何况还有源代码呢(侯老师说过:在源代码面前没有秘密 8)),然后Client A就可以通过Client B的外网地址与Client B通信了。  
   
  注意:以上过程只适合于Cone NAT的情况,如果是Symmetric NAT,那么当Client B向Client A打洞的端口已经重新分配了,Client B将无法知道这个端口(如果Symmetric NAT的端口是顺序分配的,那么我们或许可以猜测这个端口号,可是由于可能导致失败的因素太多,我们不推荐这种猜测端口的方法)。  
如果两个客户端运行在一个NAT后,并且NAT不支持loopback translation(详见http://midcom-p2p.sourceforge.net/draft-ford-midcom-p2p- 01.txt),则可以通过双方先尝试连接对方的内网IP来解决。

分享到:
评论

相关推荐

    P2P之UDP穿透NAT的原理与C#实现(源码和描述)

    标题中的“P2P之UDP穿透NAT的原理与C#实现”主要涉及两个关键概念:P2P(peer-to-peer)网络技术和UDP(User Datagram Protocol)在NAT(Network Address Translation)环境下的穿透技术。这里我们将深入探讨这两个...

    P2P之UDP穿透NAT的原理与实现

    在互联网的世界里,NAT(网络地址转换)技术被广泛应用于局域网中,它允许多个内部设备共享一个公共IP地址来访问外部...尽管存在难度,但通过这些方法,我们可以让分布在世界各地的设备之间实现高效、低延迟的P2P通信。

    p2p穿透NAT原理分析

    ### P2P穿透NAT原理分析 #### 一、引言 随着互联网技术的发展和普及,P2P网络技术在日常应用中占据了重要的位置。P2P(Peer-to-Peer,点对点)网络允许网络中的节点直接进行通信,无需通过中心服务器中转。然而,...

    P2P.zip_p2p VC

    由于NAT(网络地址转换)的存在,内网设备不能直接被公网上的其他设备访问。打洞技术通过一系列复杂的交互过程,使内网设备能在没有公网IP或者被NAT屏蔽的情况下,也能与公网或者其他内网设备建立直接连接。常见的打...

    P2P之UDP穿透NAT的原理与实现(增强篇).rar

    在P2P网络中,由于NAT的存在,两个位于不同内网的节点之间直接通信可能会遇到困难,因此需要穿透NAT。 UDP(用户数据报协议)是一种无连接的传输层协议,常用于实时通信如音频、视频流,因为它具有低延迟和高效率的...

    内网端口自动映射工具.rar

    它通过在内网与公网之间建立一个通道,将公网的请求定向到内网特定的IP地址和端口。当外部用户尝试访问配置好的公网端口时,工具会将这个请求转发到内网的某个IP和端口,使得内网的服务能够对外响应。 2. **应用...

    P2P聊天工具原来QQ是这个原理

    QQ作为中国最流行的即时通讯软件之一,其背后的P2P原理是实现高效、低延迟通信的关键。 在传统的客户端-服务器(C/S)架构中,所有通信都必须经过服务器。例如,当你发送一条消息给朋友时,你的消息首先发送到腾讯...

    P2P之UDP穿透NAT的原理与实现源码

    在P2P网络中,UDP穿透NAT的技术是关键,它允许两个内网主机通过NAT建立直接连接,从而提高通信效率和降低服务器压力。 **NAT的工作原理:** NAT通过将私有IP地址转换为公网IP地址,使得内部网络中的设备可以访问...

    TCP实现P2P通信TCP穿越NAT

    5. **服务器辅助**:当直接的P2P连接失败时,可以借助第三方服务器作为中介,两个内网节点分别与服务器建立TCP连接,服务器转发两者之间的数据。 在Visual Studio环境下开发TCP P2P通信程序,你需要理解Socket编程...

    P2P穿透NAT的具体实现

    然而,这同时也阻碍了P2P节点之间的直接通信。在本文中,我们将深入探讨如何使用VB.NET编程语言实现P2P穿透NAT的具体技术细节。 首先,我们需要理解P2P穿透NAT的基本策略。主要有以下几种方法: 1. **UDP Hole ...

    基于P2P方式的即时通讯Delphi源码

    在传统的客户端-服务器(C/S)模型中,信息通常通过服务器进行中转,而在P2P网络中,节点之间可以直接通信,减少了服务器的压力并提高了系统的可扩展性。NAT(Network Address Translation)打洞是P2P通信中一个关键...

    TCP P2P连接示例.rar

    P2P技术在分布式系统、文件共享、在线通信等领域广泛应用,它允许网络中的两个节点直接通信,无需通过中心服务器。在NAT(网络地址转换)环境下,P2P连接的建立会遇到挑战,因为NAT会隐藏内部设备的IP地址,使得外部...

    P2P 之 UDP穿透NAT的原理与实现(附源代码)

    然而,NAT对P2P通信构成了挑战,因为数据包在穿越NAT时会丢失必要的源地址信息,导致两端的P2P节点无法直接通信。本文将深入探讨UDP穿透NAT的原理以及实现方法,并提供源代码供参考。 1. UDP穿透NAT原理: - NAT...

    P2P技术介绍

    P2P技术的核心之一是通过UDP协议实现NAT(网络地址转换)穿越,进而实现Internet两端不同内网的两台计算机直接点对点通信。 1. **公网IP与NAT**:在大多数情况下,用户的计算机位于一个私有网络内部,并通过NAT设备...

    音乐播放器P2P

    P2P技术在互联网领域中具有重要的地位,它允许用户之间直接交换数据,而不是通过中心服务器。这种分布式网络架构降低了对单一服务器的依赖,同时也能够提高数据传输速度,尤其在大量用户同时访问时,能有效缓解网络...

    p2p UDP打洞 C++程序

    在NAT环境下,内网的设备不能直接被外网设备访问,因为它们的IP地址被NAT转换了。打洞技术的目的是让两个位于NAT后的设备能够相互发现并建立直接的通信链路。这个程序可能是通过发送特定的UDP报文,诱使NAT设备为两...

    P2P之UDP穿透NAT的原理与实现源代码

    在P2P网络中,数据直接在对等节点之间传输,而不是通过中心服务器。UDP(User Datagram Protocol)是互联网上一种无连接的、不可靠的数据传输协议,常用于实时应用如语音通话、在线游戏等,因为其低延迟和高效性。...

    支持tcp&udp;穿透的商业应用的p2p组件(新版本可编译)

    在IT行业中,P2P(Peer-to-Peer)技术是一种分布式网络架构,它允许网络中的节点之间直接进行通信,而无需通过中心服务器。TCP(Transmission Control Protocol)与UDP(User Datagram Protocol)是两种广泛使用的...

    简单实现内网穿透 没有公网IP也能轻松搞定群晖NAS.docx

    1. **高速传输**:采用P2P模式,一旦客户端之间建立了连接,数据将直接在两端进行传输,极大减少了中间节点的影响,提高了传输效率。 2. **免费多客户端支持**:与某些商用解决方案不同,零遁Edge允许用户免费接入多...

Global site tag (gtag.js) - Google Analytics