问题标签 [hole-punching]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
17106 浏览

sockets - UDP打孔算法

任何人都可以举一个UDP打孔的例子吗?

其实,我想写一个聊天程序,当人们知道对方的IP时,可以用它聊天。但是这两台机器都将位于防火墙路由器后面。所以,我需要打一个洞来沟通。

我想要一个函数,这样在调用该函数时,会打一个洞,未来的通信会很容易进行——如果这不是太多要求的话:)

0 投票
1 回答
258 浏览

networking - PHP、Java Servlet 或 C# WebService 作为 NAT 中间服务器

与其在亚马逊和其他托管公司租用服务器(这将花费很多美元/月),是否可以设置 Java Servlet、C# WebService 或简单的 PHP 网站(带有套接字或 PHP 具有的任何网络功能)并使用作为中间服务器,客户端和服务器可以交换IP吗?

这个问题是关于 NAT 穿越、UDP 打孔等。

从技术上讲,只要中间服务器能够接收和发起连接,就足够了,对吧?中间服务器只需从客户端和服务器读取公共端点,交换它们,并启动与相反(或接近此)端点的相同连接。因此,它看起来像是一个免费的 ASP.NET 托管服务,因为 C# WebService 将使这成为可能,而不是租用 Amazon EC2 服务器来设置更全面的服务器。

0 投票
5 回答
26691 浏览

c# - UDP打孔实现

我正在尝试完成 UDP 打孔。我的理论基于这篇文章和这个WIKI 页面,但我在 C# 编码方面遇到了一些问题。这是我的问题:

使用此处发布的代码,我现在能够连接到远程计算机并在同一端口上侦听传入连接(将 2 个 UDP 客户端绑定到同一端口)。

由于某种原因,同一个端口的两个绑定会阻止对方接收任何数据。我有一个响应我的连接的 UDP 服务器,所以如果我在将任何其他客户端绑定到端口之前先连接到它,我会得到它的响应。

如果我将另一个客户端绑定到该端口,则任何一个客户端都不会收到任何数据。

以下是显示我的问题的 2 段代码。第一个连接到远程服务器以在 NAT 设备上创建规则,然后在不同的线程上启动侦听器以捕获传入的数据包。然后代码将数据包发送到本地 IP,以便侦听器获取它。第二个仅将数据包发送到本地 IP 以确保其正常工作。我知道这不是真正的打孔,因为我将数据包发送给自己,而根本没有使用 NAT 设备。在这一点上我面临一个问题,如果我使用 NAT 设备外部的计算机进行连接,我认为这不会有任何不同。

[编辑] 2/4/2012 我尝试使用网络上的另一台计算机和 WireShark(数据包嗅探器)来测试侦听器。我看到从另一台计算机传入的数据包,但侦听器 UDP 客户端 (udpServer) 或发送方 UDP 客户端 (客户端) 未接收到这些数据包。

[编辑] 2010 年 2 月 5 日我现在添加了一个函数调用,以在初始发送和接收数据包后关闭第一个 UDP 客户端,仅在第二个 UDP 客户端上监听端口。这有效,我可以从该端口上的网络内部接收数据包。我现在将尝试从网络外部发送和接收数据包。我一有发现就会发布我的发现。

使用此代码,我在侦听客户端上获取数据:

如果我使用下面的代码,在我的客户端和服务器之间的连接和数据传输之后,正在监听的 UDP 客户端将不会收到任何东西:

0 投票
0 回答
1150 浏览

java - NAT Traversal / HolePunching TPC的Java实现

我一直在浏览和搜索与路由器后面的两个客户端的对等 TCP 连接的实现,但我得到的一切都是“变得更加困惑”!

我的情况“有点简单”,因为我已经知道双方的本地和公共 IP 地址

所以,在这一点上,我不需要使用第三台服务器来发现这些信息。


客户端 A:(LocalIP="192.168.0.1",PublicIP="aaaa")。

此客户端将侦听端口“pppp”上的连接


客户端 B: (LocalIP="10.10.0.1", PublicIP="bbbb")

此客户端将尝试连接到端口“pppp”上的“客户端 A”


当然它不起作用,所以鉴于这些信息,如何进行?

0 投票
1 回答
623 浏览

ssh - 如果可能——如何使用 irc 服务器(如 gmail 聊天或 facebook)在防火墙后面的两台主机之间建立 ssh 连接

我一直在寻找实现这一点的解决方案,但谷歌总是给我提供关于通过 ssh 隧道建立实时聊天的教程——而不是相反。我怀疑这可以仅使用隧道来实现(如果可能的话),但我不确定如何。

如果有人问过这个问题,我很抱歉,但是在查看了相关问题之后,我还没有找到一个我可以肯定会满足我特定需求的问题(即我无法直接使用 gmail.com 创建一个 ssh 会话等)如果我错了,请发布适用问题的链接。

0 投票
3 回答
2628 浏览

networking - UDP 打孔主机特定故障

我编写了一个程序来建立对等链接。该程序可在http://basyl.co.uk/code/punch/doc/files/Readme-txt.html找到,它分为两部分:在公共主机上运行的服务器;以及由所需对等链路的每一端使用的客户端。

我可以访问两个公共服务器:“bonn”(home.contextshift.co.uk)和“entropy”(home2.contextshift.co.uk)

  • 如果服务器在 bonn 并且客户端在 bonn、entropy 和我的家用 PC(在 NAT 之后)上运行,则 entropy 的穿孔连接可以毫无问题地与我的 PC 通信。但是,从波恩到 PC 的连接失败;来自 PC 的数据到达波恩,但从波恩通过 NAT 孔返回的数据永远不会到达。

  • 如果服务器再次处于熵状态,则客户端在波恩、熵和我的 PC 上运行,所有客户端之间的穿孔连接都可以正常工作。

这是令人困惑的,因为服务器不参与对等数据流。如果你还和我在一起,这里是流程:

  • Client-A 通过 TCP 链接连接到 Server 并获得唯一的令牌;
  • Client-B 通过 TCP 链接连接到 Server 并获得唯一的令牌;

  • Client-A 和 Client-B 通过他们的 TCP 链路接收更新,告诉他们还有谁连接;

  • 客户端 A(或 B)通过新创建的 UDP 链接向服务器发送请求,传递其令牌和客户端 B 的名称;

  • 服务器从令牌中识别出Client-A,并通过其TCP链接将请求转发给Client-B,在请求中包括A的UDP地址/端口号;

  • 客户端 A(或 B)通过新创建的 UDP 链接向服务器发送确认,传递其令牌和客户端 A 的名称;

  • 服务器从令牌中识别出Client-B,并通过其TCP链接将请求转发给Client-A,在请求中包括B的UDP地址/端口号;

  • A 和 B 现在有了对方的 UDP 地址/端口,可以互相 ping 通并交换数据。

如您所见,服务器从不讨论客户端为他们的请求创建的 UDP 链接,只在 TCP 链接上进行对话。

因此,总而言之,当服务器位于同一主机上时,客户端无法在特定主机上工作。关于这种行为的原因或我可以进一步调查的方法有什么建议吗?

请注意,此测试是人为的,因为打孔的目的是在 NAT 后面的两个主机之间进行通信。这实际上是有效的,无论服务器在哪里,所以这个问题可能被认为是学术问题。

另请注意,在编写程序之前,我尝试使用名为“NatCheck”的公共应用程序。这也以类似的方式失败,尽管我没有对其进行太多调查 - 它需要三个公共主机,我修改它只使用我的两个。当它无法工作时,我认为我以某种方式搞砸了并丢弃了该应用程序。

对代码的任何评论也非常受欢迎(我可能会将其发布在代码审查网站上)。

0 投票
4 回答
19701 浏览

java - Java UDP 打孔示例 - 通过防火墙连接

假设我有两台电脑。

他们通过ice4j.

一个客户端监听,另一个发送一些字符串。

我希望通过 UPD 打孔看到这种情况发生:

任何人都可以发布如何通过对称 NAT 进行打孔的伪示例吗?假设将有服务器 S 帮助猜测端口号并在客户端 A 和 B 之间建立连接。

如果您也考虑双 NAT,那就太好了。

笔记:

您可以使用 STUN 来发现 IP 和端口,但您必须编写自己的代码,通过keepalive技术将 IP:Port 发送到您的服务器。

一旦一个客户端通过服务器上的唯一 ID 识别另一个客户端,它将提供另一个客户端的 IP:端口信息,以便 UDP 打孔它需要发送和接收的数据。

小更新:

有一个即将出现的库供 java 检查一下:
https ://github.com/htwg/UCE#readme

0 投票
4 回答
2920 浏览

c# - 游戏如何处理 NAT 路由器问题?

在过去的几天里,我一直在开发一款在线游戏,一款 2 人游戏,其中一个人启动服务器(侦听某个端口),另一个人通过输入他的 IP 连接到他。这种方法有两个问题:

  • 输入对方IP非常难受。
  • 服务器不能位于路由器后面,因为 NAT 会阻止它工作。

第一个问题可以通过匹配服务来解决,该服务会在用户不关心的情况下处理所寻址的 IP。但我不确定如何解决第二个问题。我已经阅读了有关“TCP 打孔”的信息,但根据我所阅读的内容,当两个玩家都在路由器后面时,不可能执行此操作。如果这是真的,那么像 Halo 3 这样的配对服务游戏如何运作?

提前致谢。

0 投票
2 回答
522 浏览

c# - c# 使用 stunserver 完成远程计算机发送和接收数据

我无法使用这两个远程计算机发送数据 stunserver。数据来自本地计算机,但远程计算机上的数据不会到来。

我正在使用我的程序 stunserver

0 投票
3 回答
897 浏览

java - 关闭连接后无法通过本地端口连接

我正在尝试按照本文http://www.brynosaurus.com/pub/net/p2pnat/中的描述对 NAT 的 TCP 打孔进行原型设计。

我有这段简单的代码,它试图在特定本地端口上打开与服务器的连接。我试图在公共服务器上观察 NAT 是否将两个连接都映射到同一个 NAT 映射。

第一次连接正常。但是第二次尝试它会引发异常:

选择用于打孔的本地端口:65416

2012-06-17 15:55:21,545 错误 - 地址已在使用中:连接

2012-06-17 15:55:25,175 调试 - 详细信息:java.net.BindException:地址已在使用中:在 java.net.PlainSocketImpl.socketConnect(Native Method) 处连接 ~[na:1.6.0_24] 在 java.net .PlainSocketImpl.doConnect(PlainSocketImpl.java:351) ~[na:1.6.0_24] at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:213) ~[na:1.6.0_24] at java.net.PlainSocketImpl.connect (PlainSocketImpl.java:200) ~[na:1.6.0_24] at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366) ~[na:1.6.0_24] at java.net.Socket.connect(Socket.java :529) ~[na:1.6.0_24] at java.net.Socket.connect(Socket.java:478) ~[na:1.6.0_24] at java.net.Socket.(Socket.java:375) ~[ na:1.6.0_24] 在 java.net.Socket.(Socket.java:249) ~[na:1.6.0_24]