2011-03-15 4 views
0

Je teste la multidiffusion avec les deux programmes ci-dessous. Le client tourne bien sur linux et dans le vin sur deux de mes machines, mais cela ne fonctionnera pas correctement sur ma machine Windows (dans Virtualbox). Etrangement, si je démarre vlc dans Windows et que j'ouvre le flux udp, le programme client reçoit les paquets - et quand j'arrête vlc, le client se tait à nouveau.Problème de multidiffusion sous Windows XP

Qu'est-ce que je fais mal?

Voici le programme du serveur:

/* 
* server.c - multicast server program. 
*/ 

#include <sys/types.h> 
#ifdef WINDOWS 
#include <winsock.h> 
#include <windows.h> 
#else 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 
#endif 
#include <time.h> 
#include <string.h> 
#include <stdio.h> 


#define HELLO_PORT 5004 
#define HELLO_GROUP "224.0.0.1" 

int main(int argc, char *argv[]) 
{ 
    struct sockaddr_in addr; 
    int fd, cnt, numbytes; 
    struct ip_mreq mreq; 
    char message[100]; 

#ifdef WINDOWS 
    WSADATA wsaData; /* Windows socket DLL structure */ 

    if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) { 
     fprintf(stderr, "WSAStartup() failed"); 
     return 1; 
    } 
#endif 

    /* create what looks like an ordinary UDP socket */ 
    if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { 
     fprintf(stderr, "failed to create socket.\n"); 
     return 1; 
    } 

    /* set up destination address */ 
    memset(&addr, 0, sizeof(addr)); 
    addr.sin_family = AF_INET; 
    addr.sin_addr.s_addr = inet_addr(HELLO_GROUP); 
    addr.sin_port = htons(HELLO_PORT); 

    /* now just sendto() our destination! */ 
    cnt = 0; 
    while (1) { 
     numbytes = sprintf(message, "%d", cnt); 
     if (sendto(fd, message, numbytes, 0, (struct sockaddr*)&addr, 
        sizeof(addr)) < 0) { 
      fprintf(stderr, "sendto failed.\n"); 
      return 1; 
     } 
#ifdef WINDOWS 
     Sleep(1000); 
#else 
     sleep(1); 
#endif 
     cnt++; 
    } 

    return 0; 
} 

et voici le programme client:

/* 
* client.c -- client program for udp multicast data. 
*/ 

#include <sys/types.h> 
#ifdef WINDOWS 
#include <winsock.h> 
#else 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 
#endif 
#include <time.h> 
#include <string.h> 
#include <stdio.h> 


#define HELLO_GROUP "224.0.0.1" 
#define HELLO_PORT 5004 
#define MSGBUFSIZE 256 

int main(int argc, char *argv[]) 
{ 
    struct sockaddr_in addr; 
    int fd, nbytes,addrlen; 
    struct ip_mreq mreq; 
    char msgbuf[MSGBUFSIZE]; 
    u_int yes = 1; 

#ifdef WINDOWS 
    WSADATA wsaData; /* Windows socket DLL structure */ 

    if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) { 
     fprintf(stderr, "WSAStartup() failed"); 
     return 1; 
    } 
#endif 

    /* create what looks like an ordinary UDP socket */ 
    fd = socket(AF_INET, SOCK_DGRAM, 0); 
    if (fd == -1) { 
     fprintf(stderr, "failed to create socket.\n"); 
     return 1; 
    } 


    /* allow multiple sockets to use the same PORT number */ 
    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&yes, sizeof(yes)) != 0) { 
     fprintf(stderr, "failed to reuse port number.\n"); 
     return 1; 
    } 

    /* set up destination address */ 
    memset(&addr, 0, sizeof(addr)); 
    addr.sin_family = AF_INET; 
    addr.sin_addr.s_addr = INADDR_ANY; 
    addr.sin_port = htons(HELLO_PORT); 

    /* bind to receive address */ 
    if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) != 0) { 
     fprintf(stderr, "failed to bind socket.\n"); 
     return 1; 
    } 

    /* use setsockopt() to request that the kernel join a multicast group */ 
    mreq.imr_multiaddr.s_addr = inet_addr(HELLO_GROUP); 
    mreq.imr_interface.s_addr = INADDR_ANY; 

    if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char*)&mreq, sizeof(mreq)) != 0) { 
     fprintf(stderr, "failed to join the multicast group.\n"); 
     return 1; 
    } 

    /* now just enter a read-print loop */ 
    while (1) { 
     addrlen = sizeof(addr); 
     nbytes = recvfrom(fd, msgbuf, MSGBUFSIZE, 0, 
       (struct sockaddr*)&addr, &addrlen); 

     if (nbytes < 0) { 
      fprintf(stderr, "recfrom failed, %d\n", nbytes); 
      return 1; 
     } 

     msgbuf[nbytes] = '\0'; 
     puts(msgbuf); 
    } 

    return 0; 
} 

Merci,

Oskar

Répondre

0

Ok, donc apparemment le pare-feu ont bloqué la paquets. L'éteindre règle le problème.

+0

Vous avez de la chance, de nombreuses machines virtuelles ne prennent pas en charge la multidiffusion. Il était limité à VMware ESX depuis longtemps. –