1

我正在研究 NAT 和 STUN 协议,但我还没有理解它们,所以我尝试在 Java 中实现 STUN。

假设我有 2 台计算机通过 2 个各自的全锥 NAT 设备连接到 Internet,我正在尝试用 Java 实现 STUN 协议,我只是实现了当 2 个对等方都知道彼此的外部 IP 和端口时的部分,其中一个(我们称这个对等点是“客户端”)正在尝试向另一个(这个对等点是“服务器”)发送消息。我做了这样的事情:

  • 在服务器上,我通过以下方式打开了一个套接字:

    ServerSocket sv = new ServerSocket(0);
    

    然后我通过这个站点http://www.whatismyip.com获取服务器的 ip ,并获取打开的端口:

    System.out.println(sv.getLocalPort());
    
  • 在客户端,我通过以下方式向服务器发送消息:

    Socket sk = new Socket(serverIP, serverPort);
    PrintWriter pw = new PrintWriter(sk.getOutputStream(), true);
    pw.print("Hello there");
    pw.close();
    sk.close();
    

但是服务器收不到任何东西,所以我有一些问题:

  1. 我认为我通过上述方式获得的服务器外部端口不是另一个对等方将用于向服务器发送消息的外部端口,那么在 Java 中获取它的正确方法是什么?

  2. 我的做法是在与 STUN 服务器交换后 2 个对等方知道彼此的外部 ip 和端口时实现 STUN 部分的正确方法?如果不是,那么正确的方法是什么?

希望大家给我解释一下,谢谢大家!

4

2 回答 2

0

你需要一个著名的 STUN 服务器,它位于公共互联网的某个地方,作为协调器。这种 STUN 服务器帮助两个对等方发现彼此的公共地址和端口。只有在对等方相互了解并开始通信后,您拥有全锥形 NAT 才会有所帮助。如果不是全锥体,STUN 服务器可能需要在对等点之间中继所有流量!

最相关的规格是:

至于 Java 实现,我发现littleshoot stun stack的状态非常好。

于 2011-12-06T08:05:09.590 回答
0

大多数 NAT 系统不会为私有地址空间中的侦听套接字打开隧道。您必须要求管理员为您打开一个端口并将该端口与远程对等方通信,或者您必须使用类似uPNP 的 Internet 网关设备协议(实际上没有标准化,但许多路由器实现它)来请求 NAT 打开一个您的特定端口。

根据我对STUN RFC的阅读,似乎假设用于与 STUN 协调服务器通信的端口与客户端可能用于连接第一个 STUN 对等方的端口相同。对于 RFC 来说,这似乎是一个令人惊讶的假设,因为它给 NAT 路由器带来了难以置信的负担,要反复将同一个端口分发给同一个客户端,从而使 NAT 数据包传递规则变得非常复杂。我希望我在这里错了。

于 2011-11-13T09:36:44.010 回答