为什么我无法使用我的 public IP 连接到我的服务器?

Why can't I connect to my server using my public IP?

我有一个服务器程序和一个客户端程序。在开发程序时,为了方便,我 运行 服务器和客户端在同一台机器上。服务器使用这些行开始侦听传入连接:

var listener = new TcpListener(IPAddress.Any, 7070);
listener.Start();

客户端使用这些行(简化)连接到服务器:

var client = new TcpClient(AddressFamily.InterNetwork);
client.Connect(IPAddress.Loopback, 7070);

我使用 IPAddress.Loopback 因为我 运行 程序在同一台机器上。但是,知道服务器和客户端将来不一定 运行 在同一台机器上,我将它从 http://icanhazip.com 更改为我的 public IP (IPAddress.Parse(...) ).因此,客户端无法连接到同一台机器上的服务器,异常 No connection could be made because the target machine actively refused it <my public ip:7070>.

我尝试禁用我的防火墙,但它仍然无法正常工作。为什么服务器拒绝连接?我不是特别告诉它用 IPAddress.Any 监听 all 接口吗?

为什么会发生这种情况,我该如何解决?

这是根据我对问题的评论得出的答案,希望是正确的:

您的 public IP 由您的 ISP 提供,实际上是您路由器的地址。路由器为本地网络中计算机的传出连接执行网络地址转换 (NAT)。这些请求在 Internet 上看起来就像它们都来自一个 IP,并且您的路由器会根据地址转换 table 将响应发送到正确的本地计算机。这适用于传出连接,但不适用于传入连接。

如果有东西试图打开从 Internet 到您的路由器的 TCP 连接,路由器不知道它可能试图连接到哪台本地计算机,除非您专门将其配置为将该流量转发到您的特定计算机本地网络。这就是端口转发的用武之地。如果您没有配置端口转发,路由器只会说,"sorry, I'm not handling incoming requests on port 7070."

你的开发机器在路由器后面吗?

通过您的 public IP 地址发送给您的网络流量通过特定网络协议在给定端口上到达您的路由器。您的路由器需要知道在网络内部将此流量发送到何处。流量来自 Internet 到您的计算机,您的路由器不能或不会将流量转发到您的计算机。

由于网络地址转换 (NAT) 和通用即插即用 (UPnP) 的强大功能,您在 day-to-day 生活中不会注意到这一点。忽略此处的一些细节,网络地址转换允许修改流量 headers 以将流量从您的 public IP 路由到网络上您实际机器的 IP。当传入流量尝试打开网络连接端口时,路由器需要配置为适当地转发该流量。通用即插即用协议是许多现代路由器支持的协议,允许软件和设备无缝路由流量而无需转发端口。

这给您留下了两个选择:

  1. 出于开发目的,访问您的路由器并将所需的端口转发到您的开发计算机

  2. 为了更健壮的应用程序,特别是如果你要在不同的机器或不同的网络上 运行 这个,考虑在你的应用程序中添加 UPnP support 同时理解某些用户可能不支持或启用 UPnP,在这种情况下仍然需要端口转发。