Networking STUN下NAT下服务器/客户端通信的UDP打孔 问题

Networking STUN下NAT下服务器/客户端通信的UDP打孔 问题,networking,udp,nat,stun,hole-punching,Networking,Udp,Nat,Stun,Hole Punching,我正在尝试开发一个通信系统,其中: A、 B是NAT下的机器,A是服务器,B是客户端 S是STUN服务器 S正在可通过Internet访问的计算机上运行 流程如下: A hits S with an opcode saying he's the server S registers A as server B hits S with an opcode saying he's the client S sends to A B's external infos (IP, PORT) S sen

我正在尝试开发一个通信系统,其中:

A、 B是NAT下的机器,A是服务器,B是客户端 S是STUN服务器

S正在可通过Internet访问的计算机上运行

流程如下:

A hits S with an opcode saying he's the server
S registers A as server

B hits S with an opcode saying he's the client
S sends to A B's external infos (IP, PORT)
S sends to B A's external infos (IP, PORT)

A starts sending B an opcode saying he's the server every 500ms
and meanwhile listens for packets saying he's got a client

B starts sending A an opcode saying he's the client every 500ms
and meanwhile listen for packets saying he's got the server

麻烦 问题就从这里开始,STUN服务器完成了它的工作,因为两端都接收到关于另一端的正确信息

但是我从来没有收到对方的信息,所以双方都在听,没有收到握手操作码或其他任何东西

纳特的行为 我确实检查过这个NAT的行为,看起来是这样的

A位于192.168.X.X,端口4444 连接到外部暴露N.N.N:4444 因此,只要端口号是空闲的,就会保留它,如果不可用,就会获得一个新的(随机的?)端口号

测验 我运行的测试已经看到了托管在同一台机器上的两端(A,B),都绑定到机器的内部IP,试图绑定到127.0.0.1,0.0.0.0,没有任何更改

如果在他们听握手时,我用
nc
localhost
回音
某个东西,它会被接收并显示(作为未识别的消息),没有任何问题。通过NAT路由的连接并不困难,每个数据包都被丢弃

还尝试了在机器上托管A,在Android手机上的移动数据下托管B,并使用一个简单的临时编写的应用程序。仍然会锁定等待的内容,比如nodejs测试


更新: 我尝试做的另一件事是用
nc

在同一NAT下运行的两台不同机器上:

echo“问候陌生人”| nc-u 4567-p 4568

echo“问候陌生人”| nc-u 4568-p 4567

每台机器的时间不同。根据我的理解,这应该在NAT中打一个洞,第一个包被丢弃,随后被转发。但是什么也没发生,没有人得到消息

我也试过:

从本地计算机
echo“问候陌生人”| nc-u 4567-p 4568

从公共机器
echo“问候陌生人”| nc-u 4568-p 4567

这样,NAT下的本地机器与公共机器联系,在第一个丢弃的数据包能够在指定的端口上接收和发送之后。我想知道为什么在同一个NAT下的两台机器上都不起作用(???)


代码 我没有显示任何代码,因为我认为这里面有某种逻辑缺陷,不过这里有一个项目

index.js
包含STUN服务器,tests文件夹包含测试用例:
test.js
启动STUN服务器,
PeerClientTest.js
PeerServerTest.js
是客户端和服务器的实体模型

运行
node tests/test.js
在公用计算机上启动服务器(在
config.js
tests/config.js
中更改IP)

然后
节点测试/PeerServerTest.js
启动服务器(“A”)和
节点测试/PeerClientTest.js
启动客户端(“B”)。双方都将通过STUN相互识别,然后在发送自己的握手操作码的同时监听对方的握手操作码。这种情况从未发生过,所以他们一直在发送/收听


节点不是必需的,所以如果有其他语言的更好的解决方案,请告诉我,我们将不胜感激。

B的NAT正在过滤A的数据包,不让它们通过。NAT过滤发送给它的未知数据包。您的服务器A正在向客户端B发送数据包。但是客户端B以前从未通过NAT向A发送数据包。因此,到B的NAT A的数据包是未知的,将被丢弃

您需要在B的NAT上打一个洞,以便NAT允许传入的数据包。从B向NAT的IP:端口发送数据包。之后,当您从a向B发送数据包时,B的NAT不会丢弃a的数据包


如果A和B的NAT具有类似对称和对称/PRC NAT的组合,这将不起作用。在这种情况下,您必须使用转向中继服务器。

实际上我是这样做的。。在A和B联系S后,他们接收到另一端的地址(NAT IP,端口),双方开始互相发送数据包并监听传入的响应,这意味着漏洞已经打开。这种情况从未发生过,他们在发送/等待响应时陷入困境。B的NAT类型是什么?您写道“A位于192.168.X.X,在端口4444上连接到外部,暴露了N.N.N.N:4444,因此只要端口号是空闲的,它就会一直保留”。你能用B来验证一下吗。你需要知道当B向a发送数据包时,B从服务器S获得的公共端口是否保持不变。看看这是否是你的情况……在我运行的测试中,a和B都托管在同一台机器上,所以相同的NAT,相同的外部甚至内部IP,只是不同的端口。在两个不同的网络下尝试此配置,使用不同的路由器和ISP。还尝试在我的机器上使用A,在Android上的移动数据下使用B。相同的结果。对于相同的网络,您不需要使用NAT。但是对于不同的NAT,您需要知道两端的NAT类型。每个NAT都有不同的行为,对于NAT遍历来说,这些信息是必不可少的。不知道我们什么都说不准。