所以我正在进行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图书馆的工作方式有何不同?
答案 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将改变所述映射,从你的角度来看似乎是愚蠢的原因。这需要大量更新。但总的来说没有。