使用服务器绕过路由器以启动连接

| 我想用Java创建简单的聊天程序,该程序可以在p2p的基础上工作。使用公共服务器仅启动连接。但是我什至不确定这是可能的。 我成功地用Java实现了聊天解决方案,如果至少一台PC转发了正确的端口,该解决方案就可以工作。我还设法使用外部服务器来代替,或者不得不在客户端上转发端口。 因此,我什至有可能以某种方式使用公共服务器来发起连接,而不是仅在客户端之间发送数据,从而减轻服务器的负担? 我对路由器的工作方式不是很熟悉,但是我希望当您从内部IP呼叫公用服务器时,路由器会记住该公用IP的呼叫和传入响应,而不是发送到您的PC。所以我想,也许第一个客户端连接到服务器,然后服务器将信息传递给第二个客户端,也许他们可以通过某种方式直接进行通信?路由器中的规则是否由服务器建立? 我希望我能清楚地解释。如果没有,请原谅。我什至不知道该怎么做,我只是想知道我的概念是否正确,并且我必须更加努力地学习,以使它可行。谢谢。     
已邀请:
这是一个广泛的主题,搜索打孔(对于TCP:http://en.wikipedia.org/wiki/TCP_hole_punching)     
我认为TeleHash是一个可以执行类似操作的新项目。我只是在最近才发现它,所以我对此不太了解。 我做了这个答案社区Wiki,以便其他人可以对其进行更新,以解释如何将TeleHash用于此目的。     
编辑:评论后(并阅读链接的页面),我应该撤退我的建议。对于精美的图形,我不删除它,但更改了最后一部分。 如果我理解正确,那么您有两个客户端都位于NAT防火墙后面,该防火墙允许传出连接,但是如果没有经过特别配置,则不会转发传入的连接(因为它们不知道要发往哪个本地主机)。 原则上,TCP连接在其整个存在期间始终会连接相同的两个IP地址和这些地址处的端口号(例如,我们有四个保持不变的数字)。在NAT的情况下,您实际上有两个连接,但这在客户端计算机A(从服务器S)中也不可见:
Client A  -------(LAN)------ NAT B      ------ (Internet) -------- Server S
  IP A                   IP B1 | IP B2                               IP S
  Port a                       | Port b                              Port s
TCP数据包的LAN部分具有[A:a / S:s](或[S:s / A:a])地址,以及[B2:b / S:s](或[S:s / B2:b] ])在互联网部分上的地址。该连接由此[IP:port / IP:port]四元组标识,因此,即使您尝试更改四个数字之一,也必须是新的连接(否则数据包将被丢弃)。 因此,如果您是第一次与服务器对话,则除非服务器正在转发内容,否则您将无法继续与同一连接上的其他客户端对话。 实际上,UDP数据包也是如此,区别在于没有连接,并且NAT必须很聪明,并猜测哪个数据包是另一个数据包的答案,因此将其转发到正确的方向。 正如评论和其他答案所指出的,这是可以欺骗NAT的地方:我们首先将UDP数据包发送到另一个客户端,该客户端将被那里的NAT丢弃。但是,另一个客户端发送一个应答数据包,该应答数据包不是传出数据包的真正答案(因为由于其他客户端NAT从未收到此数据包),但是IP地址和端口号匹配,因此仍然可以通过。如果NAT还转换端口号,这可能会变得更加复杂。 对于TCP,如果两个NAT都不真正保持打开的连接,而是在以前发送过SYN时仅转发(更改)数据包,则它的工作原理类似。这甚至更加复杂,因为此处TCP序列号也必须匹配。     

要回复问题请先登录注册