【问题标题】:What does BitTorrent and Gnutella uses for bypassing NAT when transferring files?传输文件时,BitTorrent 和 Gnutella 使用什么绕过 NAT?
【发布时间】:2011-08-01 12:00:50
【问题描述】:

我正在尝试用 Java 做一个 p2p 文件共享原型/软件。 我有兴趣学习使用套接字,所以我不会使用 JXTA 或任何类型的 API。

我阅读了有关 TCP 打孔的信息,它可能不适用于所有 NAT 类型。 但我可以看到 Gnutella 和 BitTorrent 总是可以在我尝试的每台机器/NAT 上运行。 那么他们是否使用 TCP Hole Punching 来启动主机之间的连接?

另外,这样的代码可以进行 TCP 打孔吗?

    final ServerSocket s = new ServerSocket(7777);
    Thread t = new Thread(new Runnable(){

        public void run() {
            try
            {
                s.accept();
            }
            catch(Exception ex)
            {

            }
        }
    });

    Socket sock = new Socket();
    sock.connect(new InetSocketAddress("IP ADDRESS", 7777), 50000);

【问题讨论】:

  • 非常有趣的问题(+1)

标签: java tcp bittorrent


【解决方案1】:

我认为Universal Plug and Play (UPnP) 是一种协议,可让您以编程方式在路由器中设置端口转发。不过,我不确定这是否是这些程序使用的唯一方法。

查看UPnP PortMapper project 的Java 实现。

这篇 CodeProject 文章看起来也不错,虽然不是 Java:Using UPnP for Programmatic Port Forwardings and NAT Traversal。

【讨论】:

  • 我不明白... 这个 UPnP 在 NAT 路由器中创建端口转发规则?但我不想那样做,我想使用 Tcp Hole Punching 或其他技术进行连接,如 bittorrent、gnutella,确实......我写的上面的代码也不起作用
  • @fredcrs - 我对 TCP 打孔一无所知。我所知道的是,µTorrent 和 Azureus 都可以使用 UPnP 来允许来自新 IP 地址的传入连接(尽管在某些情况下它们也可能使用 TCP 打孔)。
  • 我发现大多数路由器默认禁用 UPnP(至少在我的国家)
  • @fredcrs - 是的,我一直必须进入路由器设置并启用 UPnP 才能正常工作。 (或者你的意思是永久禁用?)
【解决方案2】:

你应该先阅读维基百科上的NAT traversal。

但实际上,主要使用的方式是UPnP、STUN、TURN,以及由STUN和TURN组合而成的ICE。

由于 TCP 是一种面向连接的协议,NAT 可以对每个连接进行控制,并在连接结束时丢弃所有数据包。
但是 UDP 是无连接的,响应可能来自不同的端口或不同的地址(与您的原始目的地相比)。此外,UDP 消息没有确切的超时时间。因此,NAT 上的 UDP 限制通常较少。
因此,这些 P2P 实现中的许多都使用 UDP 或某些基于 UDP 的协议,例如 microTP、RUDP、UDT,甚至是 SCTP over UDP(WebRTC 就是基于它)。

您还可以从有关 NAT 遍历、RFC 和 BEP(BitTorrent 文档)的文章中学习。

编辑:还有一种更有趣的方式——ICMP 遍历。事实上,ICMP(尤其是超过 TTL 的消息)在 NAT 上的限制甚至比 UDP 还要小,因为错误消息可以从 Internet 的各个角落发送,而具有 NAT 的路由器无法意识到这些消息不是真实的。但是,在类 Unix 系统上发送 ICMP 数据包需要 root 权限,在 Windows 上需要管理员权限。

【讨论】:

    【解决方案3】:

    经过研究,我发现 TCP 不适合绕过 NAT,而且 TCP 打孔也不是 100% 成功的技术。

    最好的方法是使用 UDP 并在其上实现一个容错层,这样它就可以像 TCP 一样工作。

    还有一些 API,例如用于 Java 的 UDT。但我还没试过 http://sourceforge.net/projects/udt-java/

    【讨论】:

    • 您的回答与您的问题不符!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-16
    • 2013-06-01
    • 2021-07-04
    • 1970-01-01
    • 2020-02-20
    • 1970-01-01
    相关资源
    最近更新 更多