将套接字连接到同一 NAT 中的另一台 PC

将套接字连接到同一 NAT 中的另一台 PC

嘿,我在同一个网络上有两台机器。它们从外部网络服务器获取 IP 信息。由于 NAT,IP 相同,但本地端口不同。嗯,这很奇怪……它们无法连接,甚至无法互相看到。示例:

Microsoft Telnet> open 1.129.108.250 16054
Connecting To 1.129.108.250...Could not open connection to the host, on port 16054: Connect failed

C:\Users\Andrew>ping 1.129.108.250

Pinging 1.129.108.250 with 32 bytes of data:
Request timed out.
Request timed out.
Request timed out.
Request timed out.
    
Ping statistics for 1.129.108.250:
    Packets: Sent = 4, Received = 0, Lost = 4 (100% loss)

我不知道。由于 NAT,是否有类似“外部端口”需要担心?我的意思是,我在端口 10000 上启动侦听器,对其他人来说它仍然是 10000 吗?即使如此,为什么他们无法 ping 通?他们都在我的卧室里,在同一个网络上。谢谢

编辑:

为了更好地解释这一点,两台机器都从我的 Web 服务器获取外部 IP 地址,每台机器的 IP 地址都是 1.129.108.250。因此端口会有所不同。但它们似乎并不认为彼此在同一个网络上,除非它们在我的 WiFi 上运行。它们是通过移动设备热点连接的,好像这有什么区别似的。另外,如果它们选择同一个端口进行监听会发生什么?NAT 会崩溃或发生故障吗?

编辑2:

实际中有多少种组合?

PC1 in NAT      PC2 in NAT  (same network)
PC1 in NAT      PC2 in NAT  (different networks)
PC1 not in NAT  PC2 in NAT  (different networks)

有人说外部网络不需要特殊逻辑?因为路由器会注意让一切看起来正常。我猜这是 user1686 的意思。

如果 1.2.3.4:1000 实际上映射到 192.168.0.1:10000 那么它的行为就必须像一个真实端点一样。

答案1

他们从外部网络服务器获取 IP 信息。由于 NAT,IP 相同,但本地端口不同。

港口Web 服务器报告的端口号意义不大。每个新的 TCP 连接都会由客户端分配一个全新的本地端口 - 即使是从没有任何 NAT 的单台机器,每次您按 F5 时,Web 服务器都会看到不同的端口。(有些 NAT 会保留端口,有些 NAT 会始终转换端口。)

嗯,这很奇怪……他们无法连接,甚至无法互相看到。示例:

这不是一个“监听”端口——它不接受新连接;它只是被分配为特定出站连接,您就无法telnet进入(即使 NAT 不是问题)。

即使如此,为什么他们无法 ping 通?

地址网络服务器报告的 IP 地址不属于您的任何计算机。在 NAT 之后,“外部”IP 地址属于仅有的到执行 NAT 的路由器(通常是你的路由器,但如果是 CGNAT,则是 ISP 的路由器)。因此,当你 ping 你的外部 IP 地址时,你总是仅 ping 路由器 – 而不 ping 其后面的任何机器。

大多数“家用”路由器都配置为忽略所有对其外部地址的 ping 请求。

另外,如果他们选择同一个端口进行监听会发生什么?NAT 会崩溃或发生故障吗?

不会,NAT 只会重写端口以避免冲突。(所有“1:多”NAT 都必须跟踪每个连接才能取消对入站响应的 NAT;同一状态表会告诉它们是否有另一个连接使用此本地端口。)

一些 NAT 总是会为每个连接重写源端口,即使没有冲突。

它通过移动设备热点,好像这有什么区别

确实如此。手机很可能对其热点和网络共享应用了“客户端隔离”功能——如果是这样的话,连接到同一热点的两台设备即使使用它们的“私有”IP 地址也无法相互联系,尽管一切看起来都应该可以。(我的 Android 手机似乎没有隔离 Wi-Fi 热点客户端,但它确实在 Wi-Fi 和 USB 网络共享之间设置了一堵墙。)

实际中有多少种组合?

许多。主机可能位于本地 NAT 后面,也可能位于本地 NAT(或三个!),或位于 ISP 管理的 CGNAT 之后,或位于两个本地 NAT 之后CGNAT。(或者当然根本没有 NAT。)

每个 NAT 层都可以是“锥形 NAT”或“对称”——除了奇怪的名称之外,一个分配所有远程端点都可以使用的映射,另一个则不分配。(在对等情况下,自动打洞在许多情况下是可能的,但当两个对等点都位于对称型 NAT 之后时则不可能。)

请参阅 Tailscale 的文章NAT 穿越的工作原理仅查看一些可能性。

难道说网络之外的任何人都不需要特殊的逻辑吗?

只有当你的连接严格来自内部时外部(例如浏览器与公共 Web 服务器建立 HTTP 连接)。

我的应用程序可以监听 1.2.3.4:10000,但如果 NAT 将其更改为 33.62.123.0:12345,我如何知道真正的端点是什么?我可以通过询问我的网站来获取 IP。但如何找出我实际监听的端口?

你不是。不是您分配的任何外部端口。出站连接将获得暂时的每当 NAT 路由器看到数据包通过时就会分配 NAT 映射(并且它只持续与该连接一样长);对于监听套接字,除非有人手动添加映射,否则不会有任何映射。

如果你很幸运,最近的 NAT 可能会接受 NAT-PMP(现在是 PCP)或 UPnP IGD 请求,以建立允许入站连接的持久映射;这在 BitTorrent 客户端中很常见。你告诉路由器你的侦听器的本地地址:端口,路由器的响应将具有外部地址已分配的端口。

如果没有...那么您就进入了“NAT 穿越”领域。

NAT 似乎非常麻烦。我可以连续几天谈论 TCP 的设计有多糟糕。

“幸运的是”,NAT 实际上并不是 TCP 的一部分。它只是二十年前在 TCP/IP 之上临时加装的“临时创可贴”,从那以后我们就一直在使用它。

答案2

简短的回答...

NAT 用于将多台计算机聚合到单个网络连接中,使它们在外部网络上显示为一台计算机。在此过程中,NAT 将内部的 internal-ip:port 地址重写为临时的唯一 external-ip:port 地址。因此,内部和外部端口不相关,并且来自外部网络的传入连接通常会被阻止。

如果您在内部机器上启动监听器,外部机器将无法通过 NAT 连接到该机器,除非您已专门配置 NAT 以永久映射端口并将外部流量传递到该机器上的该端口。

如果您希望内部网络上的两台机器相互通信,则它们必须使用其内部唯一的 IP 地址,而不是共享的外部 IP 地址。

答案3

谢谢大家。看来我需要做这样的事情:

https://www.codeproject.com/Articles/18492/STUN-Client

另外,我要编写自己的 STUN 服务,因为我不想依赖另一个可能随时瘫痪的服务器。

相关内容