2011-03-15 50 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