diff --git a/packages/multicaster/src/multicaster-serverAWESOME.c b/packages/multicaster/src/multicaster-serverAWESOME.c new file mode 100644 index 0000000..d8b69d0 --- /dev/null +++ b/packages/multicaster/src/multicaster-serverAWESOME.c @@ -0,0 +1,178 @@ +/* multicast_server.c + * Adapted from tmouse's IPv6 client/server example code + * found at http://cboard.cprogramming.com/showthread.php?t=67469 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void DieWithError(const char* errorMessage) +{ + fprintf(stderr, "%s\n", errorMessage); + exit(1); +} + +int main(int argc, char *argv[]) +{ + int sender, listener; /* Sockets */ + char* multicastIP; /* Arg: IP Multicast address */ + char* multicastPort; /* Arg: Server port */ + char* token; + size_t tokenlen; + struct addrinfo * multicastAddr; /* Multicast address */ + struct addrinfo hints = { 0 }; /* Hints for name lookup */ + struct timeval timeout = { 0 }; + + if (argc != 4) + { + fprintf(stderr, "Usage: %s \n", argv[0]); + exit(1); + } + + multicastIP = argv[1]; /* First arg: multicast IP address */ + multicastPort = argv[2]; /* Second arg: multicast port */ + token = argv[3]; + tokenlen = strlen(token); + + /* Resolve destination address for multicast datagrams */ + hints.ai_family = PF_INET6; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_flags = AI_NUMERICHOST; + + if (getaddrinfo(multicastIP, multicastPort, &hints, &multicastAddr) != 0) + { + DieWithError("getaddrinfo() failed"); + } + + /* Create socket for sending multicast datagrams */ + if ((sender = socket(multicastAddr->ai_family, multicastAddr->ai_socktype, 0)) == -1) + { + DieWithError("socket() failed"); + } + + /* Create socket for recieving multicast datagrams */ + if ((listener = socket(multicastAddr->ai_family, multicastAddr->ai_socktype, 0)) == -1) + { + DieWithError("socket() failed"); + } + + { + int hops = 5; + if (setsockopt(sender, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &hops, sizeof(hops)) != 0) + { + DieWithError("setsockopt(MULTICAST_HOPS) failed"); + } + } + + /* Bind to the multicast port */ + if (bind(listener, multicastAddr->ai_addr, multicastAddr->ai_addrlen) != 0) + { + DieWithError("bind() failed"); + } + + /* Join the multicast group. */ + if ((multicastAddr->ai_family == PF_INET6)&&(multicastAddr->ai_addrlen == sizeof(struct sockaddr_in6))) + { + struct sockaddr_in6 *addr = (struct sockaddr_in6 *)(multicastAddr->ai_addr); + struct ipv6_mreq multicastRequest; /* Multicast address join structure */ + + /* Specify the multicast group */ + memcpy(&multicastRequest.ipv6mr_multiaddr, &(addr)->sin6_addr, sizeof(multicastRequest.ipv6mr_multiaddr)); + + /* Accept multicast from any interface */ + multicastRequest.ipv6mr_interface = addr->sin6_scope_id; + + /* Join the multicast address */ + if (setsockopt(listener, IPPROTO_IPV6, IPV6_JOIN_GROUP, (char*) &multicastRequest, sizeof(multicastRequest)) != 0) + { + DieWithError("setsockopt(IPV6_JOIN_GROUP) failed"); + } + } else { + DieWithError("Not IPv6"); + } + + for (;;) /* Run forever */ + { + int n; + int max_fd; + fd_set input; + + char recvString[500]; /* Buffer for received string */ + int recvStringLen; /* Length of received string */ + + char sendString[] = "Say Hello\n"; + size_t sendStringLen = sizeof(sendString)-1; + char errorString[] = "That is not correct! Try again!\n"; + + struct sockaddr_in6 from; + socklen_t fromlen = sizeof(from); + + FD_ZERO(&input); + FD_SET(listener, &input); + + max_fd = listener + 1; + + if (timeout.tv_usec < 100) + { + timeout.tv_sec = 1; + timeout.tv_usec = 0; + + int sendLen = sendto(sender, sendString, sendStringLen, 0, multicastAddr->ai_addr, + multicastAddr->ai_addrlen); + if (sendLen == sendStringLen) + { + printf("Sent [%s] (%i bytes) to %s, port %s\n", sendString, sendLen, + multicastIP, multicastPort); + } else { + DieWithError("sendto() sent a different number of bytes than expected"); + } + } + + n = select(max_fd, &input, NULL, NULL, &timeout); + + /* See if there was an error */ + if (n < 0) + { + perror("select failed"); + } else if (n == 0) { + puts("TIMEOUT"); + } else { + if (FD_ISSET(listener, &input)) + { + recvStringLen = recvfrom(listener, recvString, sizeof(recvString) - 1, 0, + (struct sockaddr *)&from, &fromlen); + /* Receive a single datagram from the server */ + if (recvStringLen < 0) + { + DieWithError("recvfrom() failed"); + } + + recvString[recvStringLen] = '\0'; + if (strcmp(recvString, "hello")==0) + { + printf("Correct!!\n"); + sendto(listener, token, sizeof(sendString), 0, (struct sockaddr *)&from, fromlen); + } else if (strcmp(recvString, sendString)!=0) { + sendto(listener, errorString, sizeof(errorString), 0, (struct sockaddr *)&from, fromlen); + } + + /* Print the received string */ + printf("Received string [%s]\n", recvString); + } + } + } + + /* NOT REACHED */ + freeaddrinfo(multicastAddr); + close(sender); + close(listener); + + return 0; +}