Сеть UDP вещания дизайн?

Я работаю над парой клиентских приложений c++ server/.NET, в которой мой сервер (который запускает c++ в linux) транслирует сообщение, чтобы показать, что он жив для всей сети, и моя программа .NET прослушивает пакеты и анализирует, чтобы получить время работы сервера.

Как я прочитал, чтобы отправить регулярную трансляцию UDP на широковещательный адрес, я просто должен отправить пакет в 192.168.0.255 (в моем случае 192.168.2.255) или 255.255.255.255. Это правда? Могу ли я использовать тот же порт адрес? Есть еще что-нибудь необходимое?

Я понимаю, что если моя программа .NET прослушивает этот конкретный адрес, можно получать пакеты из других приложений, чем моя программа сервера C++. Есть ли способ "подписания" пакета на стороне сервера C++, чтобы моя программа .NET прочитала заголовок пакета и увидела, что это (почти) тот, который я ищу?

3 ответов


вне зависимости от языка, который вы используете, вот мой ответ:

Что касается широковещательных IP-адресов, оба адреса являются широковещательными адресами, но ограниченный широковещательный адрес (который является 255.255.255.255) не будет перенаправлен маршрутизаторами. Лучше использовать широковещательный адрес, направленный на подсеть (192.168.2.255).

для отправки / получения широковещательного адреса необходимо определить широковещательный адрес (широковещательный IP-адрес и номер порта). Например: 192.168.2.255 и порт 3000. Клиентские приложения (отправители) должны включить параметр сокета SO_BROADCAST следующим образом:

int enabled = 1;
setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &enabled, sizeof(enabled));

где sockfd-дескриптор сокета.

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

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

для клиентских приложений полученный пакет является одноадресным (если у вас нет другого дизайна). Так что никакого конфликта с этой стороны.


вы также должны включить опцию сокета SO_BROADCAST в C++ для отправки широковещательного трафика, или вы получите ошибку отказа в разрешении:

int broadcastPermission = 1;
setsockopt(socketDescriptor, SOL_SOCKET, SO_BROADCAST, (void*)&broadcastPermission, sizeof(broadcastPermission))

Если ваша программа .NET прослушивает широковещательный трафик, она получит любой широковещательный трафик в сети, отправленный на этот порт, включая трафик, не отправленный вашим сервером. Вы можете поместить "маркер" в полезную нагрузку широковещательных сообщений, отправленных вашим сервером. Таким образом, ваша программа .NET может различать, какие из них она заботится.

помимо этого, я бы рекомендовал использовать мультикаст вместо трансляции. Широковещательный трафик обычно ограничен хостами на том же подсеть. С точки зрения непрофессионала, если у вас есть маршрутизатор в вашей сети, Хост на стороне a маршрутизатора не будет видеть широковещательный трафик, отправленный хостом на стороне B (и наоборот), потому что маршрутизатор "блокирует" его. Маршрутизаторы почти всегда будут пересылать многоадресный трафик, если хост присоединился к многоадресной группе.