C++ 不打开端口的两台计算机之间的通信,使用第三台计算机建立连接

C++ 不打开端口的两台计算机之间的通信,使用第三台计算机建立连接,c++,c,p2p,hole-punching,C++,C,P2p,Hole Punching,假设我有一个服务器,两个客户端连接到它。(通过TCP,但这并不重要) 我的目标是在这两个客户之间建立直接连接。例如,这允许两个玩家之间直接进行语音联系,或者他们可能安装的任何其他不需要服务器交互的客户端插件(比如在两个玩家之间玩某种随机游戏)。服务器可以在那里帮助建立连接 从Dashwuff的回答中,我得到了几个线索: 它描述了一种算法来实现这一点, 从中,我得到了更多的线索: --一种可能的基于TCP的STUN实现 随着时间的推移,我肯定能为我的计划做点什么。目前我使用C++和TCP(QT

假设我有一个服务器,两个客户端连接到它。(通过TCP,但这并不重要)

我的目标是在这两个客户之间建立直接连接。例如,这允许两个玩家之间直接进行语音联系,或者他们可能安装的任何其他不需要服务器交互的客户端插件(比如在两个玩家之间玩某种随机游戏)。服务器可以在那里帮助建立连接

从Dashwuff的回答中,我得到了几个线索:

它描述了一种算法来实现这一点,

从中,我得到了更多的线索:


--一种可能的基于TCP的STUN实现

随着时间的推移,我肯定能为我的计划做点什么。目前我使用C++和TCP(QT套接字或Boost套接字),但如果需要,我不介意在C中做UDP并包装它。
对于任何有C和C++经验的程序员来说,赏金是可以通过链接到示例程序、更新库或任何其他有用信息来提示的。一个文档化的、灵活的和工作的C++ TCP实现将是最好的,但是我会把我所得到的东西拿出来。p> 我不知道有什么方法可以可靠地打通TCP的防火墙,但有一种类似的UDP通信方法已经有很好的文档记录:


临时端口不会神奇地消除通过服务器进行中继的需要,因为它们仅在通过已知服务端口打开的会话的生命周期内有效。基本上,临时端口依赖于服务器会话

您需要使用服务器来中继两个客户端之间的通信,即充当代理服务器。一种选择是通过SSH代理服务器设置SSH隧道,并增加安全性

但这并不能保证防火墙不会阻止连接。这取决于防火墙类型和配置。默认情况下,大多数用作防火墙的住宅路由器会阻止所有传入连接。这通常是好的,因为大多数时候防火墙后面的计算机只是作为客户端,启动到外部的连接。这种设置也有所不同,因为有些限制只启动到众所周知的服务端口(如HTTP、HTTPS、FTP、SFTP、SSH等)的连接,并且如果代理服务器使用的是不知名的服务端口,则连接将被阻止

但防火墙也可以设置为阻止传出流量,这在公司网络中最为常见,公司网络甚至不允许直接连接到web服务器并通过代理服务器路由所有内容,以控制资源使用


您还可以研究如何使用UPnP动态打开端口。

一些项目的链接可能会对您感兴趣或有帮助:


在NAT中穿孔有时/通常是可能的(这取决于NAT的行为)。这不是一个简单的学习主题,而是阅读实用JXTA II(可在线在Scribd上获得)中有关NAT遍历的相应章节,以了解要解决的问题的性质

然后,读一读。它来自于写这篇文章的人:(你问题中的一个链接)

我不是C/C++专家,但要解决的问题不是特定于语言的。只要您可以从代码库访问TCP,就足够了。请记住,实现UDP遍历比TCP更容易

希望这些提示能有所帮助


p.S.:我不知道该解决方案的C/C++实现。康奈尔大学链接中提到的代码未经作者确认可运行。我试图自己将其恢复,但他告诉我,它完全是为了研究目的而调整的,还远没有准备好生产。

您正在寻找用于NAT打孔的会合服务器:可公开访问的服务器(不在NAT/防火墙后面或配置正确)帮助NAT/防火墙后面的计算机建立对等连接

UDP在NAT打孔中更受欢迎,因为它比TCP提供更好的结果。可以找到UDP NAT打孔的清晰且信息丰富的描述

如果需要可靠的通信,可以通过UDP使用可靠的协议:

  • ()-标准化的,或
  • 许多自定义协议之一,例如(我使用了这个库,它非常成熟,功能丰富,并且有NAT打孔实现),或者

  • 临时端口用于响应在已知服务端口(即HTTP、FTP等)上向服务器发出的请求。这样,服务器的已知服务端口在响应请求时不会被阻塞,并且可以接受新的连接。例如,当您打开一个FTP连接时,初始请求通过端口20,服务器接受连接请求并启动一个进程以在另一个端口(临时端口)上使用该会话。如果所有会话都通过同一端口,那么一次只能有一个会话保持连接。@Xint0:这不太准确。HTTP中根本不涉及“临时端口”。连接由本地ip、本地端口、远程ip和远程端口的唯一元组标识。只要任何一对不同的连接的远程ip或远程端口不同,操作系统可以在单个本地ip和端口上处理尽可能多的连接。@R。。当我编写HTTP时,我指的是端口号80,它是HTTP服务器众所周知的服务端口。HTTP是应用层的协议。在传输层中使用临时端口(TCP、UDP等),也许您可以澄清一下,但当我阅读您的评论时,这是错误的。具体来说,“如果所有会话都通过同一端口,一次只能有一个会话保持连接”这句话是不正确的