NAT穿透原理

来源:互联网 发布:相片视频制作软件 编辑:程序博客网 时间:2024/05/29 10:08

最后看的一篇是下面这个文章:

http://blog.csdn.net/cuishi0/article/details/7562010

上面基本上已经说明白了。补充一些:


引:

一. NAT分类

根据STUN协议(RFC3489),NAT大致分为下面四类:
1) Full Cone

这种NAT内部的机器A连接过外网机器C后,NAT会打开一个端口.然后外网的任何发到这个打开的端口的UDP数据报都可以到达A.不管是不是C发过来的.
例如 A:192.168.8.100 NAT:202.100.100.100 C:292.88.88.88
A(192.168.8.100:5000) -> NAT(202.100.100.100:8000) -> C(292.88.88.88:2000)
任何发送到 NAT(202.100.100.100:8000)的数据都可以到达A(192.168.8.100:5000)

2) Restricted Cone

这种NAT内部的机器A连接过外网的机器C后,NAT打开一个端口.然后C可以用任何端口和A通信.其他的外网机器不行.
例如 A:192.168.8.100 NAT:202.100.100.100 C:292.88.88.88
A(192.168.8.100:5000) -> NAT(202.100.100.100 : 8000) -> C(292.88.88.88:2000)
任何从C发送到 NAT(202.100.100.100:8000)的数据都可以到达A(192.168.8.100:5000)

3) Port Restricted Cone

这种NAT内部的机器A连接过外网的机器C后,NAT打开一个端口.然后C可以用原来的端口和A通信.其他的外网机器不行.
例如 A:192.168.8.100 NAT:202.100.100.100 C:292.88.88.88
A(192.168.8.100:5000) -> NAT(202.100.100.100 : 8000) -> C(292.88.88.88:2000)
C(202.88.88.88:2000)发送到 NAT(202.100.100.100:8000)的数据都可以到达A(192.168.8.100:5000)


前两个的打洞原理很好理解,关键是第3个,端口限制的NAT,一度让我混淆,如果是端口限制、又每次发数据出去路由器都给弄个不同的端口出来,那肿么可能打洞成功?后来发现,socket是可以指定本地端口的,这样就明白了,跟中介服务器连接的本地端口是啥,打洞的时候就用啥端口去连就能保证路由器出去时还是使用原来的端口,这样就能保证即使是端口限制的也没关系了。

引:

查看JDK API,设置相应的参数。

Socket

    public Socket(String host,              int port,              InetAddress localAddr,              int localPort)       throws IOException
创建一个套接字并将其连接到指定远程主机上的指定远程端口。socket 会通过调用 bind() 函数来绑定提供的本地地址及端口。

如果指定的主机为 null,则等效于指定与 InetAddress.getByName(null) 相同的地址。换句话话,等效于指定回送接口的地址。

如果有安全管理器,则使用主机地址和 port 作为参数调用其 checkConnect 方法。这可能会导致 SecurityException 异常。

参数:
host - 远程主机名,或者为 null,表示回送地址。
port - 远程端口
localAddr - 要将套接字绑定到的本地地址
localPort - 要将套接字绑定到的本地端口
抛出:
IOException - 如果在创建套接字时发生 I/O 错误。
SecurityException - 如果安全管理器存在并且其 checkConnect 方法不允许进行该操作。

示例代码:

Socket so=new Socket("192.168.0.123",5670,InetAddress.getByName("127.0.0.1"),8001);



补充一些知识(转http://blog.csdn.net/overmaker/article/details/3201799):

现在来看一下我们最关心的问题,就是NAPT是依据什么策略来判断是否要为一个请求发出的UDP数据包建立Session的呢?主要有一下几个策略:

A. 源地址(内网IP地址)不同,忽略其它因素, 在NAPT上肯定对应不同的Session
B. 源地址(内网IP地址)相同,源端口不同,忽略其它的因素,则在NAPT上也肯定对应不同的Session
C. 源地址(内网IP地址)相同,源端口相同,目的地址(公网IP地址)相同,目的端口不同,则在NAPT上肯定对应同一个Session
D. 源地址(内网IP地址)相同,源端口相同,目的地址(公网IP地址)不同,忽略目的端口,则在NAPT上是如何处理Session的呢?

D的情况正式我们关心和要讨论的问题。依据目的地址(公网IP地址)对于Session的建立的决定方式我们将NAPT设备划分为两大类:

Symmetric NAPT:
对于到同一个IP地址,任意端口的连接分配使用同一个Session; 对于到不同的IP地址, 任意端口的连接使用不同的Session.
我们称此种NAPT为 Symmetric NAPT. 也就是只要本地绑定的UDP端口相同, 发出的目的IP地址不同,则会建立不同的Session.

        [202.223.98.78:9696] [202.223.98.78:9696] [202.223.98.78:9696]
                ^               ^                       ^
                |               |                       |
                v               v                       v
               9883            9882                    9881
                                 |
                             / [NAT] /
                                 ^
                                 |
                                 v                       
                          [192.168.0.6:1827]
                         
                          图六: Symmetric 的英文意思是对称。多个端口对应多个主机,平行的,对称的!
                 
Cone NAPT:
对于到同一个IP地址,任意端口的连接分配使用同一个Session; 对于到不同的IP地址,任意端口的连接也使用同一个Session.
我们称此种NAPT为 Cone NAPT. 也就是只要本地绑定的UDP端口相同, 发出的目的地址不管是否相同, 都使用同一个Session.

        [202.223.98.78:9696] [202.223.98.78:9696] [202.223.98.78:9696]

                        ^          ^         ^
                         /         |        /
                          v        v       v
                                 9881
                                 [NAT]
                                   ^
                                   |
                                   v                     
                          [192.168.0.6:1827]
                         
                          图七: Cone 的英文意思是锥。一个端口对应多个主机,是不是像个锥子?