Получите случайный порт для сокета UDP

Мне нужно создать программу, которая будет общаться с другими программами на том же компьютере через сокеты UDP. Он будет читать команды из stdin, и некоторые из этих команд заставят его отправлять/получать пакеты без остановки выполнения. Я прочитал некоторую информацию там, но так как я не знаком с программированием сокетов и мне нужно быстро это сделать, у меня есть следующие вопросы:

  • Мне нужно получить случайный неиспользуемый порт для прослушивания программы и зарезервировать его, чтобы другие программы могли общаться с этим, а также порт не был зарезервирован другой программой. Мне также нужно сохранить номер порта в переменной для будущего использования.
  • Поскольку связь происходит через процессы на одном компьютере, мне интересно, могу ли я использовать PF_LOCAL.

Также будет полезен пример кода для установки такого сокета, а также пример отправки/получения символов.

Ответ 1

Вызвать bind() указать порт 0. Это позволит ОС выбрать неиспользуемый порт. Затем вы можете использовать getsockname() для возврата выбранного порта.

Ответ 2

Ответ Remy Lebeau хорош, если вам нужен временный порт. Это не так хорошо, если вам нужен постоянный зарезервированный порт, потому что другое программное обеспечение также использует тот же метод для получения порта (включая стек стека ОС, которому нужен новый временный порт для каждого подключения).

Так может случиться следующее:

  • Вы вызываете bind с 0 и getsockname(), чтобы получить порт;
  • затем сохраните его в config (или в нескольких конфигурациях) для использования в будущем;
  • которому нужен этот порт, запускается и связывает порт.

Тогда вам нужно, например, перезапустите программное обеспечение:

  • программное обеспечение останавливает и отвязывает порт: теперь порт может быть возвращен bind (0) и getsockname() еще раз;
  • например. TCP-стек требует порт и связывает ваш порт;
  • не удается запустить программное обеспечение, поскольку порт уже связан.

Итак, для "будущих применений" вам нужен порт, который не находится в эфемерном диапазоне портов (диапазон, из которого bind (host, 0) возвращает порт).

Мое решение для этой проблемы - port-for утилита командной строки.

Ответ 3

Если это случайный порт действительно важен, вы должны сделать что-то вроде:

srand(time(NULL));
rand() % NUM_PORTS; // NUM_PORTS isn't a system #define

Затем укажите этот порт в bind. Если он терпит неудачу, выберите новый (нет необходимости повторно забирать случайный генератор. Если случайный порт не важен, посмотрите на ответ Реми Лебо.