NAT遍历技术和想法

时间:2012-05-01 16:54:04

标签: android traversal nat stun

所以我正在进行NAT遍历。

下一个场景是:我有两个Android手机,我想使用HTTP服务器连接它们(套接字)(两个设备都在NAT后面)。

到目前为止,两个客户端都连接到HTTP服务器,HTTP服务器记录了他们的IP地址和端口,

然而有一点问题,因为我使用Java HttpDefaultClient(),它会在每次我从客户端向服务器发送请求时更改端口。好吧,这听起来像一个简单的问题: 让我们只使用Socket()来实际维护到服务器的有效TCP连接。

public Socket(InetAddress地址,               int端口,               InetAddress localAddr,               int localPort)        抛出IOException

我将使用这个类并将localPort随机放入,我会记住。 现在我又做了一切,这次似乎端口不会改变,就像我想要的那样。

现在我拥有了对手的IP和端口(他也在NAT后面),理论上我可以删除SERVER连接并使用我已经用来实际托管客户端服务器的相同localPort吗?

除非,现在出现我有疑问的部分: 1)如果我丢弃HTTP服务器套接字,NAT会理解并删除端口映射吗?(这很糟糕) 2)实际通过对称锥nat的工作原理是什么? 3)STUN图书馆的工作方式有何不同?

3 个答案:

答案 0 :(得分:0)

NAT并不都是一样的,但你可以指望一些事情: 1)如果您的客户认为它在端口X上,则NAT会将其转换为其他端口 2)NAT通常允许响应传出数据包的数据包。

STUN尝试在服务器的帮助下猜测实际的传出端口是什么,然后将地址+端口传递给另一个客户端。它并不十分可靠。 TURN只通过服务器路由一切。虽然它会在服务器上产生CPU和带宽成本,但它更可靠。

如果您可以使用现有代码进行NAT遍历,那么您将省去很多麻烦。否则,做一些像TURN通过套接字,或使用Urban Airship之类的东西。我也使用了二进制短信,但那是一个特例。

答案 1 :(得分:0)

目前,对于大多数(但不是全部)NAT,您可以假设一些一致性和可预测的端口映射行为。 (即,对不同的服务器连接使用相同的本地端口,映射到NAT上的同一本地端口)。但听起来你想通过TCP进行NAT遍历,这比UDP更难。

根本问题是大多数NAT也充当防火墙。他们不允许从远程ip:端口进行入站连接。我相信诀窍是双方同时进行连接。

您可以在此处阅读有关TCP打孔的更多信息:http://en.wikipedia.org/wiki/TCP_hole_punching

答案 2 :(得分:0)

我认为你遇到了关于Nats的几个问题。我实际上让它工作了一段时间(使用第三方服务器(我的)和公共STUN服务器创建一个对等的android连接。

我强烈建议您阅读RFC5389 - Nat traversal这很复杂。我还建议您使用JStun library之类的内容,或者像我一样实现自己的内容。

  

我将使用这个类并将localPort随机放入,我会记住。现在我又做了一切,这次似乎端口不会改变,就像我想要的那样。

我的猜测是你背后的nat,所以你请求的内部端口被映射到不同的外部端口。

  

现在我拥有了对手的IP和端口(他也在NAT后面),理论上我可以删除SERVER连接并使用我已经用来实际托管客户端服务器的相同localPort吗?

还没有,大多数nat不仅会记录客户端建立连接的端口,而且还记录它们连接的IP地址,这样它们就会阻止来自其他IP的流量。例如,Phone1在IP-a上并从端口-b上的ip-a连接到服务器nat将端口-b转换为端口-c。从服务器的角度来看,手机处于端口-c的IP-a。它将此信息转发给phone2。 nat将阻止来自phone2的所有通信,直到phone1从port-b向phone2发送数据。

  

1)如果我丢弃HTTP服务器套接字,NAT会理解并删除端口映射吗?(这很糟糕)2)

我从实验中学到的东西不是期望nats端口映射行为的任何东西,除了你的端口将被映射,并且一些nat将改变所述映射,从你的角度来看似乎是愚蠢的原因。这需要大量更新。但总的来说没有。