在没有公共 IP 的情况下通过 http 连接两台计算机

Posted

技术标签:

【中文标题】在没有公共 IP 的情况下通过 http 连接两台计算机【英文标题】:Connect two computer over http without public IP 【发布时间】:2011-05-12 22:05:54 【问题描述】:

我希望计算机/客户端在其中一个或两个没有公共 IP 的情况下直接相互连接。我想这可以通过服务器作为中间人来完成。最终建立的连接必须是客户端之间的直接流量。这怎么可能,技术叫什么?

我真的很想看看 Java 中的一些代码 fx。

谢谢

【问题讨论】:

【参考方案1】:

如果端口转发不是一个选项,有一种最可靠的技术可以用于 UDP 流量,称为NAT traversal。它需要一个中间人服务器充当集合点,但在初始设置之后,所有流量都将是端点到端点。

这并非在所有情况下都有效;这取决于各种 NAT 层如何将外部端点映射到内部端点。

TCP NAT 穿越非常难以实现,甚至工作的可能性极低。

(我已成功使用 UDP NAT 遍历在不同大学的两台计算机之间建立了 Open*** 连接,均位于多个 NAT 层之后!)

【讨论】:

谢谢。好吧,这不是我所期望的。 Skype就是这样处理流量的吗?这可以用 Java 之类的语言来完成吗? Skype 使用 NAT 穿越,是的。而且我实际上用 Java 实现了一个基本的 NAT 遍历客户端和集合服务器,所以是的,这绝对是可能的。 那么 Skype 是否使用 UDP 打孔? @Stig:是的,确实如此:h-online.com/security/features/… 这是一个很好的描述!谢谢。【参考方案2】:

如果双方都在 NAT 之后,您可能必须使用 hole punching(TCP 或 UDP)。像这样的:

socket = new DatagramSocket(port);
volatile boolean connectionEstablished = false;
volatile boolean reveivedSomething = false;

发件人线程:

while (!connectionEstablished) 
  byte[] buf = new byte[256];
  buf[0]=reveivedSomething?1:0;
  DatagramPacket packet = new DatagramPacket(buf, buf.length,
          otherpcpublicaddr, otherpcsport);
  socket.send(packet);
  Thread.sleep(500);

接收线程:

while (true) 
  byte[] buf = new byte[256];
  DatagramPacket packet = new DatagramPacket(buf, buf.length);
  socket.receive(packet);
  reveivedSomething=true;
  if (buf[0]==1) 
    connectionEstablished=true;
    break;
  
  Thread.sleep(500);

(您必须在两台 PC 上执行此操作,并使用一些可访问的服务器交换 IP 和端口,只要它们不是静态的)

【讨论】:

谢谢。这就是“UDP打孔”技术,对吧?我可以在两个客户端上硬编码 IP 和端口,并在没有服务器的情况下使其工作吗? @Stig:如果这仅适用于少数情况(甚至一种),您或许应该考虑在两个路由器上使用简单的端口重定向规则。 太好了,我会试试的。看起来很简单。【参考方案3】:

我不知道 Java 修复程序,但您可以使用动态 dns 服务将流量重新路由到非公共 IP。我认为他们使用一个客户端来跟踪由他们的 ISP 分配的公共客户端 IP,并将其报告给服务,然后更新他们的主机表。每个系统的路由器可能还需要一些配置,以便将公共请求转发到私有 ip。

将有多种技术用于执行此操作,端口转发、NAT、动态 DNS 等

【讨论】:

动态 DNS 不是这样做的。即使知道私有 IP 地址,您也无法路由到它,因为它是私有的。 动态 DNS 提供一个固定的主机名和一个短 TTL,当机器的动态 public IP 改变时更新。

以上是关于在没有公共 IP 的情况下通过 http 连接两台计算机的主要内容,如果未能解决你的问题,请参考以下文章

ec2 实例无法在没有弹性 IP 地址的情况下访问公共子网中的互联网?

ADB over TCP/IP 在没有连接 USB 电缆的情况下无法工作

如何在两台机器之间通过 IP 建立非静态 L2TPv3 套接字连接

拆分表并在没有公共列的情况下执行连接

在没有公共列的情况下连接两个数据框

有没有办法在不同网络上通过双向连接连接两台计算机(一台具有端口转发)