Что BitTorrent и Gnutella используют для обхода NAT при передаче файлов? - PullRequest
16 голосов
/ 08 апреля 2011

Я пытаюсь сделать прото / программное обеспечение для обмена файлами p2p на Java.Я заинтересован в изучении с использованием сокетов, так что нет, я не буду использовать JXTA или какой-либо другой API.

Я читал о дыроколах TCP, и он может не работать на всех типах NAT.Но я вижу, что Gnutella и BitTorrent всегда работают на каждой машине / NAT, которые я пробую.Так они используют TCP Hole Punching для инициации соединения между хостами?

Кроме того, подобный код будет выполнять TCP Hole Punching?

    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);

Ответы [ 3 ]

3 голосов
/ 14 июня 2015

Сначала вы должны прочитать прохождение NAT в Википедии.

Однако, на самом деле, в основном, используются следующие способы: UPnP, STUN, TURN, а также ICE, представляющий собой комбинацию STUN и TURN.

Поскольку TCP является протоколом, ориентированным на соединение, NAT может управлять им для каждого соединения и отбрасывать все пакеты, когда соединение установлено.
Но UDP не имеет соединения, и ответ может приходить с другого порта или с разных адресов (по сравнению с вашим исходным адресатом). Также нет точного времени ожидания для сообщения UDP. Таким образом, для NAT обычно меньше ограничений для UDP.
В результате многие из этих реализаций P2P используют UDP или некоторые виды протоколов на основе UDP, такие как microTP, RUDP, UDT или даже SCTP через UDP (на основе WebRTC).

Вы также можете узнать из статей об обходах NAT, RFC и BEP (документы BitTorrent).

Редактировать: есть еще один интересный способ - обход ICMP. На самом деле ICMP (особенно сообщение о превышении TTL) имеет даже меньше ограничений, чем UDP для NAT, поскольку сообщение об ошибке может быть отправлено из любого уголка Интернета, и маршрутизаторы с NAT не могут знать, что эти сообщения не являются истинными. Однако для отправки ICMP-пакетов требуется разрешение root в Unix-подобных системах и разрешение администратора в Windows.

3 голосов
/ 08 апреля 2011

Я думаю, что Universal Plug and Play (UPnP) - это протокол, который позволяет программно настраивать переадресацию портов в маршрутизаторе. Я не уверен, что это единственный метод, который используют эти программы.

Взгляните на проект UPnP PortMapper для реализации Java.

Эта статья CodeProject также выглядит хорошо, хотя это не Java: Использование UPnP для программной переадресации портов и обхода NAT .

1 голос
/ 18 января 2012

После моего исследования я обнаружил, что TCP не подходит для обхода NAT, а TCP Hole Punching не является 100% успешной техникой.

Лучший способ - использовать UDP и реализовать поверх него уровень устойчивости к ошибкам, так чтокак это будет работать как TCP.

Также есть некоторые API, такие как UDT для Java.Но я еще не пробовал http://sourceforge.net/projects/udt-java/

...