Я тестирую многоадресную рассылку с помощью двух программ ниже. Клиент хорошо работает в Linux и Wine на двух моих машинах, но он не будет работать должным образом на моей машине с Windows (в Virtualbox).
Странно, если я запускаю vlc в windows и открываю поток 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;
}
Спасибо
Oskar