20.4. Функция dg_cli при использовании широковещательной передачи

20.4. Функция dg_cli при использовании широковещательной передачи

Мы еще раз изменим нашу функцию dg_cli, на этот раз дав ей возможность отправлять широковещательные сообщения стандартному серверу времени и даты UDP (см. табл. 2.1) и выводить все ответы. Единственное изменение, внесенное нами в функцию main (см. листинг 8.3), состоит в изменении номера порта получателя на 13:

servaddr.sin_port = htons(13);

Сначала мы откомпилируем измененную функцию main с прежней функцией dg_cli из листинга 8.4 и запустим ее на узле freebsd:

freebsd % udpcli01 192.168.42.255

hi

sendto error: Permission denied

Аргумент командной строки — это широковещательный адрес подсети для присоединенной сети Ethernet. Мы вводим строку, программа вызывает функцию sendto, и возвращается ошибка EACCESS. Мы получаем ошибку, потому что нам не разрешается посылать дейтаграмму на широковещательный адрес получателя, если мы не указали ядру явно, что будем передавать широковещательное сообщение. Мы выполняем это условие, установив параметр сокета SO_BROADCAST (см. табл. 7.1).

ПРИМЕЧАНИЕ

Беркли-реализации реализуют эту «защиту от дурака» (sanity check). Однако Solaris 2.5 принимает дейтаграмму, предназначенную для широковещательного адреса, даже если мы не задаем параметр сокета SO_BROADCAST. Стандарт POSIX требует установки параметра сокета SO_BROADCAST для отправки широковещательной дейтаграммы.

В 4.2BSD широковещательная передача была привилегированной операцией, и параметра сокета SO_BROADCAST не существовало. В 4.3BSD этот параметр был добавлен и каждому процессу стало разрешено его устанавливать.

Теперь мы изменим нашу функцию dg_cli, как показано в листинге 20.1[1]. Эта версия устанавливает параметр сокета SO_BROADCAST и выводит все ответы, полученные в течение 5 с.

Листинг 20.1. Функция dg_cli, осуществляющая широковещательную передачу

//bcast/dgclibcast1.c

 1 #include "unp.h"

 2 static void recvfrom_alarm(int);

 3 void

 4 dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)

 5 {

 6  int n;

 7  const int on = 1;

 8  char sendline[MAXLINE], recvline[MAXLINE + 1];

 9  socklen_t len;

10  struct sockaddr *preply_addr;

11  preply_addr = Malloc(servlen);

12  Setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));

13  Signal(SIGALRM, recvfrom_alarm);

14  while (Fgets(sendline, MAXLINE, fp) != NULL) {

15   Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);

16   alarm(5);

17   for (;;) {

18    len = servlen;

19    n = recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len);

20    if (n < 0) {

21     if (errno == EINTR)

22      break; /* окончание ожидания ответов */

23     else

24      err_sys("recvfrom error");

25    } else {

26     recvline[n] = 0; /* завершающий нуль */

27     printf("from %s: %s",

28      Sock_ntop_host(preply_addr, len), recvline);

29    }

30   }

31  }

32  free(preply_addr);

33 }

34 static void

35 recvfrom_alarm(int signo)

36 {

37  return; /* прерывание recvfrom() */

38 }

Выделение памяти для адреса сервера, установка параметра сокета

11-13 Функция malloc выделяет в памяти пространство для адреса сервера, возвращаемого функцией recvfrom. Устанавливается параметр сокета SO_BROADCAST, устанавливается обработчик сигнала SIGALRM.

Чтение строки, отправка сокету, чтение всех ответов

14-24 Следующие два вызова, fgets и sendto, выполняются так же, как и в предыдущих версиях этой функции. Но поскольку мы посылаем широковещательную дейтаграмму, мы можем получить множество ответов. Мы вызываем в цикле функцию recvfrom и выводим все ответы, полученные в течение 5 с. По истечении 5 с генерируется сигнал SIGALRM, вызывается наш обработчик сигнала и функция recvfrom возвращает ошибку EINTR.

Вывод каждого полученного ответа

25-29 Для каждого полученного ответа мы вызываем функцию sock_ntop_host, которая в случае IPv4 возвращает строку, содержащую IP-адрес сервера в точечно-десятичной записи. Эта строка выводится вместе с ответом сервера.

Если мы запустим программу, задав широковещательный адрес подсети 192. 168.42.255, мы увидим следующее:

bsdi % udpcli01 192.168.42.255 hi

from 192 168.42 2: Sat Aug 2 16.42.45 2003

from 192.168.42.1: Sat Aug 2 14.42.45 2003

from 192.168.42.3: Sat Aug 2 14.42.45 2003

hello

from 192.168.42.3: Sat Aug 2 14.42.57 2003

from 192.168.42.2: Sat Aug 2 16.42.57 2003

from 192.168.42.1: Sat Aug 2 14.42.57 2003

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

Все системы сообщают одно и то же время, поскольку на них используется NTP (Network Time Protocol — протокол синхронизации времени).

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг

Проблемы при использовании

Из книги Разгони свой сайт автора Мациевский Николай

Проблемы при использовании Даже если положиться на то, что спрайты поддерживаются (почти) всеми браузерами на данный момент, все равно остается достаточно много вопросов, которые они не только не решают, а скорее сами создают. Во-первых, это проблемы при использовании


Простота в использовании

Из книги Skype: бесплатные звонки через Интернет. Начали! автора Гольцман Виктор Иосифович

Простота в использовании После правильной установки и настройки пользоваться системой VoIP-телефонии не сложнее, чем обычным телефоном. Принцип все тот же: вы снимаете трубку, ждете гудка, набираете номер, а когда собеседник отвечает, начинаете разговор. Конечно, если


Отсутствие поддержки ограничений при использовании операций

Из книги Язык программирования С# 2005 и платформа .NET 2.0. [3-е издание] автора Троелсен Эндрю

Отсутствие поддержки ограничений при использовании операций При создании обобщенных методов для вас может оказаться сюрпризом появление ошибок компилятора, когда с параметрами типа используются операции C# (+, -, *, == и т.д.). Например, я уверен, вы сочли бы полезными классы


Отчет об использовании дискового пространства

Из книги Windows Script Host для Windows 2000/XP автора Попов Андрей Владимирович

Отчет об использовании дискового пространства Напишем сценарий DrivesReport.js, который будет создавать таблицу использования дискового пространства для дисков всех типов (съемных, жестких и сетевых), имеющихся на компьютере, в следующем формате: Диск: буква_диска  Метка


2.1.9. Передача данных при использовании UDP

Из книги О чём не пишут в книгах по Delphi автора Григорьев А. Б.

2.1.9. Передача данных при использовании UDP Мы наконец-то добрались до изучения того, ради чего сокеты и создавались: как передавать и получать с их помощью данные. По традиции начнем рассмотрение с более простого протокола UDP. Функции, которые рассматриваются в этом разделе,


2.1.11. Передача данных при использовании TCP

Из книги Сетевые средства Linux автора Смит Родерик В.

2.1.11. Передача данных при использовании TCP При программировании TCP и UDP применяются одни и те же функции, но их поведение при этом различно. Для передачи данных с помощью TCP необходимо сначала установить соединение, и после этого возможен обмен данными только с тем адресом, с


3.4.5. Ошибка EReadError при использовании вещественных свойств

Из книги VBA для чайников автора Каммингс Стив

3.4.5. Ошибка EReadError при использовании вещественных свойств Если в секции published компонента имеются свойства вещественного типа (Single, Double или Extended), то попытка присвоить в режиме проектирования формы этим свойствам некоторые вполне корректные значения приводит к ошибке


Повышение уровня защиты при использовании CGI-сценариев

Из книги Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ автора Борри Хелен

Повышение уровня защиты при использовании CGI-сценариев Если на Web-узле присутствуют CGI-сценарии, любой пользователь, работающий с Web-броузером, имеет возможность запустить на стороне сервера программу. Это может стать источником проблем, связанных с безопасностью


Вопросы защиты при использовании VPN

Из книги UNIX: разработка сетевых приложений автора Стивенс Уильям Ричард

Вопросы защиты при использовании VPN Система VPN призвана повысить безопасность при обмене по сети. Однако она же может открыть злоумышленнику доступ к сетевым ресурсам. Взаимодействие компьютеров и сетей посредством VPN условно показано на рис. 26.1, 26.2 и 26.6. Однако из этих


Советы об использовании текстовых полей

Из книги автора

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


Ошибка "объект находится в использовании"

Из книги автора

Ошибка "объект находится в использовании" Исключение "object is in use" (объект находится в использовании) заслуживает внимания в контексте применения ограничений ссылочной целостности, поскольку является постоянным источником огорчений для новичков. Firebird не позволяет


8.6. Эхо-клиент UDP: функция dg_cli

Из книги автора

8.6. Эхо-клиент UDP: функция dg_cli В листинге 8.4 показана функция dg_cli, которая выполняет большую часть работы на стороне клиента.Листинг 8.4. Функция dg_cli: цикл обработки клиента//lib/dg_cli.c 1 #include "unp.h" 2 void 3 dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen) 4 { 5  int n; 6  char sendline[MAXLINE], recvline[MAXLINE + 1]; 7 


8.12. Функция dg_cli (продолжение)

Из книги автора

8.12. Функция dg_cli (продолжение) Вернемся к функции dg_cli, показанной в листинге 8.4, и перепишем ее, с тем чтобы она вызывала функцию connect. В листинге 8.7 показана новая функция.Листинг 8.7. Функция dg_cli, вызывающая функцию connect//udpcliserv/dgcliconnect.c 1 #include "unp.h" 2 void 3 dg_cli(FILE *fp, int sockfd, const SA


21.3. Сравнение многоадресной и широковещательной передачи в локальной сети

Из книги автора

21.3. Сравнение многоадресной и широковещательной передачи в локальной сети Вернемся к примерам, представленным на рис. 20.2 и 20.3, чтобы показать, что происходит в случае многоадресной передачи. В примере, показанном на рис. 21.3, мы будем использовать IPv4, хотя для IPv6


21.8 Функция dg_cli, использующая многоадресную передачу

Из книги автора

21.8 Функция dg_cli, использующая многоадресную передачу Мы изменяем нашу функцию dg_cli, показанную в листинге 20.1, просто удаляя вызов функции setsockopt. Как мы сказали ранее, для отправки дейтаграмм многоадресной передачи не нужно устанавливать ни одного параметра сокета