Зарезервируйте порт TCP в Windows - PullRequest
13 голосов
/ 10 марта 2011

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

Как процесс может зарезервировать порт, не привязывая его / не прослушивая его, а затем безопасно (т. е. чтобы избежать условий гонки) передать его другому процессу по запросу?

Номер порта не нужно определять заранее.Первый процесс может получить случайный номер порта и передать его запрашивающему процессу.

РЕДАКТИРОВАТЬ: Мне приходит в голову, что мой вопрос несколько плохо сформулирован.Что я действительно хочу, так это отделить распределение номера динамического порта от операции привязки к порту-ноль.Это означает не только предотвращение случайного случайного распределения этого номера порта, но также предотвращение привязки любого другого процесса к тому же адресу / порту в промежуточный период.Или, говоря иначе, я хочу, чтобы один процесс запустил операцию bind-to-port-zero - сразу узнал номер порта, который будет использоваться - и позволил назначенному второму процессу завершить операцию bind когда-нибудь в будущем.

В настоящий момент самый близкий обходной путь, о котором я могу подумать, - это чтобы первый процесс немедленно связался с address / 0 и оставался связанным до тех пор, пока второй процесс не запросит его, после чего он отсоединится и сообщит другому процессуномер порта, который он получил, который затем явно привязывается к адресу / порту.У этого есть две проблемы: 1) я бы предпочел не связываться вообще, пока не наступит второй процесс;2) существует небольшой интервал времени, в течение которого третья сторона может случайно (или намеренно) узурпировать порт.

Справочная информация

Вам может быть любопытно, почему я хочу сделать что-то странное.Я играл с ZeroMQ, и одним из основных ограничений является отсутствие транспорта ipc:// в Windows.Меня поразило, что процесс сопоставления портов (похожий на сопоставление конечных точек RPC или epmd Эрланга) был бы просто билетом для реализации обходного пути с использованием транспорта tcp:// с динамическим распределением портов.Тем не менее, клиентам и серверам ZeroMQ разрешается подключаться не по порядку (т. Е. Клиент не ошибается при подключении до привязки сервера), поэтому я пытаюсь выяснить, как подключающийся клиент может обнаружить - с оченьвысокая степень уверенности - порт, который будет использоваться для связи до того, как сервер фактически подключится к этому порту.

Ответы [ 5 ]

6 голосов
/ 06 июня 2016

Как уже упоминалось @vahapt, вы можете изменить динамический диапазон портов, используя netsh.

Однако лучшим решением может быть использование netsh для резервирования портов, необходимых для вашего приложения, оставляя в покое диапазон динамических портов по умолчанию.

Для этого:

  1. На сервере 2008/2008 R2 установите это Исправление Microsoft . Это не требуется на Server 2012 или более поздней версии.
  2. Остановите все процессы, использующие зарезервированные порты. Если процесс использует порт, включенный в диапазон портов, которые должны быть зарезервированы, NETSH возвратит следующую ошибку, и резервирование завершится ошибкой:

    Процесс не может получить доступ к файлу, поскольку он используется другим процессом.

  3. Используйте следующую команду NETSH для резервирования портов:

    netsh int <ipv4|ipv6> Add excludedportrange [protocol=]tcp|udp [startport=]<integer> [numberofports=]<integer> [[store=]active|persistent]

    Например, чтобы зарезервировать порты 55368-55372 для UDPv6, используйте команду:

    netsh int ipv6 add excludedportrange protocol=udp startport=55368 numberofports=5

Примечания:

  • По умолчанию резервирование портов сохраняется после перезагрузки
  • Порты могут быть зарезервированы для версии 4 или 6 протокола, но не для обоих (т.е. вы не можете зарезервировать порт 60000 для TCPv4 и TCPv6)

См. https://support.microsoft.com/en-us/kb/929851 для получения дополнительной информации, в том числе о том, как просмотреть или удалить существующие резервирования портов.

5 голосов
/ 10 марта 2011

Использование команды netsh может помочь вам. Вы можете изменить динамический диапазон портов, используемый Windows.
Это похоже на изменение реестра, которое вы указали, но оно вступает в силу немедленно.

см. http://support.microsoft.com/kb/929851 для получения подробной информации о команде netsh.

4 голосов
/ 02 февраля 2012

Редактировать: Это относится только к пред-Windows Server 2008 ( Поддержка Microsoft KB )

Вы можете редактировать параметр реестра 'ReservedPorts' в

HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Services \ Tcpip \ Parameters

Чтобы зарезервировать диапазон портов, следуйте формату '4000-4010' или 'xxxx-yyyy', однако, чтобы зарезервировать один порт, который вы должны использоватьформат '4000-4000' или 'xxxx-xxxx'

http://support.microsoft.com/kb/812873

2 голосов
/ 15 марта 2011

Я придумала возможное решение, поэтому я подумала, что я также могу задокументировать его здесь как ответ.

Процесс может передать сокет другому процессу через вызов WSADuplicateSocket, поэтомукоординирующий процесс может связываться с динамическим портом и внутренне связывать его с заданным именем IPC.Когда приходит процесс сервера ZMQ, желающий «привязать» к этому имени, координирующий процесс копирует связанный сокет в процесс сервера и закрывает свою собственную копию.

Это решение не учитывает мои предпочтения, чтобы избежать вызова привязки(), но это, возможно, не является строго необходимым;Мне придется выполнить несколько тестов.

0 голосов
/ 13 марта 2015

Для ZeromMQ вы можете использовать модуль zbeacon из czmq или C # NetMq для реализации обнаружения служб.

...