Topic: [guide]Как играть нескольким игрокам с 1 внешним ip в одной игре
Как играть нескольким игрокам с 1 внешним ip в одной игре
Кто не знает, что такое NAT и имеет ли эта статья к нему вообще отношение - может почитать это и это.
Соединение в Battle.Net играх.
Для War 3 все сравнительно просто - те, кто сидят за 1 ip, не должны хостить игру. Starcraft и War 2 же требуют соединения между всеми клиентами.
Причина проблем вот в чем.
Желающий зайти в игру клиент получает внешний ip:port других клиентов от сервера или хоста и пытается с ними соединиться. Даже если этот клиент находится в той же локалке (за тем же NAT-ом), что и джойнящийся - он все равно пытается установить соединение с внешним ip NAT рутера, т.к. он просто не знает про существование NAT-а. Проблема в том, что в RFC для NAT не описано, как NAT должен обрабатывать такую ситуацию (иногда это называют NAT loopback), и несмотря на то, что подавляющее большинство прошивок сделаны на базе линупса, который сам по себе эти соединения разрешает - среди производителей рутеров "кто как хочет, тот так и др...", т.е. рутер их или разрешает, или нет. Это ничем не лечится (если нет возможности поставить альтернативную прошивку вроде DD-WRT / OpenWRT), только заменой рутера на тот, который это может.
Единственное, что можно в такой ситуации сделать - это протестировать, какие модели рутеров с какими версиями прошивки разрешают соединения на свой внешний ip из внутренней сети, а какие нет, и покупать рутер, который это разрешает.
Более простой алгоритм ручной проверки.
1. Качаем Blue's port tool (что-то вроде netcat с GUI). GIFRAR, сохранить на диск и открыть винраром.
2. Запускаем. В графе port пишем порт, ставим галку на TCP. Жмем на listen. Соответствующий порт должен быть открыт на рутере.
3. Проверяем, открыт ли порт снаружи. www.yougetsignal.com/tools/open-ports/ - здесь заодно можно узнать и свой внешний ip. Если порт открыт - читаем дальше.
4. Запускаем браузер, пишем в адресной строке http://внешний_ip:порт/. В окне Port tool должно появиться что-то вроде
GET / HTTP/1.1
blabla
Если появилось - поздравляю, все работает. Нет - ну и суда нет.
Алгоритм ручной проверки.
1. Качаем netcat.
2. Открываем 2 консоли.
В 1й пишем: nc -L -p 6112
(Программа слушает порт 6112 TCP. Он может быть любым, должен быть прокинут на рутере и не занят. Для UDP добавьте -u)
3. Во 2й пишем: nc external_ip 6112
Вместо external_ip пишем свой внешний ip, его можно узнать тут: 2ip.ru. Для UDP опять добавьте -u)
4. Если программа не вышла, попробуйте что-то написать в окно и нажать Enter. Текст должен появиться во втором окне. Напишите что-то во втором окне - текст должен появиться в первом окне. Если получилось, поздравляю, у вас все работает.
Если хоть 1 шаг не работает - значит нефарт, играть вам не светит.
Developers, Developers, Developers!
Идеальным способом было бы как сделано здесь - база данных по рутерам + программа-тестер, которая эту базу заполняет. Соответственно, ищется разработчик для нее и для серверной части. Программа желательно должна быть на нативном (компилируемым) языке, т.е. не требующим дополнительных библиотек вроде Java или .Net. С алгоритмом тестирования и серверной частью могу помочь.
Все, что тут написано, относится не только к Battle.Net играм - оно относится к любой ситуации, когда клиенты соединяются друг с другом и они могут оказаться за одним и тем же NAT-ом, например, различные p2p программы, интернет телефония. С точки зрения совместимости с программами, которые не знают про существование NAT, было бы гораздо правильнее такие соединения разрешать. Можно ли как-то написать петицию к производителям NAT рутеров?
Алгоритм проверки.
1. Тестируем портмаппинг снаружи. Сервисов для этого навалом, как на сайтах p2p файлообменников, так и на portforward.com (там могут проверять отдельно UDP). Если добавить поддержку UPnP, можно пытаться открыть порт самому. Если порт закрыт, заканчиваем, иначе переходим к 2. Хотя можно оставить портмэппинг на совести юзера и предложить юзеру перейти к 2, на случай, если у него инета нет или с ним чето не то.
2. Если 1. сработал, открываем новый сокет, и с него проверяем портмэппинг изнутри. Если соединение работает в обе стороны, то все работает, иначе нет.
3. Открываем юзеру окно с результатами теста (или сразу страницу в браузере). Предлагаем ему вбить туда данные рутера (их можно прочесть опять же через UPnP) и потом отправляем на сайт.
Примечание. Китайская поделка Dlink DIR-300 убедила меня, что все возможно в этом мире (какие вещества надо принять, чтобы додуматься до того, что они там сделали), и если NAT loopback работает для TCP, то есть небольшая вероятность, что для UDP он таки работать не будет, так что для окончательного результата проверять надо игрой (или потоком UDP пакетов в обе стороны).