Как отправить широковещательный запрос
Перейти к содержимому

Как отправить широковещательный запрос

  • автор:

Как сделать широковещательный запрос в сети

Доброго времени форумчане, имеется сервер к которому подключено более 300 устройств, со своими известными заранее адресами, требуется сделать широковещательный запрос раз в минуту что бы видеть какое из устройств отвалилось. В последствии ответы будут обрабатываться программой (написанной на python). Тупо использовать пинг не хочу т.к долго будут идти опросы.

94731 / 64177 / 26122

Регистрация: 12.04.2006

Сообщений: 116,782

Ответы с готовыми решениями:

Две разные сети. Как сделать доступ на только на DVR из одной сети в другую?
Добрый день! Столкнулся с такой проблемой: на одном предприятии есть две совершенно разные.

Широковещательный запрос в локальной сети
Прошу подсказать или показать на примере, как делаются широковещательные запросы по локалке.

UDP широковещательный запрос
Написал сервер и клиент по этому примеру http://www.baeldung.com/udp-in-java, но он работает только.

Client/server широковещательный запрос

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

#include #include #include #include #include #include #include #include #define DEFPORT 5000 #define DEFNUM 3 typedef struct options < int port; int number; >info_t; /* * ip port * number of connection for work */ static int server(int port, int nmax) < int sock; struct sockaddr_in server; int mysock; char buff[1024]; int rval; int n = 0; /* Create socket */ sock = socket (AF_INET, SOCK_STREAM, 0); if (sock < 0) < perror("create socet failure"); return -1; >server.sin_family = AF_INET; server.sin_addr.s_addr = INADDR_ANY; server.sin_port = htons(port); /* Call bind */ if (bind(sock, (struct sockaddr *)&server, sizeof(server))) < perror("bind failed"); return -1; >/*listen*/ listen(sock, 5); /* Accept */ while (n < nmax) < mysock = accept(sock, (struct sockaddr *) 0, 0); if (mysock == -1) < perror("accept failed"); >else < memset(buff, 0, sizeof(buff)); if ((rval = recv(mysock, buff, sizeof(buff), 0)) < 0) < perror("reading stream message error"); >else if (rval == 0) < printf("Ending connection\n"); >else < printf("MSG: %s\n",buff); printf("Got message (rval = %d)\n", rval); n++; >close(mysock); > > return 0; > static void parse_args(int argc, char *argv[], info_t *info) < int rez = 0; int p = info->port, n = info->number; while ((rez = getopt(argc, argv, "p:n:h")) != -1) < switch (rez) < case 'p': p = atoi(optarg); if (p = 65535) p = DEFPORT; break; case 'n': n = atoi(optarg); if (n > info->port = p; info->number = n; > int main (int argc, char *argv[]) < info_t info = < .port = DEFPORT, .number = DEFNUM >; parse_args(argc, argv, &info); server(info.port, info.number); return 0; > 

код клиента:

#include #include #include #include #include #include #include #include #include #define DATA "HI MANN" /* * ip mask * ip port * message */ int main (int argc, char *argv[]) < int sock; struct sockaddr_in server; struct hostent *hp; char buff[1024]; char *ip = "127.0.0.1"; int port = (5000); if (argc >1) < ip = argv[1]; >sock = socket (AF_INET, SOCK_STREAM, 0); if(sock < 0)< perror("не удалось создать сокет"); return -1; >server.sin_family = AF_INET; printf("send to: %s\n", ip); hp = gethostbyname(ip); if(hp == 0) < perror("gethostbyname failed"); close(sock); return -1; >memcpy(&server.sin_addr,hp->h_addr, hp->h_length); server.sin_port = htons (port); if(connect (sock,(struct sockaddr *) &server, sizeof(server)) < 0)< perror("connect failed"); close(sock); return -1; >if(send(sock,DATA, sizeof(DATA), 0) < 0)< perror("send failed"); close(sock); return -1; >printf("sent %s\n", DATA); close(sock); return -1; > 

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

Артём Санников

Данная книга является руководством для начинающих специалистов в области анализа и обработки данных. В книге рассматривается язык SQL и его процедурное расширение PL/SQL от компании Oracle.

Главная › Cisco › CCNA: Introduction to Networks › Сетевые IPv4-адреса. Широковещательная рассылка. CCNA Routing and Switching.

Сетевые IPv4-адреса. Широковещательная рассылка. CCNA Routing and Switching.

Широковещательная передача используется для отправки пакетов всем узлам в сети через широковещательный сетевой адрес. Пакет широковещательной рассылки содержит IPv4-адрес назначения, в узловой части которого присутствуют только единицы (1). Это означает, что пакет получат и обработают все узлы в локальной сети (домене широковещательной рассылки). Широковещательные рассылки предусмотрены во многих сетевых протоколах, например DHCP. Когда узел получает пакет, отправленный на широковещательный сетевой адрес, узел обрабатывает пакет так же, как и пакет, отправленный на адрес одноадресной рассылки.

Есть два типа широковещательной рассылки: направленная и ограниченная. Направленная широковещательная рассылка отправляется всем узлам в конкретной сети. Например, узел в сети 172.16.4.0/24 отправляет пакет на адрес 172.16.4.255. Ограниченная широковещательная рассылка отправляется на адрес 255.255.255.255. По умолчанию, маршрутизаторы не пересылают широковещательные рассылки.

Например, узел в пределах сети 172.16.4.0/24 отправляет широковещательную рассылку всем узлам внутри своей сети, используя пакет с адресом назначения 255.255.255.255.

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

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

Источник: Академия Cisco.

Записи по теме

  • Разделение IPv4-сети на подсети. Формулы разделения на подсети. CCNA Routing and Switching.
  • Разделение IPv4-сети на подсети. Разделение IPv4-сети на подсети. CCNA Routing and Switching.
  • Разделение IPv4-сети на подсети. Разделение на подсети на границе октетов. CCNA Routing and Switching.
  • Разделение IPv4-сети на подсети. Границы октетов. CCNA Routing and Switching.
  • Сегментация сети. Причины для разделения на подсети. CCNA Routing and Switching.
  • Сегментация сети. Проблемы с крупными широковещательными доменами. CCNA Routing and Switching.
  • Сегментация сети. Широковещательные домены. CCNA Routing and Switching.
  • Сетевые IPv6-адреса. Групповые IPv6-адреса для поиска узла. CCNA Routing and Switching.

Как отправить широковещательный запрос

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

При использовании широковещательной передачи надо учитывать, что передача не идет дальше локальных сетей, так как маршрутизаторы подобные рассылки не пропускают.

Присоединение к группе. JoinMulticastGroup и DropMulticastGroup

Широковещательная групповая рассылка доступна только для группы. Чтобы добавить клиент UdpClient в группу, у него вызывается метод JoinMulticastGroup() . Одна из его версий:

public void JoinMulticastGroup (System.Net.IPAddress multicastAddr); public void JoinMulticastGroup (System.Net.IPAddress multicastAddr, int timeToLive);

В качестве параметра в метод передается адрес группы. В качестве адреса может использоваться один из адресов в диапазоне от 224.0.0.0 до 239.255.255.255. Если будет передан другой адрес, либо если роутер не поддерживает групповую рассылку, то приложение сгенерирует исключение SocketException.

Второй параметр — timeToLive представляет число проходов через маршрутизаторы. То есть пока сообщение достигнет получателя, оно может пройти через некоторое число маршрутизаторов, которые направят его по нужному пути. Например, число 50 означает, что чтобы пройти от компьютера-отправителя к компьютеру-получателю, дейтаграмма может миновать 50 маршрутизаторов.

После вызова этого метода неявно используемый объект Socket посылает роутеру пакет данных в формате IGMP (Internet Group Management Protocol) для присоединения к группе. И далее объект UdpClient сможет получать дейтаграммы, которые предназначаются всей группы объектов UdpClient.

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

Для удаления из группы у UdpClient вызывается метод DropMulticastGroup() :

public void DropMulticastGroup (System.Net.IPAddress multicastAddr);

В метод передается тот же адрес группы, который передавался в JoinMulticastGroup :

using var udpClient = new UdpClient(); var brodcastAddress = IPAddress.Parse("235.5.5.11"); ; // хост для отправки данных udpClient.JoinMulticastGroup(brodcastAddress); // . рассылка и получение сообщений udpClient.DropMulticastGroup(brodcastAddress);

Рассмотрим на небольшом примере. Сначала определим Udp-клиент, который будет получать сообщения по широковещательной рассылке:

using System.Net.Sockets; using System.Net; using System.Text; using var udpClient = new UdpClient(8001); var brodcastAddress = IPAddress.Parse("235.5.5.11"); ; // хост для отправки данных // присоединяемся к группе udpClient.JoinMulticastGroup(brodcastAddress); Console.WriteLine("Начало прослушивания сообщений"); while (true) < var result = await udpClient.ReceiveAsync(); string message = Encoding.UTF8.GetString(result.Buffer); if (message == "END") break; Console.WriteLine(message); >// отсоединяемся от группы udpClient.DropMulticastGroup(brodcastAddress); Console.WriteLine("Udp-клиент завершил свою работу");

Здесь клиент прослушивает подключения на порту 8001. Кроме того, он подключен к группе по адресу «235.5.5.11».

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

Таким образом, данный клиент будет получать сообщения из группы «235.5.5.11:8001». Для теста определим программу-отправитель, которая будет отправлять данные в эту группу:

using System.Net; using System.Net.Sockets; using System.Text; var messages = new string[] < "Hello World!", "Hello METANIT.COM", "Hello work", "END" >; var brodcastAddress = IPAddress.Parse("235.5.5.11"); ; // хост для отправки данных using var udpSender = new UdpClient(); Console.WriteLine("Начало отправки сообщений. "); // отправляем сообщения foreach(var message in messages) < Console.WriteLine($"Отправляется сообщение: "); byte[] data = Encoding.UTF8.GetBytes(message); await udpSender.SendAsync(data, new IPEndPoint(brodcastAddress, 8001)); await Task.Delay(1000); >

Здесь обычный клиент UdpClient отправляет все сообщения из массива messages. При этом UdpClient не добавлен ни в какую группу. Но обратите внимание на адрес отправки — 235.5.5.11:8001 — тот же адрес, по которому выше определенный клиент получает сообщения из группы.

Запустим сначала программу Udp-клиента, который получает сообщения из группы. А затем запустим программу-отправитель. Консоль отправителя отобразит процесс отправки сообщений:

Начало отправки сообщений. Отправляется сообщение: Hello World! Отправляется сообщение: Hello METANIT.COM Отправляется сообщение: Hello work Отправляется сообщение: END

а консоль программы клиента-получателя отобразит процесс получения данных:

Начало прослушивания сообщений Hello World! Hello METANIT.COM Hello work Udp-клиент завершил свою работу

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

Получение и отправка сообщений в одном приложении

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

using System.Net; using System.Net.Sockets; using System.Text; int localPort = 8001; IPAddress brodcastAddress = IPAddress.Parse("235.5.5.11"); Console.Write("Введите свое имя: "); string? username = Console.ReadLine(); Task.Run(ReceiveMessageAsync); await SendMessageAsync(); // отправка сообщений в группу async Task SendMessageAsync() < using var sender = new UdpClient(); // создаем UdpClient для отправки // отправляем сообщения while (true) < string? message = Console.ReadLine(); // сообщение для отправки // если введена пустая строка, выходим из цикла и завершаем ввод сообщений if (string.IsNullOrWhiteSpace(message)) break; // иначе добавляем к сообщению имя пользователя message = $": "; byte[] data = Encoding.UTF8.GetBytes(message); // и отправляем в группу await sender.SendAsync(data, new IPEndPoint(brodcastAddress, localPort)); > > // получение сообщений из группы async Task ReceiveMessageAsync() < using var receiver = new UdpClient(localPort); // UdpClient для получения данных receiver.JoinMulticastGroup(brodcastAddress); receiver.MulticastLoopback = false; // отключаем получение своих же сообщений while (true) < var result = await receiver.ReceiveAsync(); string message = Encoding.UTF8.GetString(result.Buffer); Console.WriteLine(message); >>

Теперь для групповой рассылки в локальной сети будет использоваться адрес «235.5.5.11», в качестве порта — 8001.

После ввода имени пользователя запускается новая задача, которая выполняет метод ReceiveMessageAsync() для получения данных. В этом методе создается UdpClient для получения данных. Он присоединяется к группе. И важный момент, чтобы сообщения этого же клиента не транслировались ему самому, устанавливаем false для свойства MulticastLoopback :

receiver.MulticastLoopback = false;

Далее в бесконечном цикле считываем входящие сообщения и выводим их на консоль.

Также в основном потоке запускается асинхронный метод SendMessageAsync(). В нем в бесконечном цикле считываем с консоли введенное сообщение и отправляем в группу, добавляя к сообщению имя пользователя. Если же пользователь ввел пустую строку, то выходим из цикла и тем самым завершаем выполнение метода и всего приложения.

После построения проекта мы можем запустить скомпилированное приложение на разных машинах в локальной сети.

Введите свое имя: Евгений Олег: привет чат привет Олег Олег: тест
Введите свое имя: Олег привет чат Евгений: привет Олег тест

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *