转帖地址:http://www.cppblog.com/peakflys/archive/2013/01/25/197562.html
 
二、STUN方式的P2P实现
STUN是RFC3489规定的一种NAT穿透方式,它采用辅助的方法探测NAT的IP和端口。毫无疑问的,它对穿越早期的NAT起了巨大的作用,并且还将继续在NAT穿透中占有一席之地。
STUN的探测过程需要有一个公网IP的STUN server,在NAT后面的UAC必须和此server配合,互相之间发送若干个UDP数据包。UDP包中包含有UAC需要了解的信息,比如NAT外网IP,PORT等等。UAC通过是否得到这个UDP包和包中的数据判断自己的NAT类型。
假设有如下UAC(B),NAT(A),SERVER(C),UAC的IP为IPB,NAT的IP为 IPA ,SERVER的 IP为IPC1 、IPC2。请注意,服务器C有两个IP,后面你会理解为什么需要两个IP。
(1)NAT的探测过程
STEP1:
B向C的IPC1的port1端口发送一个UDP包。C收到这个包后,会把它收到包的源IP和port写到UDP包中,然后把此包通过IP1C和port1发还给B。这个IP和port也就是NAT的外网IP和port,也就是说你在STEP1中就得到了NAT的外网IP。
熟悉NAT工作原理的应该都知道,C返回给B的这个UDP包B一定收到。如果在你的应用中,向一个STUN服务器发送数据包后,你没有收到STUN的任何回应包,那只有两种可能:1、STUN服务器不存在,或者你弄错了port。2、你的NAT设备拒绝一切UDP包从外部向内部通过,如果排除防火墙限制规则,那么这样的NAT设备如果存在,那肯定是坏了„„
当B收到此UDP后,把此UDP中的IP和自己的IP做比较,如果是一样的,就说明自己是在公网,下步NAT将去探测防火墙类型,就不多说了(下面有图)。如果不一样,说明有NAT的存在,系统进行STEP2的操作。
STEP2:
B向C的IPC1发送一个UDP包,请求C通过另外一个IPC2和PORT(不同与SETP1的IP1)向B返回一个UDP数据包(现在知道为什么C要有两个IP了吧,为了检测cone NAT的类型)。
我们来分析一下,如果B收到了这个数据包,那说明什么?说明NAT来着不拒,不对数据包进行任何过滤,这也就是STUN标准中的full cone NAT。遗憾的是,full cone nat太少了,这也意味着你能收到这个数据包的可能性不大。如果没收到,那么系统进行STEP3的操作。
STEP3:
B向C的IPC2的port2发送一个数据包,C收到数据包后,把它收到包的源IP和port写到UDP包中,然后通过自己的IPC2和port2把此包发还给B。
和step1一样,B肯定能收到这个回应UDP包。此包中的port是我们最关心的数据,下面我们来分析:
如果这个port和step1中的port一样,那么可以肯定这个NAT是个CONE NAT,否则是对称NAT。道理很简单:根据对称NAT的规则,当目的地址的IP和port有任何一个改变,那么NAT都会重新分配一个port使用,而在step3中,和step1对应,我们改变了IP和port。因此,如果是对称NAT,那这两个port肯定是不同的。
如果在你的应用中,到此步的时候PORT是不同的,那就只能放弃P2P了,原因同上面实现中的一样。如果不同,那么只剩下了restrict cone 和port restrict cone。系统用step4探测是是那一种。
STEP4:
B向C的IP2的一个端口PD发送一个数据请求包,要求C用IP2和不同于PD的port返回一个数据包给B。
我们来分析结果:如果B收到了,那也就意味着只要IP相同,即使port不同,NAT也允许UDP包通过。显然这是restrict cone NAT。如果没收到,没别的好说,port restrict NAT.
协议实现的算法运行图如下:
一旦路经到达红色节点时,UDP的沟通是没有可能性的(peakflys注:准备来说除了包被防火墙blocked之外,其他情况也是有可能建立P2P的,只是代价太大,一般放弃)。一旦通过黄色或是绿色的节点,就有连接的可能。
最终通过STUN服务器得到自己的NAT类型和公网IP、Port,以后建立P2P时就非常容易了
peakflys注:Libjingle正是通过ICE&STUN方式,建立的P2P连接。关于libjingle的介绍,待续……
 
转帖地址:http://www.cppblog.com/peakflys/archive/2013/01/25/197562.html

Stun方式的P2P实现原理(转)的更多相关文章

  1. P2P的原理和常见的实现方式(为libjingle开路)

    参考原文 为了项目的IM应用,最近在研究libjingle,中间看了也收集了很多资料,感慨网上很多资料要么太过于纠结协议(如STUN.ICE等)实现细节,要么中间有很多纰漏.最后去伪存真,归纳总结了一 ...

  2. P2P的原理和常见的实现方式

    参考资料:http://www.cppblog.com/peakflys/archive/2013/01/25/197562.html P2P实现的原理 首先先介绍一些基本概念:    NAT(Net ...

  3. 转载:P2P技术原理及应用(1)

    转帖allen303allen的空间 作 者:金海 廖小飞 摘要:对等网络(P2P)有3种主要的组织结构:分布式哈希表(DHT)结构.树形结构.网状结构.P2P技术已 经延伸到几乎所有的网络应用领域, ...

  4. 穿透内网,连接动态ip,内网ip打洞-----p2p实现原理(转)

    源: 穿透内网,连接动态ip,内网ip打洞-----p2p实现原理

  5. P2P通讯原理

    1.简介 当今互联网到处存在着一些中间件(MIddleBoxes),如NAT和防火墙,导致两个(不在同一内网)中的客户端无法直接通信.这些问题即便是到了IPV6时代也会存在,因为即使不需要NAT,但还 ...

  6. P2P通信原理与实现(C++)

    1.简介 当今互联网到处存在着一些中间件(MIddleBoxes),如NAT和防火墙,导致两个(不在同一内网)中的客户端无法直接通信.这些问题即便是到了IPV6时代也会存在,因为即使不需要NAT,但还 ...

  7. p2p通信原理及实现(转)

    1.简介 当今互联网到处存在着一些中间件(MIddleBoxes),如NAT和防火墙,导致两个(不在同一内网)中的客户端无法直接通信.这些问题即便是到了IPV6时代也会存在,因为即使不需要NAT,但还 ...

  8. 浅谈P2P终结者原理及其突破

    P2P终结者按正常来说是个很好的网管软件,但是好多人却拿它来,恶意的限制他人的流量,使他人不能正常上网,下面我们就他的功能以及原理还有突破方法做个详细的介绍! 我们先来看看来自在网上PSP的资料:P2 ...

  9. 内网ip打洞-----p2p实现原理

    网上找了非常多.代码大堆,原理讲清楚透彻的不多. 本人找几篇讲得好的来整理一下. 一片技术文章,最基本的讲清楚原理.假设再有完整的能执行的源码也可,关键是要把核心部分代码分析清楚. (1)问题的由来: ...

随机推荐

  1. ie 元素兼容性总结

    css 属性元素 2.z-index 正常按自身层级决定显示顺序,在ie6 7 还需要依赖于父级的层级决定,排布在后边的元素排在前面.后来者居上覆盖前者. IE6,7支持inline元素转换成inli ...

  2. gbk编码汉字转换成对应的十进制十六进制的值

    http://www.mytju.com/classcode/tools/urlencode_gb2312.asp

  3. 26 python 并发编程之多进程理论

    一 什么是进程 进程:正在进行的一个过程或者说一个任务.而负责执行任务则是cpu. 举例(单核+多道,实现多个进程的并发执行): egon在一个时间段内有很多任务要做:python备课的任务,写书的任 ...

  4. Spring_总结_04_高级配置(三)_处理歧义

    一.前言 本文承接上一节:Spring_总结_04_高级配置(二)之条件注解@Conditional 我们前面装配bean时,在Spring容器中,都是只有一个bean能匹配所需的结果. 如果有多个b ...

  5. Spring与RMI集成实现远程访问

    使用spring对RMI的支持,可以非常容易地构建你的分布式应用.在服务端,可以通过Spring的org.springframework.remoting.rmi.RmiServiceExporter ...

  6. 字符集、字符编码、XML中的中文编码

    字符集.字符编码.XML中的中文编码 作为程序员的你是不是对于ASCII .UNICODE.GB2321.UTF-7.UTF-8等等不时出现在你面前的这些有着奇怪意义的词感到很讨厌呢,是不是总觉得好象 ...

  7. js改变select的选中项不触发select的change事件

    // test var selectEl = document.querySelector('select') var buttonEl = document.querySelector('butto ...

  8. [基本操作] Mobius 反演, Dirichlet 卷积和杜教筛

    Dirichlet 卷积是两个定义域在正整数上的函数的如下运算,符号为 $*$ $(f * g)(n) = \sum_{d|n}f(d)g(\frac{n}{d})$ 如果不强调 $n$ 可简写为 $ ...

  9. POJ - 3150 :Cellular Automaton(特殊的矩阵,降维优化)

    A cellular automaton is a collection of cells on a grid of specified shape that evolves through a nu ...

  10. 转载:maven依赖范围

    其中依赖范围scope 用来控制依赖和编译,测试,运行的classpath(注意是与classpath)的关系. 主要的是三种依赖关系如下:1.compile: 默认编译依赖范围.对于编译,测试,运行 ...