STUN(Simple Transversal of UDP through NATs)[21]是RFC3489 规定的一种NAT 穿透方式,它采用辅助的方法探测NAT 的IP 和端口。

STUN 的探测过程需要有一个公网IP的STUN 服务器,在NAT 后面的客户端必须和此服务器配合,互相之间发送若干个UDP数据包。

UDP 包中包含有客户端需要了解的信息,比如NAT 外网IP,PORT 等等。客户端通过是否得到这个UDP 包和包中的数据判断自己的NAT 类型。

前提条件:有一个公网的Server 并且绑定了两个公网IP(IP1,IP2)。这个Server 做UDP 监听(IP1,Port1),(IP2,Port2)并根据客户端的要求进行应答。

第一步:检测客户端是否有能力进行UDP 通信以及客户端是否位于NAT 后面。客户端建立UDP socket,然后用这个socket 向服务器的(IP1,Port1)

发送数据包要求服务器返回客户端的IP 和Port, 客户端发送请求后立即开始接受数据包,要设定socketTimeout(300ms),防止无限堵塞,重复这个过程若干次。

如果每次都超时,无法接受到服务器的回应,则说明客户端无法进行UDP 通信,可能是防火墙或NAT 阻止UDP 通信,这样的客户端也就不能建立P2P 连接了 。

当客户端能够接收到服务器的回应时,需要把服务器返回的客户端(IP,Port)和这个客户端socket 的 (LocalIP,LocalPort)比较,

如果完全相同则客户端不在NAT 后,这样的客户端具有公网IP 可以直接监听UDP端口接收数据进行通信(检测停止)。

否则客户端在NAT后要做进一步的NAT类型检测(检测继续)。

第二步:检测客户端NAT 是否是Full Cone NAT。客户端建立UDP socket 然后用这个socket 向服务器的(IP1,Port1)发送数据包

要求服务器用另一对(IP2,Port2)响应客户端的请求往回发送一个数据包,客户端发送请求后立即开始接受数据包,要设定socket Timeout(300ms),防止无限堵塞. 重复这个过程若干次。

如果每次都超时,无法接受到服务器的回应,则说明客户端的NAT 不是一个Full Cone NAT,具体类型有待下一步检测(继续)。

如果能够接受到服务器从(IP2,Port2)返回的应答UDP 包,则说明客户端是一个Full Cone NAT,这样的客户端能够进行UDP-P2P 通信,检测停止。

第三步:检测客户端NAT 是否是Symmetric NAT。客户端建立UDP socket 然后用这个socket 向服务器的(IP1,Port1)发送数据包要求服务器返回客户端的IP 和Port,

因为第一步保证了这个客户端可以进行UDP 通信,那么肯定能够获得返回的数据。

用同样的方法用一个socket 向服务器的(IP2,Port2)发送数据包要求服务器返回客户端的IP和Port。

比较上面两个过程从服务器返回的客户端(IP,Port),如果两个过程返回的(IP,Port)有一对不同则说明客户端为Symmetric NAT,

这样的客户端无法进行UDP-P2P通信。否则是Restricted Cone NAT,是否为Port Restricted Cone NAT 有待检测。

第四步:检测客户端NAT 是否是Restricted Cone NAT 还是Port Restricted ConeNAT。

客户端建立UDP socket 然后用这个socket 向服务器的(IP1,Port1)发送数据包要求服务器用IP1 和一个不同于Port1 的端口发送一个UDP 数据包响应客户端,

客户端发送请求后立即开始接受数据包,要设定socket Timeout(300ms),防止无限堵塞. 重复这个过程若干次。

如果每次都超时,无法接受到服务器的回应,则说明客户端是一个Port Restricted Cone NAT,如果能够收到服务器的响应则说明客户端是一个Restricted Cone NAT。

以上两种NAT 都可以进行UDP-P2P 通信。

注:以上检测过程中只说明了可否进行UDP-P2P 的打洞通信,具体怎么通信一般要借助于另外的中间服务器。

另外对于Symmetric NAT 不是说完全不能进行UDP-P2P 打洞通信,可以进行端口预测打洞, 不过不能保证成功。

STUN: NAT 类型检测方法的更多相关文章

  1. JavaScript中常用的几种类型检测方法

    javascript中类型检测方法有很多: typeof instanceof Object.prototype.toString constructor duck type 1.typeof 最常见 ...

  2. NAT类型与穿透 及 STUN TURN 协议

    STUN : Simple Traversal of User Datagram Protocol [UDP] Through Network Address Translators [NATs] S ...

  3. JS做类型检测到底有几种方法?看完本文就知道了!

    JS有很多数据类型,对于不同数据类型的识别和相互转换也是面试中的一个常考点,本文主要讲的就是类型转换和类型检测. 数据类型 JS中的数据类型主要分为两大类:原始类型(值类型)和引用类型.常见的数据类型 ...

  4. 小结 javascript中的类型检测

    先吐槽一下博客园的编辑器,太不好用了,一旦粘贴个表格进来就会卡死,每次都要用html编辑器写,不爽! 关于javascript的类型检测,早在实习的时候就应该总结,一直拖到现在,当时因为这个问题还出了 ...

  5. js安全类型检测

    背景: 都知道js内置的类型检测,大多数情况下是不太可靠的,例如:  typeof  . instanceof typeof 返回一个未经计算的操作数的类型, 可以发现所有对象都是返回object  ...

  6. Objective-C 【动态类型检测&响应方法】

    ------------------------------------------- 动态类型检测 代码: #import <Foundation/Foundation.h> @inte ...

  7. 六.OC基础--1. id和instancetype类型,2.动态类型检测,3.响应方法,构造方法,4.重写构造方法,5.自定义构造方法

    1. id和instancetype类型, id和instancetype类型区别: 1. id和instancetype都可以用来作为方法的返回值 2. id可以用来定义类型,instancetyp ...

  8. 手写面试编程题- 数组去重 深拷贝 获取文本节点 设置奇数偶数背景色 JS中检测变量为string类型的方法 第6题闭包 将两个数组合并为一个数组 怎样添加、移除、移动、复制、创建和查找节点? 继承 对一个数组实现随机排序 让元素水平 垂直居中的三种方式 通过jQuery的extend方法实现深拷贝

    第1题==>实现数组去重 通过 new Set(数组名) // var arr = [12, 12, 3, 4, 5, 4, 5, 6, 6]; // var newarr1 = new Set ...

  9. Javascript学习笔记:3种检测变量类型的方法

    ①typeof检测变量类型 console.log(typeof 1);//number console.log(typeof "a");//string console.log( ...

随机推荐

  1. Files

    write public static void write(CharSequence from, File to, Charset charset) throws IOException { asC ...

  2. 组合 z

    输入a b c d e以及它们对应的数字 比如 a-->1 2 3  b-->2 3 c-->1 d-->3 4 5 e-->1 3 5 输出a b c d e的可用组合 ...

  3. Drupal 7.23:函数drupal_alter()注释

    /** * Passes alterable variables to specific hook_TYPE_alter() implementations. * * This dispatch fu ...

  4. 使用clipboard.js复制页面内容到剪切板

    最近在做一个的智能客服Web端浏览器应用,其中有一项需求是客户在获取系统返回的 答案后点击“复制答案”按钮将答案复制到系统剪切板.本以为这是一个小case,但是发现如果 要对各种主流浏览器都有良好的兼 ...

  5. AsyncTask简单获取网络图片的例子

    //首先呢,添加网络权限 android.permission.INTERNET //然后,布局View img=(Image)findViewById(R.id.imageView1); btn=( ...

  6. Scrum角色

    产品负责人(Product Owner)的职责如下: 确定产品的功能. 决定发布的日期和发布内容. 为产品的profitability       of the product (ROI)负责. 根据 ...

  7. PHPCMS V9实现硬件地址MAC绑定访问技术实现

    目的:会员登录需要 用户名.密码.身份识别码(新增字段) 效果:  解决方法: 目前数据库中macaddress字段已经添加,修改了phpcms\modules\member\index.php 63 ...

  8. Arduino uno R3 ISP刷Rootloader for arduino pro mini

    找了好久才发现的,好东西.介绍怎么使用uno对mini 刷Rootloader **SOLUTION** Reinstall the Arduino Pro Mini Bootloader using ...

  9. gradle使用eclipse debug 代码

    设置环境变量 unix,linux      export GRADLE_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,address=9999,s ...

  10. xcode XCTest录制后测试出错临时解决方法

    Xcode 使用 XCTest 做自动化测试,录制后在run UITest 的时候总是莫名报错,后来在方法执行前添加sleep()后,没有再出现错误,可能是xcode的一处BUG.