/* * TimeCastSrvr.c (c) Bob Quinn 3/15/97 * * Released to the public domain * * Description: * Sample multicast server (sender) application that multicasts the * system time for clients (receivers) to use to set their clocks. */ #include #include #include #include #define BUFSIZE 1024 #define MAXADDRSTR 16 #define TIMECAST_ADDR "234.5.6.7" #define TIMECAST_PORT 8910 #define TIMECAST_TTL 2 #define TIMECAST_INTRVL 0 char achMCAddr[MAXADDRSTR] = TIMECAST_ADDR; u_long lMCAddr; u_short nPort = TIMECAST_PORT; u_long lTTL = TIMECAST_TTL; u_short nInterval = TIMECAST_INTRVL; SYSTEMTIME stSysTime; void show_usage(void) { printf( "usage: TimeCastSrvr [-g multicast address][:port number]\n"); printf(" [-t IP time-to-live\n\n"); printf(" multicast address: 224.0.0.0 to 239.255.255.255\n"); printf(" port number: server's port\n\n"); printf("If none provided, default values are %s:%d.\n", TIMECAST_ADDR, TIMECAST_PORT); printf(" IP time-to-live: number of router hops (default: 2)\n"); } int main(int argc, char *argv[]) { int nRet, i; BOOL fFlag; SOCKADDR_IN stLclAddr, stDstAddr; struct ip_mreq stMreq; /* Multicast interface structure */ SOCKET hSocket; WSADATA stWSAData; /* Display program banner */ printf("------------------------------------------------------\n"); printf(" AudioStreamSrvr - multicast audio server\n"); printf("------------------------------------------------------\n"); /* Process input arguments */ if ((argc == 2) && ((strcmp(argv[1],"-help")==0) || (strcmp(argv[1],"-?")==0))) { show_usage(); exit(1); } /* Init WinSock */ nRet = WSAStartup(0x0202, &stWSAData); if (nRet) { printf ("WSAStartup failed: %d\r\n", nRet); exit (1); } fFlag = FALSE; for (i=1; i= 0xe0000000) || (lMCAddr <= 0xefffffff))) { printf ("Invalid address %s provided by user.\n", argv[1]); printf ("using default address: %s\n", achMCAddr); } else { strcpy (achMCAddr, argv[i+1]); /* Address is ok */ } } continue; } /* IP time-to-live setting (scope of multicast send) */ if (argv[i][1] == 't') { fFlag = TRUE; lTTL = atoi(argv[i+1]); if ((lTTL <= 0) || (lTTL > 255)) { printf ( "Invalid IP time-to-live, using default of %d.\n", TIMECAST_TTL); } } } /* Display current settings */ printf ("Multicast Address:%s, Port:%d, IP TTL:%d, Interval:%d\n", achMCAddr, nPort, lTTL, nInterval); /* Get a datagram socket */ hSocket = socket(AF_INET, SOCK_DGRAM, 0); if (hSocket == INVALID_SOCKET) { printf ("socket() failed, Err: %d\n", WSAGetLastError()); exit(1); } /* Bind the socket * * NOTE: Normally, we wouldn't need to call bind unless we were * assigning a local port number explicitly (naming the socket), * however Microsoft requires that a socket be bound before it * can join a multicast group with setsockopt() IP_ADD_MEMBERSHIP * (or fails w/ WSAEINVAL). */ stLclAddr.sin_family = AF_INET; stLclAddr.sin_addr.s_addr = htonl(INADDR_ANY); /* any interface */ stLclAddr.sin_port = 0; /* any port */ nRet = bind(hSocket, (struct sockaddr*) &stLclAddr, sizeof(stLclAddr)); if (nRet == SOCKET_ERROR) { printf ("bind() port: %d failed, Err: %d\n", nPort, WSAGetLastError()); } /* Join the multicast group * * NOTE: According to RFC 1112, a sender does not need to join the * group, however Microsoft requires a socket to join a group in * order to use setsockopt() IP_MULTICAST_TTL (or fails with error * WSAEINVAL). */ stMreq.imr_multiaddr.s_addr = inet_addr(achMCAddr); stMreq.imr_interface.s_addr = INADDR_ANY; nRet = setsockopt(hSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&stMreq, sizeof(stMreq)); if (nRet == SOCKET_ERROR) { printf ( "setsockopt() IP_ADD_MEMBERSHIP address %s failed, Err: %d\n", achMCAddr, WSAGetLastError()); } /* Set IP TTL to traverse up to multiple routers */ nRet = setsockopt(hSocket, IPPROTO_IP, IP_MULTICAST_TTL, (char *)&lTTL, sizeof(lTTL)); if (nRet == SOCKET_ERROR) { printf ("setsockopt() IP_MULTICAST_TTL failed, Err: %d\n", WSAGetLastError()); } /* Disable loopback */ fFlag = FALSE; nRet = setsockopt(hSocket, IPPROTO_IP, IP_MULTICAST_LOOP, (char *)&fFlag, sizeof(fFlag)); if (nRet == SOCKET_ERROR) { printf ("setsockopt() IP_MULTICAST_LOOP failed, Err: %d\n", WSAGetLastError()); } /* Assign our destination address */ stDstAddr.sin_family = AF_INET; stDstAddr.sin_addr.s_addr = inet_addr(achMCAddr); stDstAddr.sin_port = htons(nPort); int count = 0; // load an audio buffer from a sound file sf::SoundBuffer buffer; const sf::Int16* pSample; sf::Int16 * pSound; sf::Int16 * temp; size_t sampleCount, sampleRate, channelCount; buffer.loadFromFile("test.wav"); sampleRate = buffer.getSampleRate(); channelCount = buffer.getChannelCount(); pSample = buffer.getSamples(); sampleCount = buffer.getSampleCount(); pSound = const_cast(pSample); temp = const_cast(pSample); char * test; // initialize and play our custom stream for (;;) { test = (char *)temp; /*--------------------------------------- Read File ----------------------------------------*/ /* Send the time to our multicast group! */ nRet = sendto(hSocket, test, sizeof(sampleRate), 0, (struct sockaddr*)&stDstAddr, sizeof(stDstAddr)); if (nRet < 0) { printf ("sendto() failed, Error: %d\n", WSAGetLastError()); exit(1); } printf("Sent...\n"); count++; &temp[count*sampleRate]; /* Wait for the specified interval */ //Sleep(nInterval*1000); } /* end for(;;) */ /* Close the socket */ closesocket(hSocket); /* Tell WinSock we're leaving */ WSACleanup(); return (0); } /* end main() */