C ++套接字:PC之间通过互联网进行通信

C++ sockets: communication between PCs over internet

我正在 Windows 上使用可以将消息发送到另一台计算机的 winsocks 编写程序。客户端与另一台计算机中的服务器连接并开始交换数据。

它在我使用本地地址 (192.168.1.*) 的本地网络上工作正常,但我无法与 public 地址 (216.185.45.129) 通信;甚至不是我自己的。我可以成功连接到端口 80 上的网站,但不能使用它的 public IP 地址连接到我家里的笔记本电脑,无论我使用什么端口(未保留端口)。

所以我在网上做了研究,唯一可行的解​​决方案似乎是端口转发。

-但绝对没有其他方法可以做到这一点吗?

-那么Teamviewer等其他程序如何连接到网络上的其他计算机?

-是否有我可以使用的已经打开但通常未使用的端口?

-至少,我可以转发 my 路由器上的端口,但 让客户端做任何事情吗?或者让我的程序自动转发端口。

主要问题是,每个路由器都使用 NAT 来区分您本地网络中的不同计算机与 WAN。他需要这样做,因为你在互联网上只有一个 IP,但你家里有好几台设备。为了存档,他使用端口组。这意味着,如果您过去常常使用两台设备从端口 2048 发送到 Internet 中的网络服务器,则路由器会为一台设备提供另一个端口(如 2049)。响应具有请求者的端口,因此路由器可以将其映射回来。不幸的是,大多数路由器总是映射端口,因此您现在永远无法从互联网端获得哪个端口。

有两种常见的方法可以解决和实现您的目标。

  1. Port Fowarding

您可以强制大多数路由器不映射特殊端口,而是将它们绑定到唯一的 MAC 地址。您可以使用 UPNP 来配置大多数路由器来执行此操作,但出于安全原因我不建议这样做,而且它在路由器不允许 UPNP 操作的许多环境中也不起作用。 出于游戏原因,大多数路由器都具有端口转发功能(主要用于 P2P 网络) 它适用于 TCP 和 UDP。

  1. NAT Traversal

常见的方式是NAT穿越,也叫NAT打洞。我将简称为UDP。您可以在此处找到维基解释 here for TCP and for UDP。不幸的是,您需要一个两个客户端都可以访问的互联网服务器。这里的步骤:

  1. 两个客户端都联系了服务器。服务器现在知道两个客户端的 IP 和端口。
  2. 服务器将信息返回给客户端。
  3. 两个(!)客户端现在在已知地址上互相发送包裹。

两个客户端都必须发送一个 UDP 包并且必须接受第一个包丢失。原因是路由器。如果客户端之前已将包发送到该源,则大多数路由器只接受来自映射端口上源的包。

更新 关于 Remy Lebau 的评论,我将 Firewall piercing 部分更改为 NAT Traversal,因为它有一部分是错误的。