2011-03-15 48 views
0

我正在测试多播与下面的两个程序。客户端在我的两台机器上在linux和wine上运行良好,但在我的Windows机器上(在Virtualbox中)无法正常工作。奇怪的是,如果我在windows中启动vlc并打开udp流,客户端程序将接收数据包 - 当我停止vlc时,客户端再次进入沉默状态。在Windows XP上的多播问题

我在做什么错?

这里是服务器程序:

/* 
* 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; 
} 

和这里的客户端程序:

/* 
* 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; 
} 

感谢,

奥斯卡

回答

0

好了,显然是防火墙阻止了数据包。关闭它解决了这个问题。

+0

很幸运,许多虚拟机实际上并不支持多播。它长期以来只限于VMware ESX。 – 2011-03-17 19:42:16