Android NAT穿越技术与思想

Android NAT穿越技术与思想,android,traversal,nat,stun,Android,Traversal,Nat,Stun,所以我正在进行NAT遍历 接下来的场景是:我有两部Android手机,我想用HTTP服务器连接它们(套接字)(两部设备都支持NAT) 到目前为止还不错,两个客户端都连接到HTTP服务器,HTTP服务器记录它们的IP地址和端口 但是有一个小问题,因为我使用Java HttpDefaultClient(),每次我从客户端向服务器发送请求时,它都会更改端口。好吧,听起来问题很简单: 让我们使用Socket()来实际维护到服务器的有效TCP连接 公共套接字(InetAddress), 国际港口, Ine

所以我正在进行NAT遍历

接下来的场景是:我有两部Android手机,我想用HTTP服务器连接它们(套接字)(两部设备都支持NAT)

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

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

公共套接字(InetAddress), 国际港口, InetAddressLocalAddr, int本地端口) 抛出IOException

我将只使用这个类,并将localPort放在一些随机的东西上,我会记住的。 现在我又做了所有的事情,这一次似乎港口不会改变,就像我想要的

现在,在我有了对手的IP和端口(他也支持NAT)之后,理论上我可以放弃服务器连接,使用我已经用来实际托管clientServer的本地端口

除非,现在我有个问题: 1) 如果我删除HTTP服务器套接字,NAT会理解这一点并删除端口映射吗 2) 实际上,通过对称圆锥nat是如何工作的?
3) STUN库的工作方式是否有所不同?

NAT的工作方式不尽相同,但您可以依靠以下几点: 1) 如果您的客户端认为它位于端口X上,NAT将把它转换到另一个端口 2) NAT通常接收响应传出数据包的数据包

在服务器的帮助下,STUN尝试猜测实际的传出端口是什么,然后将地址+端口传递给另一个客户端。它不太可靠。TURN只是将所有内容路由到服务器。这更可靠,尽管它会导致服务器上的CPU和带宽成本


如果您可以使用现有代码进行NAT遍历,那么您将省去很多麻烦。否则,就做一些像旋转插座之类的事情,或者使用城市飞艇之类的东西。我也使用了二进制短信,但这是一种特殊情况。

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

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


您可以在此处阅读有关TCP打孔的更多信息:

我认为您在NAT方面遇到了一些问题。事实上,我在一段时间前就做到了这一点(利用第三方服务器(我的)和公共STUN服务器创建了一个点对点android连接)

我强烈建议你阅读这本书,因为它很复杂。我还建议你像我一样使用或实现你自己的

我将使用这个类,并将localPort设置为随机的,我会记住的。现在我再做一次,这一次似乎端口不会改变,就像我想要的那样

我猜是你在nat后面,所以你请求的内部端口被映射到了一个不同的外部端口

现在,在我有了对手的IP和端口(他也支持NAT)之后,理论上我可以放弃服务器连接,使用我已经用来实际托管clientServer的本地端口

目前还没有,大多数nat不仅记录客户端进行两次连接的端口,还记录客户端连接到的IP地址,以便阻止来自其他IP的通信。例如,Phone1位于IP-a上,并从端口b上的IP-a连接到服务器。nat将端口b转换为端口c。从服务器的角度来看,手机位于端口c上的IP-a。它将将此信息发送给phone2。nat将阻止phone2的所有通信,直到phone1从端口b向phone2发送数据

1) 如果我删除HTTP服务器套接字,NAT会理解这一点并删除端口映射吗

我从经验中学到的一点是,除了您的端口将被映射之外,我不希望从nats端口映射行为中得到任何东西,并且一些NAT将更改所述映射,从您的角度来看,这似乎是愚蠢的原因。这需要大量的更新。但总的来说不是