当前位置: 首页 > 知识库问答 >
问题:

利用STUN在NAT下对服务器/客户端通信进行UDP打孔

高修筠
2023-03-14

我正在开发一个通讯系统:

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,B)托管在同一台机器上,都绑定到机器的内部IP,尝试绑定到127.0.0.1、0.0.0.0,没有任何改变。

如果他们在监听握手时,将带有nc的东西echo发送到localhost时,它会被接收并显示(作为无法识别的消息),不会有任何问题。通过NAT路由的连接并不困难,每个数据包都被丢弃。

也试过在机器上托管A,在移动数据下的Android手机上托管B,用一个特别编写的简单应用程序。仍然锁定等待某些东西,如nodejs测试。

更新:我尝试做的另一件事是用nc打开一个洞

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

echo“问候未知对等体”NC-U 4567-P 4568

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

我也试过:

从本地计算机回显“greet UNKOWN peer”nc-u 4567-p 4568

从公用计算机echo“greet UNKOWN peer”NC-U 4568-P 4567

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

我没有显示任何代码,因为我认为这里面存在某种逻辑缺陷,但是这里有一个github项目。

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

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

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

节点是不需要的,所以如果有更好的解决方案,在其他语言只是告诉,将是赞赏的。

共有1个答案

璩俊雅
2023-03-14

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具有对称NAT和对称/PRC NAT这样的组合,这将不起作用。在这种情况下,您将不得不使用TURN relay服务器。

 类似资料:
  • 我尝试使用Spring Integration实现UDP服务器,就像这里描述的那样,但是当客户端在NAT之后运行时,它们将永远不会收到来自服务器的响应。这是因为服务器应该从与UDP适配器端口相同的端口发送响应数据报(通过这里解释的NAT检查UDP)。 如何使用Spring Integration实现与NAT后客户端的正确UDP通信?

  • 本文向大家介绍java UDP通信客户端与服务器端实例分析,包括了java UDP通信客户端与服务器端实例分析的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了java UDP通信客户端与服务器端。分享给大家供大家参考,具体如下: 最初Udp是以字节为单位进行传输的,所以有很大的限制 服务器端: 用户端: 注:由于必须以字节为单位进行传输,Udp的传输用了一个容器类的东西,用来接收字节 先建

  • 本文向大家介绍C#利用服务器实现客户端之间通信,包括了C#利用服务器实现客户端之间通信的使用技巧和注意事项,需要的朋友参考一下 先来讲述下我自己对于整个Socket通信过程的理解,毕竟初学,说错见谅,知道错了会改正~  首先在服务端新建一个serverSocket,对其进行初始化(一般包含AddressFamily:IP地址类型,SocketType:Socket传输数据方式,ProtoType:

  • 我对使用UDP协议的服务器和客户端之间的通信有一个非常奇怪的问题。客户端是用Mono2x编写的(我使用Unity 3D作为我的客户端)并创建Udp客户端类实例: 我的服务器是 UWP 应用程序,我想在使用 DatagramSocket 的 Raspberry Pi 上运行: 我将数据从客户端发送到服务器,但运气不佳。我用TCPView检查了数据是从我的客户端应用程序发送的,但从未到达服务器。现在是

  • 我正在尝试使用UDP在服务器(在公共IP上)和客户端(通过NAT)之间进行双向通信。我的逻辑是,如果服务器向IP和它接收数据包的端口发送一些数据,客户端仍然应该得到它,因为NAT最终会有将数据包发送到客户端的映射。 客户端有 2 个进程,一个用于发送数据包,另一个进程用于接收数据。服务器继续等待数据,如果它获得数据,它会将数据发送回从接收数据的端口和 IP。 客户代码如下: client_recv

  • 本文向大家介绍Java使用UDP的基本客户端/服务器通信(数据报),包括了Java使用UDP的基本客户端/服务器通信(数据报)的使用技巧和注意事项,需要的朋友参考一下 示例 客户端程序 在这种情况下,我们通过参数(args[0])传入服务器的地址。我们使用的端口是4160。 服务器.java 在服务器端,在我们将消息发送到的同一端口上声明一个DatagramSocket(4160),然后等待响应。