Вход/Регистрация
UNIX: разработка сетевых приложений
вернуться

Стивенс Уильям Ричард

Шрифт:

t=
задает время начала и время окончания сеанса в единицах NTP (Network Time Protocol — синхронизирующий сетевой протокол), то есть число секунд, прошедшее с 1 января 1900 года, измеренное в соответствии с UTC (Universal Time Coordinated — универсальное скоординированное время). Данный сеанс является постоянным и не имеет конкретных моментов начала и окончания, поэтому соответствующие времена полагаются нулевыми.

Строки

a=
представляют собой атрибуты, либо сеанса, если они помещены до первой строки
m=
, либо мультимедиа, если они помещены после первой строки
m=
.

Строки

m=
— это анонсы мультимедиа. Первая строка говорит нам о том, что видео передается на порт 63 096 в формате RTP с использованием профиля аудио и видео (Audio/Video Profile, AVP) с возможными типами данных 32, 31 и 96 (то есть MPEG, H.261 и WBIH соответственно). Строка
c=
сообщает о соединении. В данном случае используется протокол IPv4 с групповым адресом 224.2.245.25 и TTL = 127. Хотя между этими числами стоит символ «косая черта», как в формате CIDR, они ни в коем случае не должны трактоваться как префикс и маска.

Следующая строка

m=
говорит, что аудиопоток передается на порт 31 954 и может иметь один из типов RTP/AVP, некоторые из которых являются стандартными, в то время как другие указаны ниже в виде атрибутов
a=rtpmap:
. Строка
с=
сообщает нам сведения об аудиосоединении: IPv4 с групповым адресом 224.2.216.85 и TTL = 127.

21.10. Отправка и получение

Программа для получения анонсов сеанса многоадресной передачи, показанная в предыдущем разделе, могла только получать дейтаграммы многоадресной передачи. Теперь мы создадим простую программу, способную и отправлять, и получать дейтаграммы многоадресной передачи. Наша программа состоит из двух частей. Первая часть отправляет дейтаграмму многоадресной передачи определённой группе каждые 5 с. Эта дейтаграмма содержит имя узла отправителя и идентификатор процесса. Вторая часть программы — это бесконечный цикл, присоединяющийся к той группе, которой первая часть программы отправляет данные. В этом цикле выводится каждая полученная дейтаграмма (содержащая имя узла и идентификатор процесса отправителя). Это позволяет нам запустить программу на множестве узлов в локальной сети и посмотреть, какой узел получает дейтаграммы от каких отправителей.

В листинге 21.8 показана функция

main
нашей программы.

Листинг 21.8. Создание сокетов, вызов функции fork и запуск отправителя и получателя

//mcast/main.c

1 #include "unp.h"

2 void recv_all(int, socklen_t);

3 void send_all(int. SA *, socklen_t);

4 int

5 main(int argc, char **argv)

6 {

7 int sendfd, recvfd;

8 const int on = 1;

9 socklen_t salen;

10 struct sockaddr *sasend, *sarecv;

11 if (argc != 3)

12 err_quit("usage: sendrecv <IP-multicast-address> <port#>");

13 sendfd = Udp_client(argv[1], argv[2], (void**)&sasend, &salen);

14 recvfd = Socket(sasend->sa_family, SOCK_DGRAM, 0);

15 Setsockopt(recvfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));

16 sarecv = Malloc(salen);

17 memcpy(sarecv, sasend, salen);

18 Bind(recvfd, sarecv, salen);

19 Mcast_join(recvfd, sasend, salen, NULL, 0);

20 Mcast_set_loop(sendfd, 0);

21 if (Fork == 0)

22 recv_all(recvfd, salen); /* дочерний процесс -> получение */

23 send_all(sendfd, sasend, salen); /* родитель -> отправка */

24 }

Мы создаем два сокета, один для отправки и один для получения. Нам нужно, чтобы принимающий сокет связался при помощи функции

bind
с группой и портом, допустим 239.255.1.2, порт 8888. (Вспомните, что мы могли просто связать универсальный IP-адрес и порт 8888, но связывание с определенным адресом многоадресной передачи предотвращает получение сокетом других дейтаграмм, которые могут прийти на порт получателя 8888.) Далее, нам нужно, чтобы принимающий сокет присоединился к группе. Отправляющий сокет будет отправлять дейтаграммы на этот же адрес многоадресной передачи и этот же порт, то есть на 239.255.1.2, порт 8888. Но если мы попытаемся использовать один сокет и для отправки, и для получения, то адресом отправителя для функции
bind
будет 239.255.1.2.8888 (здесь используется нотация
netstat
), а адресом получателя для функции
sendto
— также 239.255.1.2.8888. Но адрес отправителя, связанный с сокетом, становится IP-адресом отправителя дейтаграммы UDP, a RFC 1122 [10] запрещает дейтаграмме IP иметь IP-адрес отправителя, являющийся адресом многоадресной или широковещательной передачи. (См. также упражнение 21.2.) Следовательно, мы создаем два сокета: один для отправки, другой для получения.

Создание отправляющего сокета

13
Наша функция
udp_client
создает отправляющий сокет, обрабатывая два аргумента командной строки, которые задают адрес многоадресной передачи и номер порта. Эта функция также возвращает структуру адреса сокета, готовую к вызовам функции
sendto
, и длину этой структуры.

Создание принимающего сокета и связывание (при помощи функции bind) с адресом многоадресной передачи и портом
  • Читать дальше
  • 1
  • ...
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: