Модераторы: feodorv
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [boost::asio] UDP multicast - непонятное поведение 
V
    Опции темы
cupper
Дата 27.3.2012, 16:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 525
Регистрация: 29.11.2006

Репутация: нет
Всего: 1



Какая то невообразимая штука случилось со мной.

Есть Сервер, вещает данные по UDP multicast на, предположим, 239.192.1.1:9000. 
Есть клиент который слушает эту группу. Получает данные. 

Меняем адрес группы но оставляем тот же порт, и все равно получаем данные. Туда ни кто не вещает, получаем теже данные что и по адресу 239.192.1.1:9000. Меняем еще раз, и опять получаем адрес.

Порт во всех случаях один и тот же, меняется только IP адрес группы.
Для того что бы отбросить сомнения в неправильности свого кода, взял примет с сайта boost
usd receiver
Указал ему порт 9000 какую то случайную группу, <cenzored>, я опять получаю данные.

Данное поведение происходит если клиент запускается на linux. Если запускаем на Win то данные получаем только если укажем корректный адрес группы.

Сервер запущен на линуксе. Использует код аналогичный как в примере boost asio для отправки.
Даже если сервер запускаем на винде то у клиента все равно тоже поведение. 

Еще раз подчеркну, что код кроссплатформенный, при запуске клиента на линуксе он получет данные не зависимо от IP multicast группы, если указан нужный порт (нужный это в смысле куда сервер вещает).

Такое вообще возможно ? Проверялось на нескольких системах и на виртуалке с изолированной сетью. 

Это сообщение отредактировал(а) Олег2005 - 17.4.2012, 12:27
PM MAIL   Вверх
cupper
Дата 28.3.2012, 11:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 525
Регистрация: 29.11.2006

Репутация: нет
Всего: 1



Я не понимаю :(

Написал receiver на чистом Апи сокетов, включил сервер, включил ресивер, порты одинаковые адреса разные  - данные получаю.

Написал sender на Апи, порты одинаковые, адреса разные - данные не получаю.
Взял sender из boost::asio, порты одинаковые, адреса разные - данные не получаю.

Код в проекте и sender одинаковый. цензура!!! как это цензура!!! возможно ???
PM MAIL   Вверх
cupper
Дата 28.3.2012, 14:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 525
Регистрация: 29.11.2006

Репутация: нет
Всего: 1



Итак, выявил ТО при каких условиях воспроизводится проблема.

Имеем апликуху для получения данных из Multicast группы.

Запускаем ее два раза, первый раз с параметрами 
239.192.111.111 9998
вторую с 
239.192.111.112 9998

Берем апликуху sender, запускаем ее с параметрами
239.192.111.111 9998

Получаем данные на обоих receiver'ах.

Воспроизводится на Linux.

---------------------
PS. что бы не быть голословным
receiver
Код

#include <iostream>
#include <sstream>
#include <string>

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>

namespace
{
    void err(const char* err)
    {
        std::cerr << "Err: " << err << std::endl;
        std::cerr << strerror(errno) << std::endl;
    }
}

int create_receiver(const char* ip_addr, const int port)
{
    int sockfd;
    struct sockaddr_in real_addr;
    struct sockaddr_in* addr = &real_addr;
    
    if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    {
        err("create socket");
        return -1;
    }
    
    const int optval = 1;
    if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) != 0)
    {
        err("do setsockopt SO_REUSEADDR");
        close(sockfd);
        return -1;
    }
    
    struct ip_mreq mreq;
    if(inet_aton(ip_addr, &(mreq.imr_multiaddr)) == 0)
    {
        err("do inet_aton");
        close(sockfd);
        return -1;
    }
    mreq.imr_interface.s_addr = htonl(INADDR_ANY);
    
    if(setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) != 0)
    {
        err("do setsockopt IP_ADD_MEMBERSHIP");
        close(sockfd);
        return -1;
    }
    
    if(setsockopt(sockfd, IPPROTO_IP, IP_PKTINFO, &optval, sizeof(optval)) != 0)
    {
        err("do setsockopt IP_PKTINFO");
        close(sockfd);
        return -1;
    }
    
    bzero(addr, sizeof(*addr));
    addr->sin_family = AF_INET;
    addr->sin_port = htons(port);
    addr->sin_addr.s_addr = htonl(INADDR_ANY);
    
    if(bind(sockfd, (sockaddr *)addr, sizeof(*addr)) < 0)
    {
        err("cannot bind");
        close(sockfd);
        return -1;
    }

    return sockfd;
}

int main(int argc, char* argv[])
{    
    int receiver;

    if (argc != 3)
    {
      std::cerr << "Usage: sender <multicast_address>\n";
      std::cerr << "  For IPv4, try:\n";
      std::cerr << "    sender 239.255.0.1 9999\n";
      std::cerr << "  For IPv6, try:\n";
      std::cerr << "    sender ff31::8000:1234 9999\n";
      return 1;
    }
    
    short port = atoi(argv[2]);
    std::cout << "Send to: " << argv[1] << ":" << port << std::endl;
    
    std::cout << "Create receiver" << std::endl;
    if((receiver = create_receiver(argv[1], port)) < 0)
        return 1;
    
    std::cout << "Receiver was created\n";
    
    char msg_buf[300];
    
    int bytesrecv;
    errno = 0;
    for(int i = 0; i < 5; i++)
    {
        std::cout << "Try to receive from: " << argv[1] << ":" << port << std::endl;
        bytesrecv = recv(receiver, msg_buf, sizeof(msg_buf), 0);
        std::cout << std::string(msg_buf, bytesrecv) << std::endl;
    }
    
    close(receiver);
}

sender
Код

#include <iostream>
#include <sstream>
#include <string>

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>

namespace
{
    void err(const char* err)
    {
        std::cerr << "Err: " << err << std::endl;
        std::cerr << strerror(errno) << std::endl;
    }
}

int create_sender(struct sockaddr_in* to, const char* ip_addr, const int port)
{
    int sockfd;
    
    if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    {
        err("create socket");
        return -1;
    }
    
    bzero(to, sizeof(*to));
    to->sin_family = AF_INET;
    to->sin_port = htons(port);
    if(inet_aton(ip_addr, &(to->sin_addr)) == 0)
    {
        err("do inet_aton");
        close(sockfd);
        return -1;
    }

    return sockfd;
}

int main(int argc, char* argv[])
{    
    struct sockaddr_in to;
    int sender;

    if (argc != 3)
    {
      std::cerr << "Usage: sender <multicast_address>\n";
      std::cerr << "  For IPv4, try:\n";
      std::cerr << "    sender 239.255.0.1 9999\n";
      std::cerr << "  For IPv6, try:\n";
      std::cerr << "    sender ff31::8000:1234 9999\n";
      return 1;
    }
    
    short port = atoi(argv[2]);
    std::cout << "Send to: " << argv[1] << ":" << port << std::endl;
    
    std::cout << "Create sender" << std::endl;
    if((sender = create_sender(&to, argv[1], port)) < 0)
        return 1;
    
    std::cout << "Sender was created\n";
    
    std::stringstream sstr;
    sstr << "The UDP datagram was sent from " << argv[1] << ":" << port;
    const char* msg_to_send = sstr.str().c_str();
    size_t msg_to_send_size = sstr.str().length();
    
    int bytesrecv;
    errno = 0;
    for(int i = 0; i < 5; i++)
    {
        std::cout << "Send to: " << argv[1] << ":" << port << std::endl;
        sendto(sender, msg_to_send, msg_to_send_size, 0, (sockaddr *)&to, sizeof(to));
    }
    close(sender);
    
}


Проблема, не решена. Она выявлена, и не понята.

Это сообщение отредактировал(а) cupper - 28.3.2012, 16:30
PM MAIL   Вверх
Олег2005
Дата 28.3.2012, 21:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 421
Регистрация: 26.5.2005
Где: Рига Латвия

Репутация: 6
Всего: 11



Ну, вообще то в мультикасте нет сервера.
Напрочь.
Там есть mrouted - мультикастовый рутер.
А на клиентах только приложения, который могут подключаться к любой группе, таблицу о которых и поддерживает рутер.
Алгоритм работы рутера и описывает протокол IGMP.
Кстати, алгоритм непростой, много таймаутов и опросов/ответов.
Все шлется на рутер  - а он перенаправляет.

PM MAIL WWW MSN   Вверх
cupper
Дата 28.3.2012, 21:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 525
Регистрация: 29.11.2006

Репутация: нет
Всего: 1



Цитата(Олег2005 @ 28.3.2012,  21:44)
Ну, вообще то в мультикасте нет сервера.
Напрочь.
Там есть mrouted - мультикастовый рутер.
А на клиентах только приложения, который могут подключаться к любой группе, таблицу о которых и поддерживает рутер.
Алгоритм работы рутера и описывает протокол IGMP.
Кстати, алгоритм непростой, много таймаутов и опросов/ответов.
Все шлется на рутер  - а он перенаправляет.

вы что то совсем не по делу. Сервер это мое приложение. Если вы хотите, мы можем его называть хоть санта клаусом. 

То что вы дальше написали, я совсем не понимаю как связать с тем что я спросил.
PM MAIL   Вверх
cupper
Дата 29.3.2012, 13:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 525
Регистрация: 29.11.2006

Репутация: нет
Всего: 1



вопрос решен. Обсуждение тут 
LOR
PM MAIL   Вверх
Олег2005
Дата 30.3.2012, 22:07 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 421
Регистрация: 26.5.2005
Где: Рига Латвия

Репутация: 6
Всего: 11



Это вы писали?
Цитата(cupper @  27.3.2012,  15:33 Найти цитируемый пост)
Есть Сервер, вещает данные по UDP multicast на, предположим, 239.192.1.1:9000. 

О каком сервере в мультикасте вы говорите?
Цитата(cupper @  28.3.2012,  20:53 Найти цитируемый пост)
вы что то совсем не по делу. Сервер это мое приложение. Если вы хотите, мы можем его называть хоть санта клаусом. 
То что вы дальше написали, я совсем не понимаю как связать с тем что я спросил. 

Для того чтобы понять - сначала надо ознакомиться с элементарной теорией по IGMP.
А проблемы ваши в том - что на машинах Windows - не поднимается рутер мультикаста.
А на *nix'ах - mrouted  - поднимается по умолчанию.


Это сообщение отредактировал(а) Олег2005 - 30.3.2012, 22:11
PM MAIL WWW MSN   Вверх
cupper
Дата 15.4.2012, 19:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 525
Регистрация: 29.11.2006

Репутация: нет
Всего: 1



Цитата(Олег2005 @  30.3.2012,  22:07 Найти цитируемый пост)
Для того чтобы понять - сначала надо ознакомиться с элементарной теорией по IGMP.

На что в особенности вы хотите акцентировать мое внимание ? Не ходите вокруг да около, скажите прямо в чем я ошибся ?

Цитата(Олег2005 @  30.3.2012,  22:07 Найти цитируемый пост)
А проблемы ваши в том - что на машинах Windows - не поднимается рутер мультикаста.
А на *nix'ах - mrouted  - поднимается по умолчанию.

Не понимаю.  Ну и что, что есть он локально или нет ?

PM MAIL   Вверх
Олег2005
Дата 15.4.2012, 22:35 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 421
Регистрация: 26.5.2005
Где: Рига Латвия

Репутация: 6
Всего: 11



Цитата(cupper @  15.4.2012,  18:30 Найти цитируемый пост)
а что в особенности вы хотите акцентировать мое внимание ? Не ходите вокруг да около, скажите прямо в чем я ошибся ?

Прямо ошиблись?
В идеологии - в Мультикасте - НЕТ серверов.

Цитата(cupper @  15.4.2012,  18:30 Найти цитируемый пост)
Не понимаю.  Ну и что, что есть он локально или нет ?

Если его нет - то мультикаст не существует
По определению.
Протокол IGMP - описывает взаимодействие рутера мультикаста - и клиентов (членов групп).
И если нет рутера - то нет и мультикаста.
PM MAIL WWW MSN   Вверх
cupper
Дата 16.4.2012, 09:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 525
Регистрация: 29.11.2006

Репутация: нет
Всего: 1



Цитата(Олег2005 @  15.4.2012,  22:35 Найти цитируемый пост)
Прямо ошиблись?
В идеологии - в Мультикасте - НЕТ серверов.

У меня есть ПРИЛОЖЕНИЕ которое производит вещания в заданные мультикаст группы. Довольны ?

Цитата(Олег2005 @  15.4.2012,  22:35 Найти цитируемый пост)
Если его нет - то мультикаст не существует
По определению.
Протокол IGMP - описывает взаимодействие рутера мультикаста - и клиентов (членов групп).
И если нет рутера - то нет и мультикаста. 

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

Вы хотя бы поняли какая у меня проблема ? Или вам просто моя терминология не понравилась ?
Мне на самом деле не особо важно куда и как от вещателя идут данные (но я на 99% уверен, что до ближайшего мультикаст роутера). Проблема, в том что... мну лень ее еще раз описывать :( вы по ссылке ходили? Да, там длинная дискуссия. Но и проблема не очевидная.
PM MAIL   Вверх
Олег2005
Дата 17.4.2012, 12:40 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 421
Регистрация: 26.5.2005
Где: Рига Латвия

Репутация: 6
Всего: 11



Вполне возможно ваша проблема лежит в плоскости несовершенной фильтрации (imperfect filtering).
Как пишет Стивенс, фильтрация несовершенна, потому что если интерфейс получает указание принимать кадры, предназначенные только для одного определенного группового адреса Эзернет, может случиться так, что он также будет получать кадры, предназначенные для каких-то других групп.
Проблема в карточках и способах вычисления хеш-функций для идентификации номера группы.
Если хеш совпадет для другой группы - то карта получит этот кадр - и он далее пойдет на порт UDP.
Одно из решений:
Цитата

При помощи профиля IGMP фильтра (IGMP Filter Profile) можно указать к каким мультикаст группам может подключиться порт. Вначале конфигурируется профиль, который позволяет подключаться к определенной(ым) мультикаст группе(ам). После он должен быть назначен на конкретный порт. Только один профиль может быть назначен на физический порт.  

Может в этом и есть ваша проблема.

Это сообщение отредактировал(а) Олег2005 - 17.4.2012, 16:00
PM MAIL WWW MSN   Вверх
cupper
Дата 17.4.2012, 19:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 525
Регистрация: 29.11.2006

Репутация: нет
Всего: 1



эх, не знал о такой проблемы. Я было предположил что фильтрации под линем просто нету. И все что сыплется на один порт но с разных групп, направляется всем кто подписан (сокет) на хотя бы одну из этих групп на этом порте. Частично эту проблему решет bind на адрес нужной мультикаст группы. Но тогда один сокет - одна мультикаст группа.

PS. и все же я сомневаюсь что у меня проблема была в imperfect filtering, потому что у меня разнные данные, разные группы и все это постоянно менялось и даже при сугубо пессимистичном сложении звезд на небе не могло это повторяться на протяжении всех экспериментов, на абсолютно разных системах, адресах, портах и данных.

Это сообщение отредактировал(а) cupper - 17.4.2012, 19:09
PM MAIL   Вверх
Олег2005
Дата 17.4.2012, 21:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 421
Регистрация: 26.5.2005
Где: Рига Латвия

Репутация: 6
Всего: 11



Попробуйте посмотреть вот здесь
PM MAIL WWW MSN   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.0874 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.