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 + Протокол шлюза интернет-шлюза - Некоторые маршрутизаторы поддерживают это для хостов, чтобы автоматически получать сопоставления портов.
libnice - это библиотека C с открытым исходным кодом для Linux (и может работать на Windows), которая реализует ICE.
libjingle - еще одна реализация ICE (на C ++) от Google. Для Windows и Linux.
PJNATH - это библиотека из набора библиотек кодирования PJSIP . Это хорошая реализация стека ICE (код C), которая была портирована на множество платформ. (Windows, Linux, Mac, iOS, Symbian и скоро Android).
И, наконец, у меня есть явный штекер для использования моей базы кода STUN-сервера .