Программирование P2P-приложения
Я пишу пользовательскую программу p2p, которая работает на порте 4900. В некоторых случаях, когда человек находится за маршрутизатором, этот порт не доступен из Интернета.
Есть ли автоматический способ включения доступа к порту из интернета. Я не совсем уверен, как работают другие приложения P2P.
Кто-нибудь может пролить свет на это?
6 ответов
P2P-соединение в двух словах. Предположим, мы говорим о UDP здесь. Приведенные ниже шаги также могут быть применены к TCP с некоторыми корректировками.
Перечислите все ваши локальные IP-адреса (обычно только 1). Создайте сокет UDP на заданном номере порта ** для каждого адаптера с IP-адресом.
Для каждого сокета, созданного на шаге 1, обратитесь к серверу STUN или TURN с тем же сокетом, чтобы узнать ваш внешний IP-адрес и узнать, какой номер внутреннего порта отображается вне NAT (это не всегда одно и то же значение порта). То есть ваш локальный адрес 192.168.1.2:4900 может быть 128.11.12.13:8888 для внешнего мира. И некоторые NAT не всегда используют одинаковое сопоставление портов при использовании одного и того же локального порта с другими IP-адресами. TURN также предоставит вам "адрес ретранслятора". Вы также можете использовать UPNP для получения адресов, привязанных к порту, непосредственно от вашего маршрутизатора, если он поддерживает этот протокол.
С помощью службы рандеву (SIP, XMPP, мгновенных сообщений, веб-службы, электронной почты, чашек со строками) опубликуйте свой список адресов адресов в службе или отправьте уведомление другому клиенту, который говорит: "Эй, я хочу с вами связаться ". Это сообщение включает в себя все "кандидаты в адреса" (пары ip и port), собранные на шагах 1 и 2.
Удаленный клиент, получив приглашение на подключение, выполняет также шаги 1 и 2, описанные выше. Затем отправляет обратно свой список кандидатов по тому же каналу, на котором он получил список кандидатов приглашающего.
Шаг перфорации. Оба клиента начинают отправлять тестовые сообщения по UDP на адреса-кандидаты другой стороны и прослушивают те же сообщения на своем конце. Всякий раз, когда сообщение получено, ответьте на адрес, с которого оно пришло. В конце концов, клиенты обнаружат, что у них есть пара адресов, на которые они также могут надежно отправлять дейтаграммы. Как правило, одна конечная точка принимает окончательное решение о том, с какой парой адресов (сокетами) обмениваться данными, и протокол облегчает эту конечную точку, сообщая другой конечной точке об этом решении.
** - обычно лучше не полагаться на хорошо известный порт для клиентов P2P. Потому что два клиента за одним и тем же NAT или брандмауэром вряд ли смогут одновременно использовать ваше программное обеспечение.
Вот краткий обзор некоторых технологий для изучения.
STUN - это простой сервер и протокол для клиентов за NAT/ маршрутом, чтобы узнать, каковы их внешние IP и сопоставления портов.
TURN является расширением STUN, но поддерживает ретрансляцию для сценариев подключения P2P, где брандмауэры и NAT предотвращают прямые подключения.
ICE - это набор шагов, с помощью которых STUN и TURN используются для установки P2P-соединения. ICE - это официальный протокол для шагов 1-5 выше. Два отличных набора слайдов по ICE здесь и здесь.
WebRTC - это вариант стандарта ICE, а также справочная библиотека для выполнения сеансов P2P с STUN и TURN.
UPNP + Internet Gateway Device Protocol - некоторые маршрутизаторы поддерживают это для хостов, чтобы автоматически получать сопоставления портов.
libnice - это библиотека C с открытым исходным кодом для Linux (и может работать на Windows), которая реализует ICE.
libjingle - другая реализация ICE (на C++) от Google. Для Windows и Linux.
PJNATH - это библиотека в наборе кодирующих библиотек PJSIP. Это хорошая реализация стека ICE (код C), которая была портирована на множество платформ. (Windows, Linux, Mac, iOS, Symbian и скоро Android).
И, наконец, у меня есть явный штекер, чтобы вы могли использовать мою базу кода STUN-сервера.
В некоторых случаях есть решения, см. UPnP: https://en.wikipedia.org/wiki/Universal_Plug_and_Play
Мой домашний маршрутизатор позволяет это, в основном, NAT может быть настроен автоматически по соответствующему запросу от компьютера.
Я бы не стал рассчитывать на это, чтобы значительно повысить вашу доступность, потому что не так много маршрутизаторов поддерживают и поддерживают его.
РЕДАКТИРОВАТЬ: @David предложил этот вопрос SO для библиотеки.NET для UPnP: есть ли библиотека UPnP для.NET (C# или VB.NET)?
Я бы использовал технологию WebRTC в качестве платформы с открытым исходным кодом для такого приложения.
Фактически это проект с открытым исходным кодом, который поддерживает все необходимое для одноранговых технологий из коробки:
- ICE и STUN (прохождение NAT)
- DTLS и SRTP (безопасность)
- AVPF за качество потоковой передачи.
Это может быть немного сложнее, чем вы ищете, но TCP Hole Punching - это метод, который должен работать. http://en.wikipedia.org/wiki/TCP_hole_punching
В качестве альтернативы UPnP отлично работает для маршрутизаторов / брандмауэров, которые его поддерживают.
У вас есть еще один вариант - протокол преобразования портов NAT (NAT-PMP). NAT-PMP широко используется приложениями VoIP, такими как Skype или BitTorrent P2P-клиенты.
Для простого начала я бы порекомендовал посмотреть технику пробивки отверстий. Отличное видео здесь . Но будьте уверены, что это не всегда будет работать в зависимости от топологии сети. Это решает технику ICE, которая обнаруживает, как может быть установлено соединение.