Форум программистов, компьютерный форум, киберфорум
C/С++ под Linux
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.70/43: Рейтинг темы: голосов - 43, средняя оценка - 4.70
39 / 39 / 24
Регистрация: 13.05.2010
Сообщений: 282
Записей в блоге: 1

Принять по UDP multicast медиа-поток MPEG2-TS

18.07.2012, 13:39. Показов 8981. Ответов 16
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Прочитал про сокеты и как подключиться к multicast group.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
 
using namespace std;
 
int main()
{
    int sock;
 
    if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    {
        perror("socket");
        return -1;
    }
    cout << "Socket was created." << endl;
 
    const int optival = 1;
    setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optival, sizeof(optival));
 
    struct sockaddr_in addr;
    bzero(&addr, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(3425);
    addr.sin_addr.s_addr = inet_addr("10.10.20.14");
 
    bind(sock, (sockaddr *)&addr, sizeof(addr));
 
    struct ip_mreq mreq;
    mreq.imr_interface.s_addr = inet_addr("127.0.0.1");
    mreq.imr_multiaddr.s_addr = inet_addr("237.7.7.7");
 
   if ((setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq))) != 0)
   {
       perror("multicast");
       return -2;
   }
   cout << "Join to multicast group." << endl;
 
   close(sock);
 
    return 0;
}
Как теперь начать принимать от сервера пот UDP медиа-поток? Знаю, что есть функция recvfrom, которая возвращяет количество считываемых байтов и записывает данные в переменную. Какого типа должна быть переменная и правильно ли я подключаюсь к multicast group?

Добавлено через 2 часа 43 минуты
Уточню вопрос. Есть сервер, который вещяет медиа-поток по UDP. IP и multicast group я знаю. Мне надо написать клиент, с помощью которого я смогу подключиться к серверу и multicast group и получить медиа-поток. Пока что проблема возникла с подключением к multicast group. В данный момент застрял на подключение к multicast group. Подскажите, что я делаю не правильно?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
18.07.2012, 13:39
Ответы с готовыми решениями:

UDP - MUlticast
Добрый день. Кто-нибудь сталкивался с такой неожиданность, как зависание приема используя udp соединение, и передачу по Multicast? ...

LwIP + UDP + multicast
Добрый день, в предыдущей теме https://www.cyberforum.ru/arm/thread2192192.html, получилось наладить передачу/прием UDP пакетов с помощью...

multicast udp ipv6
Доброго времени суток! Можете объяснить, почему setsockopt() выдает ошибку no error, и если ее проигнорировать, то recvfrom() не получает...

16
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
18.07.2012, 15:06
Цитата Сообщение от Khelleos Посмотреть сообщение
Подскажите, что я делаю не правильно?
Если код не работает, то
Цитата Сообщение от Khelleos Посмотреть сообщение
mreq.imr_interface.s_addr = inet_addr("127.0.0.1");
либо Вы не понимаете, что это значит, либо в системе не настроен форвардинг мультикаст трафика на lo.
1
39 / 39 / 24
Регистрация: 13.05.2010
Сообщений: 282
Записей в блоге: 1
18.07.2012, 16:01  [ТС]
Сообщение от Khelleos
Подскажите, что я делаю не правильно?
Если код не работает, то
Сообщение от Khelleos
mreq.imr_interface.s_addr = inet_addr("127.0.0.1");
либо Вы не понимаете, что это значит, либо в системе не настроен форвардинг мультикаст трафика на lo.
Скорее не понимаю. Читал тут http://www.winsocketdotnetwork... ast9a.html
но плохо понял. Не могли бы вы объяснить?
А что такое форвардинг мультикаст трафика на lo?
0
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
18.07.2012, 16:22
Ваше, "mreq.imr_interface.s_addr = inet_addr("127.0.0.1");" означает, что Вы просите систему добавить интерфейс которому принадлежит этот адрес в мультикаст группу. На 99.99% систем этот адрес принадлежит интерфейсу lo0. Т.е. это будет работать только если сервер живет на localhost, либо настроен проброс/пересыл (я хз как правильней сказать forwarding по-русски) мультикаста с реального сетевого интерфейса на lo. Вам нужно написать там локальный адрес интерфейса (например eth0, судя по коду у Вас это 10.10.20.14) по которому реально бегает мультикаст трафик, либо написать INADDR_ANY, позволив системе выбрать интерфейс за Вас (в случае когда в системе несколько интерфейсов она это может делать не правильно/не так как Вы хотите).
1
39 / 39 / 24
Регистрация: 13.05.2010
Сообщений: 282
Записей в блоге: 1
18.07.2012, 16:54  [ТС]
Цитата Сообщение от g_u_e_s_t Посмотреть сообщение
Ваше, "mreq.imr_interface.s_addr = inet_addr("127.0.0.1");" означает, что Вы просите систему добавить интерфейс которому принадлежит этот адрес в мультикаст группу. На 99.99% систем этот адрес принадлежит интерфейсу lo0. Т.е. это будет работать только если сервер живет на localhost, либо настроен проброс/пересыл (я хз как правильней сказать forwarding по-русски) мультикаста с реального сетевого интерфейса на lo. Вам нужно написать там локальный адрес интерфейса (например eth0, судя по коду у Вас это 10.10.20.14) по которому реально бегает мультикаст трафик, либо написать INADDR_ANY, позволив системе выбрать интерфейс за Вас (в случае когда в системе несколько интерфейсов она это может делать не правильно/не так как Вы хотите).
Что-то я запутался. У меня появилось пару вопросов для уточнения.
Здесь я создаю переменную, в которой храниться порт и ip сервера(10.10.20.14).
C++
1
2
3
4
5
struct sockaddr_in addr;
    bzero(&addr, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(3425);
    addr.sin_addr.s_addr = inet_addr("10.10.20.14");
Тут все правильно?

Дальше я создаю переменную, в которой храниться информация о multicast group.
C++
1
struct ip_mreq mreq;
Вещание идет по upd://237.7.7.7:10700 и это должно храниться в mreq.imr_multiaddr.s_addr, так?
А что должно храниться тогда в mreq.imr_interface.s_addr?
0
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
18.07.2012, 17:13
Цитата Сообщение от Khelleos Посмотреть сообщение
Здесь я создаю переменную, в которой храниться порт и ip сервера(10.10.20.14).Тут все правильно?
Нет, тут Вы должны указать адрес и порт на которые Вы будите принимать мультикаст поток. Порт должен быть 10700, а не 3425.

Цитата Сообщение от Khelleos Посмотреть сообщение
Вещание идет по upd://237.7.7.7:10700 и это должно храниться в mreq.imr_multiaddr.s_addr, так?
Да, тут должно быть 237.7.7.7
Цитата Сообщение от Khelleos Посмотреть сообщение
А что должно храниться тогда в mreq.imr_interface.s_addr?
Локальнай адрес интерфейса(можно алиас) через который Вы хотите подписаться на группу.

Т.е псевдокодом делаете так:
bind(локальный_ip_адрес_интерфейса_eth0: порт_с_которого_вещает_сервер);
setsockopt(,,IP_ADD_MEMBERSHIP,[imr_interface=локальный_ip_адрес_интерфе йса_eth0 imr_multiaddr=ip_адрес_с_которого_вещает _сервер)
1
39 / 39 / 24
Регистрация: 13.05.2010
Сообщений: 282
Записей в блоге: 1
18.07.2012, 21:48  [ТС]
Нет, тут Вы должны указать адрес и порт на которые Вы будите принимать мультикаст поток. Порт должен быть 10700, а не 3425.
Значит будет так
C++
1
2
3
addr.sin_family = AF_INET;
addr.sin_port = htons(10700);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
Дальше по multicast
C++
1
2
mreq.imr_interface.s_addr = inet_addr("10.10.20.14") //адрес машины, с которой идет вещание, да?;
mreq.imr_multiaddr.s_addr = inet_addr("237.7.7.7"); //udp адрес, по которому идет вещание
Я все правильно понял?
0
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
19.07.2012, 09:54
Цитата Сообщение от Khelleos Посмотреть сообщение
mreq.imr_interface.s_addr = inet_addr("10.10.20.14") //адрес машины, с которой идет вещание, да?;
Цитата Сообщение от g_u_e_s_t Посмотреть сообщение
Вам нужно написать там локальный адрес интерфейса
Цитата Сообщение от g_u_e_s_t Посмотреть сообщение
Локальнай адрес интерфейса(можно алиас) через который Вы хотите подписаться на группу
Цитата Сообщение от g_u_e_s_t Посмотреть сообщение
imr_interface=локальный_ip_адрес_интерфе йса
Простите, но я не знаю какими еще словами сказать, что это не "адрес машины, с которой идет вещание"
0
39 / 39 / 24
Регистрация: 13.05.2010
Сообщений: 282
Записей в блоге: 1
19.07.2012, 11:10  [ТС]
imr_interface=локальный_ip_адрес_интерфе йса
хорошо, тогда правильно будет так imr_interface = "127.0.0.1" (или мой ip "192.168.11.66")?

Тогда почему вы сказали про struct sockaddr_in addr, что
Нет, тут Вы должны указать адрес и порт на которые Вы будите принимать мультикаст поток. Порт должен быть 10700, а не 3425.
То есть я опять должен указать ip машины, на которую буду принимать или я должен указать адрес машины, с которой идет вещание(ip адрес)?
0
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
19.07.2012, 11:29
Цитата Сообщение от Khelleos Посмотреть сообщение
хорошо, тогда правильно будет так imr_interface = "127.0.0.1"
Дежавю.
Цитата Сообщение от Khelleos Посмотреть сообщение
(или мой ip "192.168.11.66")?
или 0.0.0.0
Цитата Сообщение от Khelleos Посмотреть сообщение
Тогда почему вы сказали про struct sockaddr_in addr, что
Потому что так есть.
Цитата Сообщение от Khelleos Посмотреть сообщение
Нет, тут Вы должны указать адрес и порт на которые Вы будите принимать мультикаст поток. Порт должен быть 10700, а не 3425.
То есть я опять должен указать ip машины, на которую буду принимать
Отквоченное Вами же можно понять как-то иначе?
Цитата Сообщение от Khelleos Посмотреть сообщение
или я должен указать адрес машины, с которой идет вещание(ip адрес)?
Делай те, как хотите. Простите, печатных слов у меня уже не осталось.
0
39 / 39 / 24
Регистрация: 13.05.2010
Сообщений: 282
Записей в блоге: 1
19.07.2012, 11:47  [ТС]
Чтобы получать медиа-поток по UDP.
Мне же сначала надо подключиться к серверу, а потом уже присоединиться к multicast group.

1) создаю сокет(AF_INET, DGRAM, IPPROT_UDP)
2) создаю struct sockaddr_in addr, в которой указываю ip и порт машины, к которой подключаюсь
C++
1
2
3
addr.sin_family = AF_INET;
addr.sin_port = htons(554);
addr.sin_addr.s_addr = inet_addr("10.10.20.14");
3) связываю сокет с адресом с помощью функции bind
C++
1
bind(sock, (struct sockaddr *)&addr, sizeof(addr)
4) создаю struct ip_mreq mreq и указываю в mreq.imr_interface.s_addr = inet_addr("127.0.0.1") (ну или адрес моей машины - 192.168.11.66), а в mreq.imr_multiaddr.s_addr = inet_addr("237.7.7.7"); (upd, по ко-му идет вещание);

5)
C++
1
setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq))
В каких пунктах я ошибся?

Добавлено через 1 минуту
Цитата Сообщение от g_u_e_s_t Посмотреть сообщение
Дежавю.
или 0.0.0.0

Потому что так есть.
Отквоченное Вами же можно понять как-то иначе?
Делай те, как хотите. Простите, печатных слов у меня уже не осталось.
Честно говоря, я еще больше запутался после вас(
0
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
19.07.2012, 11:58
Цитата Сообщение от Khelleos Посмотреть сообщение
Честно говоря, я еще больше запутался после вас(
Начните с начала, с азов, где рассказывают о том, что у UDP нет понятия соединения, по этому "подключиться к серверу" не выйдет. Потом почитайте что-нибудь линукс специфичное, где расскажут про то, что линукс не умеет BIND_ANY и соответственно сделать bind() на "создаю struct sockaddr_in addr, в которой указываю ip и порт машины, к которой подключаюсь" тоже не получиться.
0
dmzavr
21.07.2012, 00:13
Да все верно в твоем 1-м посте было написано. В бинде не тот адрес просто. - Чтобы снова не тереть ... и если по-простому ..., то с чтением выглядит как-то так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
 
#include <errno.h>
#include <poll.h>
#include <fcntl.h>
 
using namespace std;
 
#define BUFF_SIZE 1024
#define ASYNC_READ_TO_MSEC 5000
 
char buffer[BUFF_SIZE];
 
/// Sync reading
void sync_reading(int sock) 
{
 
    size_t bytes2read(BUFF_SIZE);
   
    cout << "Socket reading started" << endl;
    for(;;) {
        int s = read(sock, buffer, bytes2read);
        if( 0 > s
            && EAGAIN != errno
            ) 
        {
            perror("reading socket");
            break;
        }
        // ........ Received piece of broadcasting data is in buffer now. 
        cout << "read " << s << " bytes" << endl;
    }
    cout << "Socket reading complete" << endl;    
}
 
/// Async reading.
void async_reading(int sock, int timeout)
{
    if( -1 == fcntl(sock, F_SETFL, O_NONBLOCK) ) {
        perror("seting non-block state");
        return;
    }
 
    for(;;) {
        size_t bytes2read(BUFF_SIZE);
        struct pollfd pollfd[1];
        pollfd[0].fd = sock;
        pollfd[0].events = POLLIN | POLLRDNORM;
    
        int nevents = poll(pollfd, 1, timeout);
        if( 1 == nevents 
            && pollfd[0].revents & (POLLIN | POLLRDNORM)
            ) 
        {
            int s = read(sock, buffer, bytes2read);
            if(0 <= s) {
                // ........ Received piece of broadcasting data is in buffer now. 
                cout << "read " << s << " bytes" << endl;
            } else if(errno == EAGAIN || errno == EWOULDBLOCK) // This error is OK for async read
                continue;   
            else {
                perror("async-reading socket");
                break;
            }
                
        } else {
            cout << "Timeout (" << timeout << "msec) elapsed while broadcast start/continue awaiting" << endl;
            break;
        }
    }
}
 
int main()
{
    int sock;
 
    if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    {
        perror("socket");
        return -1;
    }
    cout << "Socket was created." << endl;
 
    const int optival = 1;
    setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optival, sizeof(optival));
 
    struct sockaddr_in addr;
    bzero(&addr, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(3425);
    addr.sin_addr.s_addr = inet_addr("237.7.7.7"); // Multicast-group address here.
 
    bind(sock, (sockaddr *)&addr, sizeof(addr));
 
    struct ip_mreq mreq; // Use ip_mreqn, instead. Avail since v.2.2 kernel. See "man 7 ip" 
    mreq.imr_interface.s_addr = INADDR_ANY; //inet_addr("192.168.1.4"); ///< YOUR PC local address(or INADDR_ANY to let the kernel to make choice). I.e. your client host address (not the TV broadcasting server) 
    mreq.imr_multiaddr.s_addr = inet_addr("237.7.7.7");   ///< Multicast-group address where TV server is broadcasting to and which we should to join with
    if ((setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq))) != 0)
    {
        perror("multicast");
        return -2;
    }
    cout << "Joined to multicast group." << endl;
 
    // Next, use one of sync_reading or async_reading (see 2 funcs above)
    // sync_readig(sock);
    async_reading(sock, ASYNC_READ_TO_MSEC);
 
    close(sock);
 
    return 0;
}
Кстати, если под рукой нет сетки с трансляцией, моно заюзать vlc плеер:
1. Запускаем (из консоли) мультикастовую трансляцию какой-нибудь авишки/мп3-шки:
vlc -vvv <файл_с_какой-нибудь_авишкой> --sout udp:237.7.7.7:3425 --ttl 12 --loop
2. Для порядка проверяем, что трансляция действительно идет (должны увидеть/услышать картинку/звук):
vlc udp://@237.7.7.7:3425
3. Запускаем нашу утилитку.

Добавлено через 9 минут
Цитата Сообщение от dmzavr Посмотреть сообщение
В бинде не тот адрес просто.
ну и в джойне к мультикасту 127.0.0.1 - тоже косяк, конечно.
39 / 39 / 24
Регистрация: 13.05.2010
Сообщений: 282
Записей в блоге: 1
21.07.2012, 10:39  [ТС]
спасибо
0
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
24.07.2012, 09:07
Цитата Сообщение от dmzavr Посмотреть сообщение
addr.sin_addr.s_addr = inet_addr("237.7.7.7"); // Multicast-group address here.
рыдаю.
"Терли,терли, вроде перетерли" так следующий вылез...
0
39 / 39 / 24
Регистрация: 13.05.2010
Сообщений: 282
Записей в блоге: 1
24.07.2012, 15:14  [ТС]
Уже разобрался с сокетами. Думаю, тема закрыта.
0
0 / 0 / 0
Регистрация: 04.02.2015
Сообщений: 8
11.05.2013, 00:51
Давайте запилим утилиту, принимающую UDP в стандартный канал

Я сделать отличный сервер выдачи звука на винде с помощью VCL
C:\win\VLCPortable\VLCPortable.exe dshow://dshow-adev=Virtual Cable 1 --sout=#transcode{acodec=mp3,ab=320,channe ls=2,samplerate=44100}:std{access=udp,mu x=raw,dst=192.168.1.2:1234}

мой роутер должен принять UDP и передать музыку в mp3 плеер. Работать должно вот так:
утилита | madplay -i --tty-control -

Я сам вообще не программер, мне просто нужна утилита. вот такая вот односложная, без лишенего (пока) функционала.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
11.05.2013, 00:51
Помогаю со студенческими работами здесь

Multicast udp sender
Как известно IPTV для трансляции каналов использует multicast, то есть хост источник отправляет поток пакетов на груповой ip, а клиенты...

UDP Multicast на Qt 4.6.2 Linux
Доброго времени суток. Пишу программу, которая отправляет некие данные по UDP. При этом должен использоваться Multicast. Полез в...

Запрос на UDP Multicast
Просьба сильно не пинать, но не селен я в сетях... В общем-то нужно отправить определённый текс на UDP Multicast и получить ответ, может...

Udp multicast поиск сервера
Добрый день. Помогите разобраться с точками. Вообщем суть в следующем коде: Клиент отправляет в общую группу запрос на поиск, сервер его...

UDP Multicast Internet возможно?
Здравствуйте, подскажите возможен ли вообще UDP Multicast в Интернете, а не только в Локальной сети, на Европейский форумах кто чего пишет....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Новые блоги и статьи
Воспроизведение звукового файла с помощью SDL3_mixer при касании экрана Android
8Observer8 26.01.2026
Содержание блога SDL3_mixer - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
Установка Android SDK, NDK, JDK, CMake и т.д.
8Observer8 25.01.2026
Содержание блога Перейдите по ссылке: https:/ / developer. android. com/ studio и в самом низу страницы кликните по архиву "commandlinetools-win-xxxxxx_latest. zip" Извлеките архив и вы увидите. . .
Вывод текста со шрифтом TTF на Android с помощью библиотеки SDL3_ttf
8Observer8 25.01.2026
Содержание блога Если у вас не установлены Android SDK, NDK, JDK, и т. д. то сделайте это по следующей инструкции: Установка Android SDK, NDK, JDK, CMake и т. д. Сборка примера Скачайте. . .
Использование SDL3-callbacks вместо функции main() на Android, Desktop и WebAssembly
8Observer8 24.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
моя боль
iceja 24.01.2026
Выложила интерполяцию кубическими сплайнами www. iceja. net REST сервисы временно не работают, только через Web. Написала за 56 рабочих часов этот сайт с нуля. При помощи perplexity. ai PRO , при. . .
Модель сукцессии микоризы
anaschu 24.01.2026
Решили писать научную статью с неким РОманом
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru