Как можно пробросить порт программно? Чтобы соединить два компьютера напрямую(даже с динамическим ip)? Подскажите, куда копать?
Ответ
Соединение двух компьютеров напрямую состоит из двух фаз (подзадач), которые обычно решаются отдельно.
Фаза 1 - обнаружение (discovery)
Чтобы соединиться - надо знать куда соединяться. Иными словами, нужен ip-адрес. Когда клиент соединяется с сервером, обычно используется доменное имя - но при одноранговом соединении, как правило, доменные имена компьютерам не назначены. И даже если назначены - их тоже нужно как-то узнать.
Для этого есть несколько способов.
Ввод ip-адреса (или доменного имени) пользователем напрямую. Если в вашем случае предполагается, что этот вариант и будет основным - дальше про обнаружение можно и не читать.
Сканирование сети. Разумеется, перебирать ip-адреса и порты не следует: есть более простой способ кооперативного обнаружения - широковещательные пакеты. Можно на одной стороне отправить UDP-пакет на широковещательный адрес, а на другой принять его на известный порт. В старых сетевых играх это был основной способ обнаружения, он неплохо показывает себя в пределах одного сегмента локальной сети.
Более современный вариант - отправка пакета на групповой адрес. Гуглить по слову IGMP
Использование общего каталога. Нужно создать сервер, который бы занимался распространением знаний клиентов друг о друге. Примеры: в сетевых играх от Blizzard этим занимаются сервера Battle.Net. В сети bittorrent этим занимаются торрент-трекеры.
Использование распределенных хранилищ данных. Гуглить по слову DHT
Фаза 2 - соединение
И так, у нас есть ip-адрес другой стороны, и возможно даже посредник, через которого можно связаться и договориться о технических параметрах соединения.
Отмечу особенно, что нам совершенно не важно, статический или динамический этот адрес. Важно лишь, что он назначен нужному компьютеру - и мы его знаем! Осталось установить соединение.
Тут снова есть варианты.
Если один из компьютеров "видит" другой - то он к нему может подключиться напрямую. Отмечу, что имеет смысл пробовать оба варианта, поскольку возможность установления соединения не обязательно симметрична. К примеру, торрент-клиенты умеют работать даже при полностью закрытых для входящих соединений портах - соединяясь с теми, у кого они открыты. Или, другой пример, протокол FTP - в нем соединение для передачи данных может быть открыто как в активном (сервер соединяется с клиентом), так и в пассивном (клиент соединяется с сервером) режимах.
Пользователя можно попросить открыть порт вручную.
Протокол UPnP позволяет, в том числе, открыть порт на локальном роутере - если он его поддерживает.
Если компьютер закрыт NATом - но этот NAT не является симметричным, то можно воспользоваться "багофичей" NAT. Дело в том, что UDP-пакет, отправленный "наружу", открывает случайный порт для приема информации "внутрь". И в некоторых типах NAT этот самый входящий порт доступен не только для того адреса и порта, на которые был отправлен первый пакет. Таким образом, для протокола UDP для некоторых типов NAT можно открыть входящий порт. За это отвечает протокол STUN
Некоторые провайдеры или организации до сих пор предоставляют доступ в интернет через прокси-сервер. HTTP(S) или SOCKS4-прокси в этом плане нам бесполезны, но вот SOCKS5-прокси позволяет открывать порт на прием соединений.
Если все совсем плохо - может помочь VPN или туннелирование. Обычно такие вопросы оставляют пользователю - но вот Skype, к примеру, своей популярностью обязан в том числе способности туннелировать трафик через т.н. супер-ноды (супер-нодой может (мог?!) внезапно стать любой компьютер с разрешенными входящими подключениями, толстым каналом и запущенным скайпом).
Комментариев нет:
Отправить комментарий