首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VB >

双方都在Port-Restricted Cone NAT后的客户端,udp穿透,打洞时发生的郁闷有关问题

2012-07-22 
双方都在Port-Restricted Cone NAT后的客户端,udp穿透,打洞时发生的郁闷问题下面写了那么多,可能大家看得

双方都在Port-Restricted Cone NAT后的客户端,udp穿透,打洞时发生的郁闷问题
下面写了那么多,可能大家看得烦,我先在这里简单说下现象,大家帮忙看看:
假如有2台公网IP服务器:
S1: 1.2.3.4 lcoal UDP端口8888
S2: 6.7.8.9 lcoal UDP端口6666
1台路由器后的客户机C:192.168.0.6,其路由器IP是 14.110.2.3
我们先测试下路由器是否cone类型
C -> S1 : 192.168.0.6:6666 ->nat 14.110.2.3:2596 -> s1 1.2.3.4:8888
C -> S2 : 192.168.0.6:6666 ->nat 14.110.2.3:2596 -> s2 6.7.8.9:6666
这里可以看到,c先后用本地端口6666访问s1和s2,都被路由器映射成了2596端口,证明是cone类型

好,我们下面进一步试验,问题就出在下面了
先 “C -> S1 : 192.168.0.6:6666 ->nat 14.110.2.3:2596 -> s1 1.2.3.4:8888
再 :S2 -> C : s2 6.7.8.9:6666 -> nat 14.110.2.3:2596 (当然这个包会被路由器丢弃,但我估计问题就出在这里了)然后就出问题了: C -> S2 : 192.168.0.6:6666 ->nat 14.110.2.3:56879 -> s2 6.7.8.9:6666

大家注意上面红色的端口,此时被映射成了56879,这是怎么回事,打洞问题就出在这里了。
怎么解决这个问题的打洞?



我用了VB 的winsock 控件用 UDP协议做了一个server和client,不成功啊。我先说说我的环境:
s在有公网固定IP,c1和c2分别为两地ADSL拨号后面的路由器后的电脑,
c1和c2不停(每5秒)向S发送心跳包,s记录它们的NAT后的外网IP和端口,并交换告知c2和c1,
现在C1欲发消息给C2,
C1向s发送请求打洞消息,s告诉c2要打洞,c2发送一个打洞包给c1 NAT后的外网IP和端口,c2告诉S已打洞,s告诉c1已打洞,C1发送消息给c2,过程就是这样,如果超时就重发,重发次数设为的5,可是就是不成功,消息发不出去。

如果C1和c2都在路由后,则打洞不成功,我又测试了一下,如果其中一方做了DMZ(就是有了公网IP),打洞就会成功。不管C1还是C2做了DMZ都会成功,这排除了2个路由器不是锥形NAT的可能。比如C1有公网ip,c1要发消息给C2,c1通过S请求c2向c1打洞后,c1的消息能正常发给c2,反过来也行。

于是,我又写了个小工具,跟踪调试它们的IP和端口信息,发现个有趣但又无赖的现象:
假如:
s的IP为 8.8.8.8 ,UDP localport 为 8888
c1的ip和端口为:192.168.1.11:1111
c2的ip和端口为:192.168.2.22:2222

c1和C2分别向S端口8888发送心跳包,S得到的:
c1的外网IP为 1.1.1.1 ,UDP localport 为 1111
c2的外网IP为 2.2.2.2 ,UDP localport 为 2222

现在C1欲发消息给c2,c1通过S告诉c2向c1打洞,那么c2还用这个winsock不改变LOCALPORT发送打洞包给1.1.1.1:1111,即:

2.2.2.2:2222(192.168.2.22:2222) --> 1.1.1.1:1111,此时,这个打洞包会被c1的路由器丢弃,根据地球人公布的打洞原理,此时打洞已成功,C1可以向C2发送消息了,但是:
关键时刻来了:
此时如果c1向C2发送消息时(即:192.168.1.11:1111 --> 2.2.2.2:2222 ),路由器会重新给C1分配端口,即是:1.1.1.1:2342(假设端口号会变成2342,不再是1111) -->2.2.2.2:2222 ,所以导致打洞失败。但是过一会(超时后,大概3分钟),c1再向C2发送消息时(即:192.168.1.11:1111 --> 2.2.2.2:2222 ),又会变成:1.1.1.1:1111 --> 2.2.2.2:2222

你可能会说我的路由器是对称型NAT,但是,我想说的是:如果c2不先向C1发送那个打洞包,而先c1向c2发送消息,即:

192.168.1.11:1111 --> 2.2.2.2:2222,那么路由器的映射又是正确的1.1.1.1:1111 --> 2.2.2.2:2222 ,心跳包也是

1.1.1.1:1111 --> 8.8.8.8:8888,即符合锥形NAT现象,看起来就好像是那个打洞包干扰了路由器的映射(我猜测是ICMP的原因),所以此时这个c1发向c2

的消息又变相成了c1到c2的打洞包,那c2向C1发消息,外网端口又会被路由器重新映射。


测试了4个路由器,飞鱼星,思科,日立,D-LINK,均是如此,这该如何解决呢?



[解决办法]
已经在另外一个帖子给你解答了,分给我吧,嘿嘿
[解决办法]
是 不能绑定一个 但是问题 处在哪里 我说下 看你是否理解

内网1 发送 给 内网2 时候 路由器 会动态分配一个端口
这时候 你如果 在 用 内网1 发送给 服务器 这时候 路由器端口就会从新分配一个
在发内网2 这时候 他会认为是单独的链接 又会分配一个端口 因此 打动时候 该控件不能变
[解决办法]
你的 远端端口 不要变 还是原来的端口 你不用管路由器的端口 也不用跟着他变 你只要 2方 向路由器 发消息 发一会就连接成功了 腾讯是 发2条消息

热点排行