没有中央服务器的P2P握手

时间:2014-05-22 15:11:11

标签: c# .net networking network-programming p2p

我编写了一个客户端 - 服务器应用程序,旨在通过局域网交换文件(以及其他内容)。在服务器模式下,应用程序侦听具有特定标识头的TCP连接。在客户端模式下,它尝试建立与用户提供的IP地址的TCP连接。

我现在需要调整此应用程序以在互联网上工作。没有太多的网络编程,我不知道如何在没有某种中央服务器(用于宣布存在等)的情况下实现这一目标。这不是一个选择。

假设我的应用程序在家用网络后面的机器上以服务器模式运行。您(读者)将应用程序置于客户端模式,我们需要连接。我们都没有静态IP地址。有没有办法让客户端到达服务器?服务器和客户端都可以找出他们的公共IP地址,但除此之外,我不知道该怎么做。

任何指导都将不胜感激。

编辑:根据答案,有些说明是有道理的。我的问题不是发现。客户端和服务器都可以查询其公共地址,用户可以通过其他介质交换这些IP。问题是,如何知道彼此的IP之后建立连接,但双方都在没有适当端口转发的网络后面。例如,我的应用程序使用端口51200作为TCP的默认值。

4 个答案:

答案 0 :(得分:4)

我已经了解到,由于所涉及的NAT类型的某些可能组合,UDP穿孔技术以获得2个对等体之间的真正直接连接是不完美的。这意味着UDP穿孔单独并不总是有效。

声称100%可操作性的方法是,在无法连接p2p的情况下,使用中继服务器。 ICE,TURN和STUN已经标准化了发现真正的p2p连接是否可行的过程。我所知道的是,使用ICE / TURN / STUN似乎是颠覆NAT问题的标准化策略。它可以在可用时促进真正的p2p连接,并在必要时提供中继服务。

注意:我在此答案中使用术语p2p来区分2个端点之间的真正直接连接,而不是与覆盖网络等混淆。

高级用户:通过引入更复杂的策略来配合对称NAT行为(例如端口预测等),可以获得更直接的p2p连接。但实现这些方法的库代价高昂,对于DIY工作来说似乎太难了。

我没有详细解释不同类型的NAT连接可能性。您将需要研究NAT类型以及它们与UDP打孔的关系。那里有RFC,我会尝试用链接更新我的答案。但重点是,您可以通过重新关注实施TURN / STUN / ICE,了解它们的实施方式以及如何使用标准化行为来避免大量学习。

潜在解决方案

  • PJSIP - 包含一个用于C / C ++的独立高级NAT遍历库,还具有其他语言的绑定。如果您只想要NAT Traversal库子组件,请参阅PJNATH
  • LibJingle - 基于XMPP构建的P2P(点对点)和RTC(实时通信)堆栈。请注意,许多LibJingle实现不能与实际的XMPP Jingle规范和子规范互操作。

这些可能会给程序增加相当大的复杂性,这就是为什么自己实现某些机制可能很有吸引力的原因。

文档

IETF

<强>的RFC

微软

注释

我听说最终迁移到IPv6可能会破坏NAT遍历问题,但是[probably not]。有人可以启发这个话题。无论哪种方式,从我没有经验的观点来看,IPv6的发展似乎很慢,我不会指望它作为解决方案。

答案 1 :(得分:2)

几个月前,我一直在寻找类似的解决方案,但不幸的是我陷入困境,从此我放弃了它。

人们说你可以使用UDP hole punchingTCP hole punching,但我无法做到这一点(我不是计算机网络的专家)。它是否有效取决于网络本身。

Here是我最初提出的问题,也许对您有所帮助。老实说,我不想扼杀你的希望,但我担心这可能是一个死路一条。 :(

答案 2 :(得分:0)

如果没有某种“找到”对方的中心位置,我不相信这是可能的。您需要一些方法让客户端找到要连接的服务器IP地址。

另外,udp或tcp打孔是一个完全不同的东西并使用,猜猜:中央服务器。

答案 3 :(得分:0)

如果您使用IPv6,则可能 - 但您仍需要了解其他方的地址。如果您使用DynDns服务也可以 - 但这已经是一种中央基础设施。