Широковещательный IP: порт по сокет-серверу - PullRequest
1 голос
/ 05 октября 2011

Я пытаюсь найти способ для клиента узнать IP-порт сокет-сервера, не определяя его явно.Обычно у меня есть сокет-сервер, работающий на переносном устройстве, который подключен к сети через DHCP (через WiFi), и в идеале клиенты должны иметь возможность его автоматически находить.

Так что я думаю, вопрос в том, может ли сокет-сервер каким-либо образом транслироватьэто адрес по локальной сети?Я думаю, что UPnP может сделать это, но я бы предпочел не вдаваться в подробности.

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

Ответы [ 2 ]

3 голосов
/ 05 октября 2011

Один из способов сделать это - через широковещательные пакеты UDP.См. Руководство Beej , если вы используете разъемы BSD.И здесь - это та же версия Microsoft.

Если все клиенты приложения находятся на одной стороне маршрутизатора, тогда широковещательный адрес 255.255.255.255 (или ff02::1 дляIPv6) должно быть более чем адекватным.

Многоадресная рассылка - это еще один вариант, но если это только для локальной сети, я не думаю, что это необходимо.

Предложение

Выберите номер порта UDP (скажем, дляради примера выберем 1667).Клиент должен прослушивать UDP-сообщения на 255.255.255.255:1667 (или на другом эквиваленте. Например: IPEndPoint(IPAddress.Any, 1667)).Сервер должен транслировать сообщения по тому же адресу.

Предложение формата

Пакет UDP: первые четыре байта в качестве магического числа, следующие четыре байта - адрес IPv4 (и вы можете захотеть добавить другие вещикак имя сервера).

Магическое число на случай, если произойдет столкновение с другим приложением, использующим тот же порт.Проверьте длину пакета и магическое число.

Сервер будет транслировать пакет с интервалом примерно в 30 секунд.(В качестве альтернативы сервер может отправлять ответ только тогда, когда клиент отправляет запрос через широковещательную рассылку.)

1 голос
/ 26 февраля 2018

Некоторые параметры:

  • DNS-SD (что, по-видимому, переводится как «Apple Bonjour»): у него есть библиотеки на macOS, но для этого нужно установить Bonjourсервис на винде.Я не знаю ситуацию с Linux для этого.Так что это мультиплатформенная, но вам нужны внешние библиотеки.
  • широковещание UDP или многоадресная рассылка
  • Некоторые другие интересные вещи, такие как широковещание Ethernet, необработанные сокеты, ...

Для вашего случая (клиенты в сети WiFi) достаточно широковещательного пакета UDP, он мультиплатформенный и не слишком сложный для реализации с нуля.

При выборе этой опции два основных алгоритма::

  1. Сервер (-ы) отправляет широковещательный пакет "анонс", когда клиенты прослушивают широковещательный адрес.Как только клиенты получают пакет «анонс», они узнают об адресе сервера.Теперь они могут отправлять UDP-пакеты на сервер (который обнаружит их адреса для отправки ответа) или подключаться по протоколу TCP.

  2. Клиенты отправляют широковещательный пакет "обнаружение"с сервером (ами), прослушивающими широковещательный адрес.Как только сервер (ы) получит пакет «обнаружение», он может ответить на него напрямую «объявить» UDP-пакет.

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

Пожалуйста, примите во внимание следующие аргументы:

  • Серверы обычно прослушивают запросы и отправляют ответы
  • Сервер, который отправляет регулярные "анонсированные" широковещательные пакеты по WiFiсеть, для клиента, который может прибыть или нет, тратит впустую пропускную способность сети, в то время как клиент точно знает, когда ему нужно опросить для доступных серверов, и остановиться, как только это будет сделано.Сочетание этих двух параметров позволяет серверу отправлять широковещательный пакет с произвольным объявлением после его поступления, а затем он может прослушивать «обнаружение» широковещательных запросов от клиентов, отвечая непосредственно на один из них с помощью обычного UDP-пакета.*

    С этого момента клиент может продолжить работу по мере необходимости: отправлять прямые запросы с UDP на сервер, подключаться к TCP-адресу: порт, указанный в поле «announce»cket, ...

    (это схема, которую я использовал в приложении, над которым я работаю)

...