2011-09-05 6 views
1

J'ai le problème suivant ici: Je veux écrire un serveur de streaming de données sur un socket UDP sur un port spécifique, et les clients devraient pouvoir s'y connecter et recevoir les données qui sont envoyées sans trop beaucoup de tracas: ils se connectent juste, et à partir du moment où ils commencent, ils devraient obtenir des données en utilisant recvfrom du serveur.Diffusion en continu sur UDP

J'ai quelques problèmes avec la mise en place des parties liées au réseau. Donc, voici un morceau rugueux de code que j'essaie de faire le travail:

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); 
} 

Ne vous inquiétez pas la variable gOutgoingAddr, il est obtenu en utilisant correctement getifaddrs, il est valide. Je suis troublé en ce qui concerne la paramétrisation de la méthode sendto, becasue en ce moment la sortie de l'application est:

sendto failure: Destination address required 

Ce qui est vrai, parce que je n'ai pas une adresse de destination, puisque tous les exemples que j'ai trouvé jusqu'à présent afficher quand le serveur obtient une connexion client, et il y a l'adresse. Mais comme je n'ai pas encore de client connecté, je voudrais toujours diffuser.

Je vous remercie de toute l'aide, je ne sais pas ce que iShould mis pour les paramètres de sendto:

  1. Le gOutgoingAddress qui est l'adresse où je crée la prise? J'ai essayé ceci, mais si j'utilise la commande tcpdump linux sur le port spécifié, je n'ai rien.
  2. Dois-je créer une socket de multidiffusion? Cela n'a aucun sens ...
  3. Quelque chose d'autre?

Merci, frc

Répondre

2

Vous ne pouvez pas diffuser vers "nulle part". La diffusion de données via UDP n'est pas multidiffusion. Cela signifie que si vous avez 100 clients connectés, vous devez envoyer exactement les mêmes données 100 fois, une fois à chacun des clients qui le recevront. La multidiffusion ne faisait pas vraiment partie de la conception IPv4 initiale. Il a été ajouté plus tard et n'est pas largement supporté. Ceci est contraire à IPv6, où la multidiffusion a fait partie de la conception initiale.La seule chose que vous pourriez faire est de diffuser le trafic au sein de votre réseau local. Cela ne fonctionnera que si tous les clients se trouvent dans votre segment de réseau local. Pour diffuser votre serveur, il suffit d'envoyer les données au 255.255.255.255 et à un port UDP fixe. Tous les clients doivent alors écouter sur ce port spécifique et recevront les données. Veuillez noter que sur la plupart des systèmes, vous avez besoin d'autorisations spéciales pour la diffusion (par exemple, seuls les programmes exécutant des privilèges root sont autorisés à diffuser du trafic car les diffusions polluent votre réseau car tous les paquets de diffusion sont envoyés à tous les clients du réseau , qu'ils en prennent soin ou non). Sans émissions, vous avez seulement unicast et unicast signifie un expéditeur, un récepteur. Pour un destinataire multiple, vous devez envoyer plusieurs fois les mêmes données à plusieurs adresses.

+1

La multidiffusion est prise en charge par de nombreux routeurs (si ce n'est la plupart) modernes. Ce sont les fournisseurs de services Internet qui peuvent ne pas le supporter. Par exemple, voir [La BBC, Virgin Radio, EMAP et GCAP ont commencé à diffuser leur radio via Multicast] (http://www.bbc.co.uk/multicast/radio/index.shtml). –

+0

Je ne parlais pas de routeurs Internet backbone dans ma réponse. Je parlais de l'équipement typique des réseaux domestiques et de petite entreprise, qui ne prend pas en charge la multidiffusion IPv4, sans tenir compte du fait qu'il ne prend pas en charge la multidiffusion de couche 2 (Ethernet) et utilise la diffusion pour les adresses multicast. – Mecki

0

Quelle est audioUdpSock par la route? Ne devriez-vous pas utiliser udpSock à la place?

+0

question éditée :) audioUdpSock est udpSock, je viens de couper la source d'origine pour jeter tout ce qui n'est pas lié à la question – fritzone

+0

OK :) Je n'ai pas compris le point. Vous essayez de diffuser mais vous n'avez pas d'adresse? Ou vous essayez de diffuser à une adresse quand une demande vient? –

+0

J'essaie de diffuser, et je n'ai pas d'adresse. Je souhaite que plusieurs clients puissent se connecter à mon serveur et commencer à recevoir les données à partir du moment où ils se connectent. – fritzone

0

Effectuez un recvfrom sur votre serveur et demandez au client d'envoyer un message (avec le contenu que vous souhaitez, il s'agit simplement d'un moyen d'établir la connexion, un message d'accueil). Ensuite, le serveur aura l'adresse du client à partir du recvfrom, et peut envoyer un paquet à celui-ci. Comme le socket UDP est sans connexion (il n'est pas nécessaire d'utiliser accept et connect lorsque vous utilisez le socket UDP), vous devez disposer d'un autre moyen pour informer le serveur de l'existence du client (et le client doit avoir un manière hors-limite de connaître l'adresse du serveur, généralement, l'utilisateur le donne, ou il est codé en dur).

Si vous pouvez avoir plusieurs clients, vous devrez utiliser select, poll, ... sur la prise de savoir quand il est sûr d'appeler recvfrom sans bloquer (ou vous pouvez configurer votre socket pour être non blocage).

Modifier: Je recommande fortement Beej's Guide to Network Programming à tout le monde, et pour votre question, vous pouvez aller directement à l'utilisation de l'échantillon de Datagram Socket.

+0

Merci, je vais essayer et poster les mises à jour ici. – fritzone