java - 创建与外部主机的连接时如何获取 NAT 的外部端口以及如何在 Java 中实现 STUN

标签 java protocols traversal nat stun

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

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

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

    ServerSocket sv = new ServerSocket(0);
    

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

    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 服务器交换后知道彼此的外部 ip 和端口时,我所做的方法是实现 STUN 部分的正确方法吗?如果不是,正确的方法是什么?

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

最佳答案

大多数 NAT 系统不会为私有(private)地址空间中的监听套接字打开隧道。您必须要求管理员为您打开一个端口并将该端口传达给远程对等方,或者您必须使用类似 uPNP's Internet Gateway Device Protocol 的内容。 (实际上并未标准化,但许多路由器都实现了它)来请求 NAT 为您打开特定端口。

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

关于java - 创建与外部主机的连接时如何获取 NAT 的外部端口以及如何在 Java 中实现 STUN,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8110693/

相关文章:

c - While 循环未正确迭代

gmail - Google 对 Gmail 使用什么协议(protocol)? (不是 IMAP 或 POP)

python - 如何在 Python 中访问父目录

c - 在二叉树中添加节点时使用指向结构指针的指针

java - 终端 : IOException: Exec_tty error:Unknown reason

java - 字节数组上的 Karatsuba 乘法优化

python - 从其他语言向 IPython 内核发送消息

java - 矩阵特定遍历的智能方法

java - Android:在位图上画一个圆圈

java - 为什么包含主要方法的类没有实例化并且在Java中仍然可以?