关于 stun 服务器的困惑

2023-11-22

我的要求是,我将打开一个UDP服务器监听X端口(本地机器)和machine(public IP)可以发送UDP包给我。我的机器没有public IP。基本上我需要stun.

我正在测试stuntman服务器/客户端项目。我在服务器(公共IP)中运行stuntman-server。在我的系统中运行客户端(本地IP)。我要求映射 ip/端口9999 port.

./stunclient --mode full --protocol udp --localport 9999 stun.server.ip

Stun 服务器返回 IP 和端口。然后我做了什么,打开一个UDP服务器(使用java)在我的本地系统中并开始监听9999端口并发送UDP消息来自other machine (which has public IP) to mapped IP/port由 stun 服务器返回。但我无法接收任何数据。您可以假设我的服务器/客户端代码(用 java 编写)在本地网络中运行良好。

Flow:

My machine ->>>>>stun request for 9999 port and my ip ------> stun server
My machine <<<<<<<<<<<<<<<<<<mapped ip/port <<<<<<<<<<<<<<<  stun server
My machine : Run JAVA udp server socket in 9999 port

My machine  <<<<<<<<<<<<<<<<<<<UDP message to mapped ip/port<<<<<< other public machine 
            xxxxxxxxxxxxxxxxxxxNot workingxxxxxxxxxxxxxxxxxxxxxxxx

你没有公布你的结果stunclient运行,但我想它看起来像下面这样:

$ stunclient --mode full --localport 9999 stunserver.stunprotocol.org
Binding test: success
Local address: 192.168.1.8:9999
Mapped address: 1.2.3.4:9999
Behavior test: success
Nat behavior: Endpoint Independent Mapping
Filtering test: success
Nat filtering: Address and Port Dependent Filtering

我猜测您的行为测试是“端点独立”,过滤测试是“地址和端口相关”,因为这些是家庭中最常见的,并且大多与您上面描述的相匹配。 (又名“端口限制 NAT”)。

无论如何,这意味着您已经在自己和 STUN 服务器之间创建了端口映射。在上面的示例中,我的公共 IP 地址是 1.2.3.4。这是常见的,但并非总是如此,我的本地端口(9999)与公共端口相同。

在内部,您的 NAT 保留一个逻辑表,如下所示:

------------------------------------------------------------------------------------
||     LOCAL IP    | LOCAL PORT ||  EXT PORT    ||   REMOTE IP      | REMOTE PORT ||
||================================================================================||
||   192.168.1.8   | 9999       ||  9999        ||  107.23.150.92   | 3478        ||
------------------------------------------------------------------------------------

由于您从端口 9999 向 stun 服务器 (107.23.150.92) 发送了一个数据包,因此 NAT 会在其表中创建一个端口映射条目,持续几分钟。当数据包从 Internet 到达 NAT/路由器时,它会查阅该表。当响应从 STUN 服务器的 IP:端口返回时,NAT 能够根据上表中的“远程”字段将其转发到 NAT 后面的计算机。

但是您和您希望从中接收数据的“其他公共计算机”之间没有端口映射。假设另一台计算机的 IP 地址是 2.4.6.8,并且它正在尝试从其本地端口 8888 发送数据。NAT 表中仍然没有任何内容可以将流量从 2.4.6.8:8888 映射到后面的主机NAT。因此,当流量从不在表中的主机到达 NAT 时,NAT 只知道将数据包丢弃在地板上。有一种称为“Cone NAT”的 NAT 分类可以在其中发挥作用,但这些分类并不常见。

对于您的情况,有一个简单的解决方法。从 STUN 服务器获取端口映射后,从同一本地端口 (9999) 向要从中接收数据的远程主机(和远程端口)发送另一个数据报。远程主机可以简单地忽略此数据报,但它会有效地在 NAT 上创建另一个端口映射条目

------------------------------------------------------------------------------------
||     LOCAL IP    | LOCAL PORT ||  EXT PORT    ||   REMOTE IP      | REMOTE PORT ||
||================================================================================||
||   192.168.1.8   | 9999       ||  9999        ||  107.23.150.92   | 3478        ||
||   192.168.1.8   | 9999       ||  9999        ||  2.4.6.8         | 8888        ||
------------------------------------------------------------------------------------

发送到 2.4.6.8:8888 的简单 1 字节数据包允许 NAT 将流量从该地址转发回 NAT 后面的主机。

换句话说,使用您自己的网络流术语:

My machine:9999 ---->[STUN BINDING REQUEST]--->stun server:3478

My machine:9999 <----[STUN BINDING RESPONSE mapped IP:port]<--- stun server:3478

My machine:9999 [Open socket on port 9999]

My machine:9999 ---->[1 byte datagram] -------> 'other:8888'

My machine:9999 <---- [UDP to public IP:port obtained in step 2]<----'other:8888'

通常,在正常的 P2P 流程中,两个端点都与 STUN 服务器一起工作来发现其端口映射。然后使用另一个服务在彼此之间交换IP:端口信息。根据您的描述,您正在程序之间手动交换这些值,这对于测试来说很好。

如果另一台机器位于公共互联网上,从技术上讲,您不需要 STUN。第一台机器(在 NAT 后面)可以直接发送到远程 IP 和端口来表示“向我发送一些数据”。远程端只需检查该消息的对等地址和端口来决定发送回何处。端口映射已经创建。一些 RTSP 客户端假设服务器是公共的

我对套接字 NAT 遍历基础知识的回答是here.

我碰巧认识《STUNTMAN》的开发者。他是一个相当不错的人,英俊,而且非常聪明。他们还说我和他长得很像,而且我们名字的拼写也几乎相同。如果您对 STUN 和 NAT 穿越有疑问,可以直接给他发邮件。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

关于 stun 服务器的困惑 的相关文章

随机推荐

  • Xcode 项目的 Git 忽略文件

    我应该包含哪些文件 gitignore使用时Git和这个结合Xcode 我之前使用的是得票最高的答案 但它需要一些清理 所以这里针对 Xcode 4 进行了重做 并进行了一些改进 我研究过every文件在此列表中 但其中有几个在 Apple
  • 如何从 Firebase 只获取新数据而不获取现有数据?

    我在 Firebase 中有一个节点不断使用日志文件中的信息进行更新 该节点是lines 和每个孩子lines 是来自一个post 所以它有一个唯一的ID 当客户端第一次加载时 我希望能够获取最后一个X条目数 我希望我会这样做once 然而
  • C# 正则表达式用于删除混合有多种不同语言、unicode 字母的文本中的不可打印字符和控制字符

    我将不胜感激你的帮助 因为我不知道要使用哪个范围的字符 或者是否有像 cntrl 这样的字符类 我在 ruby 中找到了 通过不可打印 我的意思是在打印输入字符串时删除 ie 输出中未显示的所有字符 请注意 我寻找 C 正则表达式 我的代码
  • 角度中带有“this”关键字和没有“this”关键字的数据插值绑定行为?

    下面的代码是我的组件 Component selector my app template div name div export class MyApp name String constructor this name Mr Perfe
  • 使用 JavaScript 包装一组 DOM 元素

    我有一系列p我页面上的标签 我想将它们全部包装到一个容器中 例如 p foo p p bar p p baz p 我想将以上所有标签包装到一个容器中 如下所示 div p foo p p bar p p baz p div 如何包裹一个No
  • 如何在 MVC 下创建简洁且 RESTful 的向导?

    我尝试在构建应用程序时尽可能保持 RESTful 但我不确定的一件事是如何创建一个向导式工作流程 保持 RESTful 和简洁 以多页面注册流程为例 选项1 我可以为每个步骤创建一个控制器 并在用户到达该步骤 或返回该步骤 时调用 new
  • CakePHP 2.0 选择表单 多选

    我有一个下拉菜单 您可以在其中选择多个值 现在假设我想编辑我的信息并创建一个包含多个选定值的下拉菜单 试图弄清楚它是如何进行的 但没有结果 假设我有 selected array 3 4 options array 1 2 3 4 echo
  • 我的 powershell 脚本在预期输出之前打印“1”。为什么?

    我编写了一个简单的 powershell 脚本 用于检查 PSA 服务板上的门票数量 并输出门票数量和与其关联的颜色 但是 我的脚本在结果之前打印 1 我对 powershell 很陌生 我似乎找不到打印此内容的行 任何帮助 将不胜感激 谢
  • MVC5 帐户控制器空引用异常

    我正在尝试将用户角色实现到我的 MVC Web 应用程序中 但是我收到了一个空异常return userManager HttpContext GetOwinContext GetUserManager
  • 错误:无法加载要扩展的配置“下一个”

    我有一个使用 jest 和 react testing library 进行测试的 Nextjs 应用程序 我使用 npx eslintrc init 命令将 eslintrc 文件添加到我的项目中 每当我检查我的项目时 我都会收到以下错误
  • C# 和 VB.NET 中的转换之间的区别

    以下代码在 C 中运行良好 Int32 a b Int16 c a 0x7FFFFFFF b a 0xFFFF c Int16 b 但是这段代码崩溃并出现 OverflowExceptionVB NET Dim a b As Int32 D
  • 来自学习变量的预期张量流模型大小

    在训练用于图像分类任务的卷积神经网络时 我们通常希望我们的算法能够学习将给定图像转换为其正确标签的滤波器 和偏差 我有几个模型试图在模型大小 操作数量 准确性等方面进行比较 但是 从张量流输出的模型的大小 具体来说是模型 ckpt 数据存储
  • sql server 使用计算列

    我有一个这样的查询 select price1 price2 price3 as total price from prices 我如何使用计算列total price来计算其他总计 select price1 price2 price3
  • GoogleAppEngineLauncher 在哪里保存本地日志文件?

    GoogleAppEngineLauncher 可以在开发过程中在我的 Mac 上运行时显示我的应用程序的本地日志文件 但是 我无法更改那里的字体大小 所以我想使用tail命令自己查看日志文件 很遗憾 但我找不到日志文件 他们不在 var
  • 如何将角度项目设置为另一个角度项目的 package.json 中的依赖项

    我有三个不同的 Angular cli 项目 X Y Z 我想将 X 作为父项目 同时将 Y 和 Z 作为 npm 包依赖项添加到 X 这意味着 X package json 将包含 Y 和 Z 的依赖项 如下所示 dependencies
  • Row_Number 超过 其中 RowNumber 介于

    我尝试使用 row number 从表中选择某些行 但是sql会提示错误msg Invalid column name ROWNUMBERS 有人可以纠正我吗 SELECT ROW NUMBER OVER ORDER BY Price AS
  • SQL:如何在 orderby 中将 null 和空条目排序到前面?

    如果我的数据库中有以下条目 ID Name1 空 2 空字符串 3 阿尔法4 布拉沃5 查理 那么使用 ORDER BY 时如何将有名称的行排序到前面 如果我使用 ORDER BY Name 我会得到上面的列表 但我实际上想要 3 Alph
  • 解析注释行

    鉴于以下基本语法 我想了解如何处理注释行 缺少的是处理
  • 重定向后从 XHR 对象获取最终 url

    假设我使用 ajax 例如通过 jQuery 对实现 PRG 模式的 API 执行 POST 请求 因此它会重定向我 POST some api HTTP 1 1 303 See Other Location some other loca
  • 关于 stun 服务器的困惑

    我的要求是 我将打开一个UDP服务器监听X端口 本地机器 和machine public IP 可以发送UDP包给我 我的机器没有public IP 基本上我需要stun 我正在测试stuntman服务器 客户端项目 我在服务器 公共IP