Прямые TCP / IP-соединения в P2P-приложениях
-
09-06-2019 - |
Вопрос
Из Сообщение Джоэла о втором пилоте:
Прямое Подключение!Мы всегда делали все возможное, чтобы убедиться, что Fog Creek Copilot может подключаться в любой сетевой ситуации, независимо от того, какие установлены брандмауэры или NAT.Для чтобы это произошло, обе стороны осуществляют исходящие подключения к нашему серверу, который ретранслирует трафик от их имени.Ну, во многих случаях, это не надо.Итак, версия 2.0 делает что-то довольно умное:он устанавливает первоначальное соединение через наши серверы, так что вы подключаетесь сразу со 100% надежностью.Но затем как только вы все подключены, он тихо, в фоновом режиме, ищет способ установить прямое соединение.Если это невозможно, ничего страшного:вы просто продолжаете ретранслировать через наш сервер.Если вы можете установить прямое одноранговое соединение, это автоматически перенесет ваши данные в прямое соединение.Вы не заметите ничего, кроме, возможно, гораздо более быстрого общения.
Как они меняют подключение к серверу на P2P-соединение?
Решение
Это довольно сложно и интересно.Я уверен, что в некоторых деталях ошибся, но общий обзор таков:
Программы уже могут взаимодействовать друг с другом через сервер Джоэла, поэтому они могут обмениваться информацией друг с другом и с сервером Джоэла.Кроме того, у Joel есть их внешние IP-адреса, и они предоставляют joel информацию о своих внутренних IP-адресах.
Они решают попробовать эту технику пробивания отверстий.Компьютер A инициирует TCP-соединение с компьютером B, используя внешний IP-адрес B.Он не пройдет, но что он делает, так это сообщает маршрутизатору A, что ему необходимо разрешить входящие пакеты от B на данный порт.
Компьютер B делает то же самое, но его сообщение доходит до A, поскольку маршрутизатор A открыл комбинацию порт / ip, которая соответствует отправленной B (здесь происходит некоторая магия порта - это нетривиально, но выполнимо).
Маршрутизатор B запоминает, что B инициировал соединение с A по заданному порту и IP, и поэтому пакеты A теперь также корректно поступают в B через их маршрутизатор.
Так что на самом деле это довольно просто, но в реализации есть детали, особенно касающиеся того, как порты передаются новым TCP-соединениям и как маршрутизаторы NAT обычно разберитесь с TCP-запросами и с тем, как они сопоставляются с внешними портами.Эти детали - самое интересное и сложное.
-Адам
Другие советы
Существует техника , которая называется "Пробивка отверстий" это хорошо работает с NAT "Cone" (Cone - это техническое семейство маршрутизаторов).Это не на 100% надежный метод, сегодня он хорошо работает с UDP примерно на 80% маршрутизатора.
Существует несколько реализаций библиотеки для реализации пробивки отверстий: ОГЛУШИТЬ (википедия)
Я полагаю, что простая версия заключается в том, что они удаляют соединение с сервером и заменяют его P2P-соединением.
Что-то вроде:
- Machine1 подключается к серверам второго пилота.
- Machine1 подключается к серверам второго пилота.
- Machine1 подключается к серверам второго пилота.
- Впоследствии Machine2 подключается, и они начинают совместное использование экрана.
- Machine2 открывает порт, предназначенный для подключения Machine1.
- Machine1 пытается подключиться к уже открытому порту Machine2.
Если это соединение установлено:
- Соединение с серверами второго пилота разорвано.
- Вместо этого данные передаются по прямому (P2P) соединению между двумя компьютерами.