Windows XP上的多播问题

时间:2011-03-15 10:34:07

标签: windows multicast

我正在使用以下两个程序测试多播。客户端在linux和我的两台机器上运行良好,但在我的Windows机器上(在Virtualbox中)无法正常工作。

奇怪的是,如果我在Windows中启动vlc并打开udp流,客户端程序会收到数据包 - 当我停止vlc时,客户端会再次静默。

我做错了什么?

这是服务器程序:

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

谢谢,

奥斯卡

1 个答案:

答案 0 :(得分:0)

好的,显然防火墙阻止了数据包。关闭它可以解决问题。