2016-12-21 47 views
0

我该如何管理加入一个地址为udp://@224.1.50.15:1234的多播mpeg流组?我想要管理的只是与流服务器建立连接,以使服务器知道我对此多播组感兴趣,以使服务器在一段时间内向我发送流数据包。C++如何加入多播mpeg流?

举例: 在我使用VLC Player建立与组的连接之前,我没有收到此多播组的任何数据包。即使关闭了VLC播放器,我也会在短时间内收到组播包。我试图做的是接收没有VLC播放器或任何其他第三方应用程序的帮助数据包。

我如何设法与上述目的建立联系。如果它甚至可能?

P.S:我安装了4个网络接口。

谢谢!

作为Zaboj Campula在本页的回答中的建议;我改变了代码如下。这给我一个错误10093.

struct ip_mreq { 
    struct in_addr imr_multiaddr; /* IP multicast address of group */ 
    struct in_addr imr_interface; /* local IP address of interface */ 
}; 
SOCKET  s; 
SOCKADDR_IN localif; 
struct ip_mreq mreq; 
s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 
localif.sin_family = AF_INET; 
localif.sin_port = htons(1234); 
localif.sin_addr.s_addr = INADDR_ANY; 
bind(s, (SOCKADDR *)&localif, sizeof(localif)); 
mreq.imr_interface.s_addr = INADDR_ANY; //Writing here my local ip didn't change the result. 
mreq.imr_multiaddr.s_addr = inet_addr("224.1.50.15"); 
int rc = NO_ERROR; 
s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 
// Join the group 
rc = setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mreq, sizeof(mreq)); 
if (rc == SOCKET_ERROR) 
{ 
    printf("JoinMulticastGroup: setsockopt failed with error code %d\n", WSAGetLastError()); 
} 
else 
{ 
    printf("Joined group: "); 
    //PrintAddress(group->ai_addr, group->ai_addrlen); 
    printf("\n"); 
} 
+0

直到有人会写我演讲的题目答案,我决定使用''从libvlc.lib' libvlc_media_new_location'功能。在我看来,这是一个矫枉过正的目的。 – swartkatt

回答

0

好找到一个完整的例子,我设法解决我的问题与书 Multicast Sockets Practical Guide for Programmers which is written by David Makofske & Kevin Almeroth

感谢的的帮助下进入到作家和Zaboj Campula的努力。

我希望这篇文章和答案将在未来帮助许多其他人。 工作代码写在下面! 编译与Visual Studio 2017年RC(控制台为空,C项目)

int sock;      /* socket descriptor */ 
int flag_on = 1;    /* socket option flag */ 
struct sockaddr_in mc_addr; /* socket address structure */ 
char recv_str[MAX_LEN + 1];  /* buffer to receive string */ 
int recv_len;     /* length of string received */ 
struct ip_mreq mc_req;  /* multicast request structure */ 
char* mc_addr_str;   /* multicast IP address */ 
unsigned short mc_port;  /* multicast port */ 
struct sockaddr_in from_addr; /* packet source */ 
unsigned int from_len;  /* source addr length */ 
WSADATA wsaData;    /* Windows socket DLL structure */ 

mc_addr_str = "224.1.50.15";  /* arg 1: multicast ip address */ 
mc_port = atoi("1234"); /* arg 2: multicast port number */ 

          /* validate the port range */ 
if ((mc_port < MIN_PORT) || (mc_port > MAX_PORT)) { 
    fprintf(stderr, "Invalid port number argument %d.\n", 
     mc_port); 
    fprintf(stderr, "Valid range is between %d and %d.\n", 
     MIN_PORT, MAX_PORT); 
    exit(1); 
} 

/* Load Winsock 2.0 DLL */ 
if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) { 
    fprintf(stderr, "WSAStartup() failed"); 
    exit(1); 
} 

/* create socket to join multicast group on */ 
if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { 
    perror("socket() failed"); 
    exit(1); 
} 

/* set reuse port to on to allow multiple binds per host */ 
if ((setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&flag_on, 
    sizeof(flag_on))) < 0) { 
    perror("setsockopt() failed"); 
    exit(1); 
} 

/* construct a multicast address structure */ 
memset(&mc_addr, 0, sizeof(mc_addr)); 
mc_addr.sin_family = AF_INET; 
mc_addr.sin_addr.s_addr = htonl(INADDR_ANY); 
mc_addr.sin_port = htons(mc_port); 

/* bind to multicast address to socket */ 
if ((bind(sock, (struct sockaddr *) &mc_addr, 
    sizeof(mc_addr))) < 0) { 
    perror("bind() failed"); 
    exit(1); 
} 

/* construct an IGMP join request structure */ 
mc_req.imr_multiaddr.s_addr = inet_addr(mc_addr_str); 
mc_req.imr_interface.s_addr = htonl(INADDR_ANY); 

/* send an ADD MEMBERSHIP message via setsockopt */ 
if ((setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, 
    (char*)&mc_req, sizeof(mc_req))) < 0) { 
    perror("setsockopt() failed"); 
    exit(1); 
} 

for (;;) {   /* loop forever */ 

        /* clear the receive buffers & structs */ 
    memset(recv_str, 0, sizeof(recv_str)); 
    from_len = sizeof(from_addr); 
    memset(&from_addr, 0, from_len); 

    /* block waiting to receive a packet */ 
    if ((recv_len = recvfrom(sock, recv_str, MAX_LEN, 0, 
     (struct sockaddr*)&from_addr, &from_len)) < 0) { 
     perror("recvfrom() failed"); 
     exit(1); 
    } 

    /* output received string */ 
    printf("Received %d bytes from %s: ", recv_len, 
     inet_ntoa(from_addr.sin_addr)); 
    printf("%s", recv_str); 
} 

/* send a DROP MEMBERSHIP message via setsockopt */ 
if ((setsockopt(sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, 
    (void*)&mc_req, sizeof(mc_req))) < 0) { 
    perror("setsockopt() failed"); 
    exit(1); 
} 

closesocket(sock); 
WSACleanup(); /* Cleanup Winsock */ 
0

UDP套接字不支持连接。在UDP套接字上不可能调用listenaccept。当绑定到本地端口时,您可以直接从UDP套接字读取数据。

套接字选项IP_ADD_MEMBERSHIP将套接字连接到多播组。

struct ip_mreq m; 
m.imr_interface.s_addr = inet_addr(loca_ip_address); 
m.imr_multiaddr.s_addr = inet_addr("224.1.50.15"); 
setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&m, sizeof(m)); 

您CA在http://www.winsocketdotnetworkprogramming.com/winsock2programming/winsock2advancedmulticast9a.html

+0

你能告诉我我该怎么做?在上面的代码中,我必须改变它以使其成为可能?谢谢! – swartkatt