Программирование P2P-приложения - PullRequest
34 голосов
/ 15 декабря 2011

Я пишу пользовательскую p2p-программу, которая работает на порту 4900. В некоторых случаях, когда человек находится за маршрутизатором, этот порт недоступен из Интернета.

Существует ли автоматический способ включения доступа к порту из интернета. Я не совсем уверен, как работают другие приложения p2p.

Кто-нибудь может пролить свет на это?

Ответы [ 5 ]

104 голосов
/ 15 декабря 2011

P2P-подключение в двух словах. Предположим, мы говорим о UDP здесь. Описанные ниже шаги также могут быть применены к TCP с некоторыми изменениями.

  1. Перечислите все ваши локальные IP-адреса (обычно только 1). Создайте сокет UDP на заданном номере порта ** для каждого адаптера с IP-адресом.

  2. Для каждого сокета, созданного на шаге 1, обратитесь к серверу STUN или TURN с тем же сокетом, чтобы узнать ваш внешний IP-адрес и выяснить, какой номер внутреннего порта отображается вне NAT (это не всегда одно и то же). значение порта). То есть ваш локальный адрес 192.168.1.2:4900 может быть 128.11.12.13:8888 для внешнего мира. И некоторые NAT не всегда используют одинаковое сопоставление портов при использовании одного и того же локального порта с другими IP-адресами. TURN также предоставит вам «адрес ретранслятора». Вы также можете использовать UPNP для получения сопоставленного с портом адреса непосредственно от вашего маршрутизатора, если он поддерживает этот протокол.

  3. С помощью службы рандеву (SIP, XMPP, мгновенных сообщений, веб-службы, электронной почты, чашек со строками) опубликуйте свой список кандидатов в адрес службы или отправьте уведомление другому клиенту, который говорит: «Эй, Я хочу с тобой связаться ». Это сообщение включает в себя все «кандидаты в адреса» (пары ip и port), собранные на шагах 1 и 2.

  4. Удаленный клиент, получив приглашение на подключение, выполняет также шаги 1 и 2, описанные выше. Затем отправляет обратно свой список кандидатов по тому же каналу, на котором он получил список кандидатов приглашающего.

  5. Шаг перфорации. Оба клиента начинают отправлять тестовые сообщения по UDP на адреса-кандидаты другой стороны и прослушивают те же сообщения на своем конце. Всякий раз, когда сообщение получено, ответьте на адрес, с которого оно пришло. В конце концов, клиенты обнаружат, что у них есть пара адресов, на которые они также могут надежно отправлять дейтаграммы. Как правило, одна конечная точка принимает окончательное решение о том, с какой парой адресов (сокетами) обмениваться данными, и протокол облегчает эту конечную точку, сообщая другой конечной точке об этом решении.

** - обычно лучше не полагаться на хорошо известный порт для P2P-клиентов. Поскольку два клиента за одним и тем же NAT или межсетевым экраном вряд ли смогут одновременно использовать ваше программное обеспечение.

Вот краткий обзор некоторых технологий для изучения.

STUN - это простой сервер и протокол для клиентов за NAT / маршрутом, позволяющий определить их внешние IP-адреса и сопоставления портов.

TURN является расширением STUN, но поддерживает ретрансляцию для сценариев подключения P2P, где брандмауэры и NAT предотвращают прямые подключения.

ICE - это набор шагов, с помощью которых STUN и TURN используются для установки P2P-соединения. ICE - это официальный протокол для шагов 1-5 выше. Два превосходных набора слайдов на ICE: здесь и здесь .

WebRTC - это вариант стандарта ICE, а также справочная библиотека для выполнения сеансов P2P с STUN и TURN.

UPNP + Протокол шлюза интернет-шлюза - Некоторые маршрутизаторы поддерживают это для хостов, чтобы автоматически получать сопоставления портов.

libnice - это библиотека C с открытым исходным кодом для Linux (и может работать на Windows), которая реализует ICE.

libjingle - еще одна реализация ICE (на C ++) от Google. Для Windows и Linux.

PJNATH - это библиотека из набора библиотек кодирования PJSIP . Это хорошая реализация стека ICE (код C), которая была портирована на множество платформ. (Windows, Linux, Mac, iOS, Symbian и скоро Android).

И, наконец, у меня есть явный штекер для использования моей базы кода STUN-сервера .

4 голосов
/ 15 декабря 2011

В некоторых случаях существуют решения, см. UPnP: https://en.wikipedia.org/wiki/Universal_Plug_and_Play#NAT_traversal

Мой домашний маршрутизатор позволяет это, в основном, NAT может быть настроен автоматически с помощью соответствующего запроса от компьютера.

Я бы не рассчитывал на это, чтобы значительно повысить вашу доступность, потому что не так много маршрутизаторов поддерживают и поддерживают его.

РЕДАКТИРОВАТЬ: @David предложил этот вопрос SO для библиотеки .NET для UPnP: Существует ли библиотека UPnP для .NET (C # или VB.NET)?

3 голосов
/ 14 сентября 2015

Я бы использовал WebRTC в качестве платформы с открытым исходным кодом для такого приложения.

Официальный сайт

Фактически это проект с открытым исходным кодом, который поддерживает все необходимое для одноранговых технологий из коробки:

  • ICE и STUN (обход NAT)
  • DTLS и SRTP (безопасность)
  • AVPF для качества потоковой передачи.
1 голос
/ 16 июля 2015

У вас есть еще один вариант: Протокол преобразования портов NAT (NAT-PMP) NAT-PMP широко используется приложениями VoIP, такими как клиенты Skype или BitTorrent P2P.

1 голос
/ 15 декабря 2011

Это может быть немного сложнее, чем то, что вы ищете, но TCP Hole Punching - это метод, который должен работать.http://en.wikipedia.org/wiki/TCP_hole_punching

В качестве альтернативы UPnP отлично работает для маршрутизаторов / брандмауэров, которые его поддерживают.

...