2013-08-29 3 views
2

Возможно ли установить прямое соединение между двумя клиентами, которые находятся за разными NAT? Конечно, я понимаю, что в какой-то степени необходим сервер с публичным IP-адресом, но я не хочу, чтобы он был прокси-сервером. Взгляните на следующий сценарий:Как создать соединение P2P, когда оба клиента находятся за NAT

  • Я не хочу, чтобы какое-либо отношение к настройке сетевых устройств. Я просто хочу сделать это в коде.
  • Я не хочу, чтобы сервер принять участие в процессе передачи файлов (по соображениям производительности)
  • мы имеем: клиент А, клиент B, и сервер S, и это выглядит примерно так:

а - [Роутер1] - S - [Роутер2] - Б

  • соединяется с S и разрешает
  • B соединяется с S и разрешает
  • А хочет послать файл B
  • просит S для подключения к B
  • S [делает это волшебство здесь] и А теперь есть подключение к B
  • А начинает посылать файл
  • S идет вниз (или по крайней мере передачи файлов в обход есть)
  • есть еще связь между A и B
  • продолжает передавать файл B

Мои вопросы:

  1. Возможно ли это?
  2. Как это сделать?
  3. Встретились с примером проекта, который может это сделать?

Я нашел WCF/WPF Chat Application, но оказалось, что это прокси.

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

ответ

5

Термин, который вы ищете для «волшебной части», называется NAT Hole Punching. К сожалению, тема слишком широка, чтобы полностью объяснить здесь, как ее выполнить, но теперь, зная, что правильный термин должен, по крайней мере, помочь вам начать поиск правильных учебников.

Вот краткое описание алгоритма с страницы UDP Hole Punching.

Пусть A и B - два хоста, каждый в своей частной сети; N1 и N2 - два устройства NAT с глобально достижимыми IP-адресами P1 и P2 соответственно; S является общедоступным сервером с общедоступным глобальным адресом .

  1. A и B каждый начинает беседу UDP с S; Эти устройства NAT N1 и N2 создание состояния перевода UDP и назначать временные внешние номера портов X и Y
  2. S рассматривает UDP-пакеты, чтобы получить порт источника, используемый N1 и N2 (внешних портов NAT X и Y)
  3. S передает P1: от X до B и P2: от Y до A
  4. A отправляет пакет в P2: Y и B отправляет пакет в P1: X, используя тот же исходный порт, что и разговор с S, таким образом, «пробивая» отверстие в NAT на другом хосте
  5. Если какой-либо хост принимает пакет, удары отверстий успешны и оба узла могут обмениваться данными.

Если оба хоста имеют Restricted cone NATs или Symmetric NATs, внешние порты NAT будут отличаться от тех, которые используются с S. На некоторых маршрутизаторы, внешние порты собирают последовательно делая возможным , чтобы установить разговор через догадываясь близлежащие порты.

ли или нет он будет работать в значительной степени зависит от того, как маршрутизаторы NAT ОБА конечные точки ведут себя, то весьма вероятно, что значительная часть ваших целей будет работать в паре и оба имеют маршрутизаторы, которые не являются «дыроколом дружественным» ,

В вашей ситуации я бы попробовал выполнить мои действия по порядку.

  1. Проверить и посмотреть, если мы можем просто подключить (пользователь сделал вручную перенаправление портов)
  2. Использование UPnP и открыть порт
  3. использовать некоторые формы перфорирования с использованием общедоступного сервера в пути между
  4. Используйте другой одноранговый узел, который имеет открытые порты в качестве прокси-сервера для данных (a Supernode).
  5. Используйте сервер, на котором я размещаю прокси-сервер для пересылки данных.
Смежные вопросы