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;
}
感謝,
奧斯卡
很幸運,許多虛擬機實際上並不支持多播。它長期以來只限於VMware ESX。 – 2011-03-17 19:42:16