aboutsummaryrefslogtreecommitdiffstats
path: root/tests/virtsock/virtsock_client_mcast.c
blob: b49d75510819e8aea84247403dfed0d38826cc5e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/* client.c */
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
/* Adresse für multicast IP */
static char *host_name = "224.0.0.1";
static int port = 6666;
static struct ip_mreq command;

static int setup_multicast_socket(void)
{
	int loop = 1;
	int socket_descriptor;
	struct sockaddr_in sin;
	memset(&sin, 0, sizeof(sin));
	sin.sin_family = AF_INET;
	sin.sin_addr.s_addr = htonl(INADDR_ANY);
	sin.sin_port = htons(port);
	if ((socket_descriptor = socket(AF_INET,
	SOCK_DGRAM, IPPROTO_UDP)) == -1) {
		perror("socket()");
		exit(EXIT_FAILURE);
	}
	/* Mehr Prozessen erlauben, denselben Port zu nutzen */
	loop = 1;
	if (setsockopt(socket_descriptor,
	SOL_SOCKET,
	SO_REUSEADDR, &loop, sizeof(loop)) < 0) {
		perror("setsockopt:SO_REUSEADDR");
		exit(EXIT_FAILURE);
	}
	if (bind(socket_descriptor, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
		perror("bind");
		exit(EXIT_FAILURE);
	}
	/* Broadcast auf dieser Maschine zulassen */
	loop = 1;
	if (setsockopt(socket_descriptor,
	IPPROTO_IP,
	IP_MULTICAST_LOOP, &loop, sizeof(loop)) < 0) {
		perror("setsockopt:IP_MULTICAST_LOOP");
		exit(EXIT_FAILURE);
	}
	/* Join the broadcast group: */
	command.imr_multiaddr.s_addr = inet_addr(host_name);
	command.imr_interface.s_addr = htonl(INADDR_ANY);
	if (command.imr_multiaddr.s_addr == -1) {
		perror("Keine Multicast-Adresse\n");
		exit(EXIT_FAILURE);
	}
	if (setsockopt(socket_descriptor,
	IPPROTO_IP,
	IP_ADD_MEMBERSHIP, &command, sizeof(command)) < 0) {
		perror("setsockopt:IP_ADD_MEMBERSHIP");
	}
	if(fcntl(socket_descriptor, F_SETFL, fcntl(socket_descriptor, F_GETFL) | O_NONBLOCK) < 0) {
		perror("fcntl:SOCK_SET_NONBLOCK");
	}


//	memset(&sin, 0, sizeof(sin));
//	sin.sin_family = AF_INET;
//	sin.sin_port = htons(57286);
//	inet_pton(AF_INET, "192.168.5.48", &sin.sin_addr);
//	if (connect(socket_descriptor, (struct sockaddr *) &sin, sizeof(sin)) !=0 ) {
//		perror ("connect()");
//	}

	return socket_descriptor;
}
int main(void)
{
	int iter = 0;
	socklen_t sin_len;
	char message[256];
	int socket;
	struct sockaddr_in sin;
	struct hostent *server_host_name;
	if ((server_host_name = gethostbyname(host_name)) == 0) {
		perror("gethostbyname");
		exit(EXIT_FAILURE);
	}
	socket = setup_multicast_socket();
	/* Broadcast-Nachrichten empfangen */
	// while (iter++ <= 10) {
	while (++iter <= INT_MAX) {
		sin_len = sizeof(sin);
		char addr[32];
		int port;
		while (!recvfrom(socket, message, 256, 0, (struct sockaddr *)&sin,
		                &sin_len)) {
		}
		inet_ntop(AF_INET, &sin.sin_addr, addr, 32);
		port = ntohs(sin.sin_port);
		printf("Message %d von %s:%d: %s\n", iter, addr, port, message);
		sendto(socket, "Received your message", sizeof("Received your message"), 0, (struct sockaddr *)&sin,
	                sin_len);
	}
	/* Multicast-Socket aus der Gruppe entfernen */
	if (setsockopt(socket,
	IPPROTO_IP,
	IP_DROP_MEMBERSHIP, &command, sizeof(command)) < 0) {
		perror("setsockopt:IP_DROP_MEMBERSHIP");
	}
	close(socket);
	return EXIT_SUCCESS;
}