Потоковая передача по UDP - PullRequest
       29

Потоковая передача по UDP

2 голосов
/ 05 сентября 2011

У меня есть следующая проблема: я хочу записать данные потокового сервера на сокет UDP на конкретном порту, и клиенты должны иметь возможность подключиться к нему и получать отправляемые данные без особых хлопот: они просто подключаются, и с момента запуска они должны получать данные, используя recvfrom с сервера.

У меня проблемы с настройкой сетевых компонентов. Итак, вот пример кода, который я пытаюсь заставить работать:

int udpSock = socket(AF_INET, SOCK_DGRAM, 0);
if(udpSock == -1)
{
    perror("Could not create audio output socket");
    exit(1);
}

struct sockaddr_in *sin = (struct sockaddr_in*)&gOutgoingAddr;
sin->sin_port = htons(40200);
if(bind(udpSock, (const sockaddr*)sin, sizeof(struct sockaddr_in)) == -1)
{
    perror("Cannot bind audio socket");
    exit(1);
}

int buffer_size = 0;
char* data = get_next_buffer(&buffer_size);
while(buffer_size > 0)
{
    if(sendto(udpSock, (const void*)(data), buffer_size, 0, NULL, 0) == -1)
    {
        perror("sendto failure");
    }
    data = get_next_buffer(&buffer_size);
}

Не беспокойтесь о переменной gOutgoingAddr, она получается правильно с помощью getifaddrs, она действительна. Я обеспокоен параметризацией метода sendto, потому что сейчас вывод приложения:

sendto failure: Destination address required

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

Я ценю всю помощь, я понятия не имею, что Ishould поставить для параметров sendto:

  1. gOutgoingAddress, который является адресом, где я создаю сокет? Я пробовал это, но если я использую команду tcpdump linux на указанном порту, я ничего не получаю.
  2. Должен ли я создать многоадресный сокет? Это как-то бессмысленно ...
  3. Что-то еще?

Спасибо, FRC

Ответы [ 3 ]

3 голосов
/ 05 сентября 2011

Вы не можете выйти в "никуда". Потоковая передача данных через UDP не является многоадресной. Это означает, что если у вас подключено 100 клиентов, вы должны отправлять одни и те же данные 100 раз, по одному разу каждому клиенту, который их получит. Многоадресная передача на самом деле не была частью первоначального дизайна IPv4. Он был добавлен позже и широко не поддерживается. Это противоречит IPv6, где многоадресная рассылка была частью первоначального проекта. Единственное, что вы можете сделать, это транслировать трафик в вашей локальной сети. Это будет работать, только если все клиенты находятся в вашем сегменте локальной сети. Для трансляции ваш сервер просто отправит данные на 255.255.255.255 и на фиксированный порт UDP. Затем все клиенты должны прослушивать этот конкретный порт и получать данные. Обратите внимание, что в большинстве систем вам требуются специальные разрешения для широковещания (например, не распространено, что только программы, работающие с привилегиями root, могут транслировать трафик, так как широковещательные сообщения загрязняют вашу сеть, поскольку все широковещательные пакеты отправляются всем клиентам в сети. , заботятся ли они о них или нет). Без широковещательных рассылок у вас есть только одноадресная и одноадресная передача - один отправитель, один получатель. Для одного отправителя, несколько получателей, вы должны отправлять одни и те же данные несколько раз на несколько адресов.

0 голосов
/ 05 сентября 2011

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

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

Если у вас может быть несколько клиентов, вам придется использовать select, poll, ... на сокете, чтобы знать, когда безопасно звонить recvfrom без блокировки (или вы можете настроить сокет должен быть неблокирующим).

Редактировать: я настоятельно рекомендую Руководство Биджа по сетевому программированию для всех, и по вашему вопросу вы можете непосредственно перейти к примеру использования Datagram Socket .

0 голосов
/ 05 сентября 2011

Кстати, что такое audioUdpSock?Разве вы не используете вместо этого udpSock?

...