Как организовать связь клиент-сервер, если у сервера нет выделенного ip и не проброшены порты?
Вопрос, скорее, теоретический, нежели практический. То есть я не прошу показать мне куски рабочего кода. Я просто не понимаю принцип того, как это работает.
Вот возьмём в пример любую игру, в которой подразумевается мультиплеер. Вы в неё заходите, договариваетесь с другом, создаёте сервер. Он заходит в список доступных серверов, видит вас, кликает, вы соединяетесь, все счастливы.
Я много работал с клиент-серверными приложениями и в том числе имею опыт написания сетевых игр, но там всегда или был выделенный сервер или связь была сугубо по локалке.
И вот мне непонятно, как же происходит связь в таких случаях? Допустим в локальной сети того, кто решил стать сервером 3 машины, подключенные через роутер. Порты в этом самом маршрутизаторе никто, естественно, не прокидывал, белого айпи у пользователя нет.
Я понимаю, что скорее всего выделенный сервер игры, который и хранит и отображает список всех доступных игровых серверов служит, какой-то прослойкой между клиентами и при попытке подключения тыкает их друг в друга со словами "теперь вы друзья", но как это реализуется с технической точки зрения, я не понимаю и даже более того, не знаю как гуглить. Потому как, думаю, проблема тривиальная и ответ на поверхности.
Как вариант можно вот это попробовать. Под капотом все равно есть сервер где то в сети который первоначальный коннект делает дальше уже общаются сами с собой https://professorweb.ru/my/csharp/web/level8/8_3.php
https://github.com/fatedier/frp
Нужно поднять сервер где угодно, где можно выставить наружу порт, к нему подключить клиентов. Дальше между клиентам можно поднять p-to-p подключения и пробрасывать порты.
Вы смешали"игровой сервер" который считает логику, и сервер - машину доступную для всех оппонентов. Так вот, игровой сервер может быть действительно как выделенным, так и запущенным на одном из клиентов.
А вот чтобы клиенты видели друг друга без проброса портов и прочего - нужен сервер, который будет доступен напрямую всем машинам. Им может опять таки выступить один из клиентов, а может выступать условная машина где то в интернетах. И в таком случае эта машина будет выполнять только роль прокси - т.е. передавать пакеты между всеми клиентами и игровым сервером.
Для того же юнити можете посмотреть фотон - он как раз и предоставляет вот эту проксю.
Я думаю, что всё работает не совсем так. Пакеты явно шлются напрямую от одной машины к другой, минуя сторонний сервер. А этот самый выделенный сервер нужен только для первоначального коннекта. Это можно понять, потому как после осуществления коннекта, если связь с выделенным сервером пропадёт, не важно по какой причине, игровая связь не прервётся.
Николай Алексеев, не встречал ситуаций, когда пропадание связи с прокси-сервером не приводит к обрыву сессии. Но в целом - технически можно и как вы написали - пробивается NAT и все такое - некий аналог торрентов.
GavriKos, Я сталкивался с этим при игре в Divinity original sin, когда в один прекрасный момент наш провайдер сдох, потеряв доступ к глобальному интернету, но сеть между теми, кто подключен к провайдеру сохранилась и мы узнали о том, что интернета нет, только когда вышли из игры. Поэтому я и пришёл к выводу, что после подключения пакеты уже не затрагивают тот самый прокси сервер. Ну и судя по тому, что я прочитал по ссылкам в двух других ответах, видимо, действительно должно быть что-то вроде пир ту пир
а вообще в примере с играми как раз сервера разработчиков имеют выделенные IP и с портами все в порядке, вы просто соединяетесь через них со своими друзьями
Для первого коннекта используется промежуточный и доступный всем прокси в инете.
Далее он нстраивает связь между двумя игроками, и далее игроки общаются на прямую.
Одна из технологий p-2-p
Порты у игроков открываются друг к другу автоматически, с помощью технологии UPNP