问题标签 [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 投票
1 回答
1869 浏览

java - UDP 打孔 (Java)

几个星期以来,我一直在尝试创建一个套接字聊天/文件传输应用程序。我花了几个小时在互联网上搜索一段关于 UDP 打孔的代码,但我还没有找到任何可行的或足够简单的东西供我使用。

我试图让路由器(NAT)后面的两个客户端相互连接。我设法设置了一个共享两个客户端 IP 和端口的服务器,但我还没有设法真正启动连接。我可以在任何地方使用任何源代码吗?

我找到了几个像 JStun 这样的 STUN/ICE/TURN 库,但是没有关于如何使用它们的文档。我需要 STUN 服务器来启动连接吗?我可以使用像 numb.viagenie.ca 或http://www.stunserver.org/这样的公共的吗?

任何答案将不胜感激。谢谢!

编辑:我有更多的探索,我发现即使通过 PHP 也很容易制作 STUN。我已经建立了自己的 PHP stun,它只共享两个客户端数据。困难的部分是连接两个客户端,但这使用了一种叫做 ICE 的东西。感谢在评论中发布内容的 selbie 。这让我在 ICE 上走上了正轨。如果有人提出其他问题,我会将这个问题留待更长时间。我将开始编写我自己的 ICE 代码,或者尝试在网上寻找一些东西。谢谢!

0 投票
0 回答
1350 浏览

java - Determinate NAT type and port prediction on symmetric NAT

first thing sorry for my bad English but it is not my first language. My question is this: I'm working for realize a simple software for desktop sharing, using Java. The first problem is how can communicate two client that are behind NAT. After some research on Internet, I found that one of the better solution is to use the technique of UDP hole punching. If I correctly understood, this function works in the following way:

A = client1

NA = nat of client 1

B = client 2

NB = nat of client 2

S = public server

1 - A sends a UDP packet to S

2 - S receives the public IP and the public port of NA

3 - B sends a UDP packet to S

4 - S receives the public IP and the public port of NB

5 - S sends a UDP packet to A with the public ip and port of B through the binded socket that received the first packet from A

6 - S sends a UDP packet to B with the public ip and port of A through the binded socket that received the first packet from B

7 - A sends a UDP packet to B with the specifics received from S, NB drop this packet since it doesn't know who is A (it hasn't a route for this packet). But this open a hole in the NA that can accept and inoltrate to A a packet that arrives from B.

8 - B send a UDP packet to A, NA can inoltrate the packet.

I understood that this method will work only with 3 of the 4 NAT types: full cone NAT, restricted cone NAT, restricted port NAT, but not with Symmetric NUT. Now, I realized a little software that should simulate the UDP hole punching, and this is the code (I know it is not elegant, but now I want just see if the procedure works):

Client:

Server:

With this code I can contact the server with both clients, server receives the packets from both clients, server send to A the information of B and to B the information of A, both clients receive the information, but they can't communicate together. A doesn't receive the packet from B and B doesn't receive the packet from A. So now I need to understand if I'm behind symmetric nat with both clients. If I understood the other types of NAT (full cone, restricted cone, and port restricted cone), they use always the same port for each external connection. So if for example I have and internal pc with the IP: 192.168.0.50 and this machine wants reach a public ip (for example 54.66.18.22) NAT will assign at the packet the public IP and an external port (for example the port 58000). Later if the same pc (192.168.0.50) wants to connect with another external host, NAT always use the same external port 58000. Instead with a symmetric NAT every connection will have a different external port (first connection port 58000 and the second connection with different port). Now if this is correct I think that the both clients are behind two Symmetric NAT. I can determinate this because from client A when I connect to the server I see that server receive the public IP of NAT A and a port for example 55000. If I close the client and run it again, this time I see that the server receives always the same IP (obviously) but the port is not 55000 but 55001 and if I try again the port is 55002 and so on. And the same thing is with the second client, the port is increment by 1 from a connection to the other. Now, always if I'm understanding the whole scenario, this should confirm me that the both clients are behind symmetric NAT. But the interesting thing is that it seems that the both NATs use an increment of one unit so I thought that I could use a port prediction when I send a packet from A to B and from B to A, so I simply tried this:

I added 1 to the port that I receive from the server because if is true that I'm behind two symmetric NAT, is also true the the increment is of 1 port. Check with an example:

A connect to the server and NAT A send to S this a packet containing: 45.89.66.125:58000

B connect to the server and NAT B send to S this a packet containing: 144.85.1.18:45000

S send the information of B to A and the information of A to B

Now if A send to B this information, the NAT A will create this map:

INTERNAL_IP_A:58001-144.85.1.18:45001

For this connection NAT A should use the port 58001 (last port + 1 it is a symmetric NAT)

NAT B receive the packet but discard it.

Now if B send a packet to A with the information received the NAT B will create this map:

INTERNAL_IP_B:45001-45.89.66.125:58001

Now NAT should accept this packet since in its table there is the information to accept it.

But also in this case none of the client receive the information from the other. What am I doing wrong? Or what I haven't understood?

0 投票
1 回答
13857 浏览

sockets - 如何进行 TCP 打孔?

问题如下。这是我当前没有成功的测试代码。


如何进行 TCP 打孔?我正在使用远程服务器进行测试。我在跑步wget local_public_ip:port/test。我的路由器设置为端口 80,因此不需要打孔。我的代码建立了联系。现在我尝试其他端口,但我无法完全弄清楚如何打孔。

我所做的是(C#代码)

我想也许我需要在 out tcp 连接上设置本地端点。

我犯了一个错误,得到了这个例外

修复字节数组192,168,1,5似乎可以使传出连接正确。现在我已经使用我的侦听端口与远程 IP 建立了连接,我认为 wget 将能够连接到我。事实并非如此

如何进行 TCP 打孔?

0 投票
3 回答
16112 浏览

java - UDP打孔Java示例

我想在具有静态 IP 的服务器的帮助下对两个客户端进行 UDP 打孔。服务器在端口 7070 和 7071 上等待两个客户端。之后,它将 IP 地址和端口发送给对方。这部分工作正常。但我无法在两个客户端之间建立通信。我在不同的 Wifi 网络和 3G 移动网络中尝试了代码。客户端程序抛出 IO-Exception “No route to host”。客户端代码用于两个客户端。使用端口 7070 执行一次,使用 7071 执行一次。

你认为我正确地实现了 UDP 打孔概念吗?有什么想法让它发挥作用吗?首先是服务器代码,然后是客户端代码。

谢谢你的帮助。

服务器代码:

客户代码

更新 代码通常可以正常工作。我现在已经在两个不同的家庭网络中尝试过它并且它正在工作。但它不适用于我的 3G 或大学网络。在 3G 中,我验证了 NAT 将两个端口(客户端端口和路由器分配的端口)再次映射在一起,即使在关闭和打开 clientSocket 之后也是如此。有谁知道为什么它不工作?

0 投票
1 回答
5236 浏览

java - TCP 打孔 Java 示例

我在本地机器上使用以下代码:

但它给了我一个 JVM 绑定异常。

我已从以下链接下载此代码: http ://ramonli.blogspot.in/2012/03/tcp-hole-punching-how-to-establish-tcp.html

从理论上讲,它应该可以正常工作并且不会引发任何异常。因此,它应该是 Java 中 TCP 打孔的模板。

我做错了什么?

0 投票
1 回答
843 浏览

java - UDP打孔无法外接

我之前使用 UDP 打孔制作了一个简单的点对点聊天程序,现在我正在尝试做类似的事情,但在使用 libGDX 制作的游戏中。游戏本身运行良好,连接在 LAN 上工作,但我很难尝试使用外部连接。我了解 UDP 打孔的工作原理如下:

如果 A 和 B 都知道对方的 IP 地址和端口,则:

  1. A 向 B 发送一个 UDP 数据包,该数据包在 A 的 NAT 上打了一个洞,但被 B 的防火墙丢弃
  2. A 等待回复
  3. B 向 A 发送一个 UDP 数据包,该数据包在其自己的 NAT 上打了一个洞并通过 A 的防火墙
  4. B 等待回复
  5. A 接收 B 的初始消息并发送第二个消息给 B
  6. B收到A的消息

我的网络代码属于一类:

0 投票
1 回答
588 浏览

tcp - udp打孔后发送文件

我在 NAT 后面有 2 台计算机。

为了在它们之间建立连接,我使用了 UDP 打孔协议。

有用。

现在我想通过这个隧道发送文件。我想我必须在这两台计算机之间建立一个 TCP 隧道。

两个防火墙都拒绝所有 TCP 流量。

可能吗 ?

如果没有,还有其他解决方案吗?Skype 如何通过此 UDP 隧道发送文件?

0 投票
1 回答
266 浏览

ruby - 在 Ruby 中将 UDP 套接字绑定到通配符主机

我一直在尝试理解 UDP 打孔背后的基本思想,但我无法理解以下两个套接字绑定之间的区别:

以前我曾认为使用 '' 或 '0.0.0.0' 会做同样的事情——允许套接字在任何网络接口上监听——但由于代码不能与它们互换,所以我一定遗漏了一些东西。

对于初始“punch”,数据报从绑定到“”的套接字发送,然后关闭该套接字,与远程主机的实际通信通过绑定到 0.0.0.0 的套接字完成。我知道 0.0.0.0 通常是指默认路由,但在这种情况下我无法弄清楚它的意义。将套接字绑定到 0.0.0.0 是否意味着您正在为其分配默认网关的地址?

0 投票
1 回答
2349 浏览

networking - 是否有针对 udp 打孔的安全措施?

我想在两个对等方之间建立 UDP 通信,比如 Alice 和 Bob。Alice 位于端口受限的锥形 NAT 后面(这样即使目的地改变了,相同的内部端口也会映射到相同的外部端口),而 Bob 位于对称 NAT 之后(这意味着每次新的外部端口都会改变)目的地的选择与内部端口无关,因此使外部端口不可预测)。我在两者之间有一个服务器,我想打一个 UDP 打孔。

我实施了以下策略:

  • Bob 打开大量端口,并从所有端口向 Alice 的外部端口发送一个数据包(他知道是否通过服务器)。
  • Alice 在随机端口向 Bob 的 NAT 发送数据包,直到建立连接。

手头有两个这种类型的 NAT,我做了一些实验。Bob 开放 32 个端口,Alice 每 0.1 秒发送 64 个数据包。连接通常在 1 或 2 秒内建立,这非常适合我的需求。

但是,我想知道我是否会遇到一些严格的 NAT 路由器或防火墙的问题。例如,路由器不允许内部对等方打开 32 个端口是否会发生?或者(这听起来更有可能)是否会发生这样的情况:路由器看到大量从随机端口传入的数据包被丢弃,会将 IP 列入黑名单并丢弃其所有数据包一段时间?我读到有时这可能发生在 DoS 攻击的情况下,但我的数据包速率比 DoS 攻击轻 4 到 6 个数量级。

我问的是合理的网络配置:我很确定原则上可以设置防火墙以这种方式运行。我将主要针对位于标准家庭连接之后的用户,因此我的主要目标是使用 NAT 的普通互联网提供商。

0 投票
1 回答
191 浏览

java - 打孔后未建立 TCP 连接

因此,我正在尝试在两个移动设备(Android 手机和带有 USB 移动宽带调制解调器的笔记本电脑)之间实现 TCP 打孔。我使用另一台连接到 wifi 的笔记本电脑作为服务器。

我首先让笔记本电脑连接到显示其公共 IP 地址和服务器看到的 NAT 端口号的服务器。

手机做同样的事情,所以我看到它是公共 IP 和 NAT 的端口号。笔记本电脑和手机都关闭了与服务器的连接。

然后,笔记本电脑使用相同的本地 IP 和端口号(用于连接服务器)并使用移动设备的公共 IP 和经过 NAT 的端口号连接到移动设备。

而且由于手机在nat后面,连接超时,我得到一个异常。

最后,我尝试再次连接到手机。当笔记本电脑尝试连接到手机时,我也从手机发起连接。使用相同的 IP 和端口(用于连接服务器的手机),我连接到笔记本电脑的公共 IP 和端口。

但是移动和笔记本电脑都尝试连接只是超时。

我不仅尝试第二次从笔记本电脑连接到手机,还尝试让笔记本电脑监听连接:

但这也不起作用。我不知道为什么。有没有办法让我测试我的移动提供商的 NAT 是否甚至允许打孔?

这是我从手机连接的方式:

我今天大部分时间都在试图解决这个问题。在笔记本电脑上使用 serversocket 时,移动设备上的错误是超时。昨晚(凌晨 1 点)它随机工作了一次,我就去睡觉了。今天又不上班了。不知道为什么不。任何帮助,将不胜感激。

编辑:

好的,现在在笔记本电脑尝试连接到移动设备并失败(然后不断尝试连接到移动设备而不是服务器套接字场景)之后,移动设备尝试连接到笔记本电脑并通过。如果我删除这些行: BufferedReader inFromClient = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); receivedMessage = inFromClient.readLine(); 然后手机说它已连接。如果我留下线路,移动设备会收到对等方重置连接的错误。

但是,无论哪种情况,笔记本电脑似乎都没有响应。如果我使用服务器套接字替代方案而不是尝试从笔记本电脑进行连接,则由于连接超时,移动设备尝试连接失败。