Получение неиспользуемого номера порта в C динамически при запуске процесса сервера - PullRequest
4 голосов
/ 23 сентября 2011

Я использую C и пишу клиент-серверную программу и хотел бы получить номер неиспользуемого порта для запуска процесса на моем сервере. Мой код сервера выглядит так:

getaddrinfo()
socket()
bind()
listen
while(1)
  accept()

Мне нужно предоставить неиспользуемый порт addr для вызова bind (). Но я не хочу передавать номер порта через командную строку при запуске процесса сервера. Номер порта должен быть получен через вызов сокета, и мне нужно использовать его для запуска моего клиентского процесса. Есть ли какой-либо вызов сокета, который помог бы мне динамически получить неиспользуемый порт в C?

Ответы [ 4 ]

8 голосов
/ 23 сентября 2011

Просто bind () для вашего сокета установит sin_port в 0 в sockaddr_in.Система автоматически выберет неиспользуемый порт.Вы можете получить его, вызвав getsockname ().

Но я понятия не имею, как передать его клиенту, кроме его печати и использования в качестве параметра командной строки для клиентской программы.

1 голос
/ 26 сентября 2011

Поскольку вы работаете в Linux / Unix, это именно та ситуация, для решения которой был разработан RPM portmapper. Ваш сервер bind() s подключается к неиспользуемому порту (порт 0), затем регистрирует результирующий фактический порт (выбирается с помощью getsockname() с помощью portmapper по имени приложения / службы.

Затем клиенты запрашивают portmapper на своем известном порте, спрашивая, на каком порту в действительности работает названная служба.

RPC portmapper не так популярен, как раньше

Если серверы и клиенты находятся в одном окне:

Другой альтернативой является использование какой-либо схемы именования для общего файла (создайте временный файл /tmp/servport.xxxxx), заменив xxxxx на порт.

Или вы можете создать сегмент разделяемой памяти, в который сервер сохраняет свой порт. Клиенты будут подключаться к той же общей памяти, читать порт и подключаться как обычно.

Или ваш сервер может создать сокет домена unix по известному / общему пути, и клиенты могут подключиться к нему, спрашивая, на каком порту находится сервер. (очевидно, вы могли бы просто сделать все IPC таким образом, если они оба локальные!)

Множество опций с IPC ...

1 голос
/ 23 сентября 2011

Это было бы огромное состояние гонки . Представьте себе эту последовательность событий:

  1. Ваш код использует (не существующий) вызов getNextFreePort().
  2. Другой процесс создает новый сокет без указания порта, получая присвоенный ему «ваш» номер.
  3. Вы пытаетесь bind(), который завершается неудачно с "используемым адресом".

Вот почему серверы, как правило, имеют «общеизвестные» адреса, поскольку это необходимо для того, чтобы клиент знал, куда ему следует подключиться.

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

0 голосов
/ 23 сентября 2011

Если вы связываете () со случайным или непредсказуемым адресом + номером порта, клиенты могут испытывать некоторые трудности с поиском вашего сервера и подключением к нему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...