-
-
Save hostilefork/f7cae3dc33e7416f2dd25a402857b6c6 to your computer and use it in GitHub Desktop.
// | |
// Simple listener.c program for UDP multicast | |
// | |
// Adapted from: | |
// http://ntrg.cs.tcd.ie/undergrad/4ba2/multicast/antony/example.html | |
// | |
// Changes: | |
// * Compiles for Windows as well as Linux | |
// * Takes the port and group on the command line | |
// | |
#ifdef _WIN32 | |
#include <Winsock2.h> // before Windows.h, else Winsock 1 conflict | |
#include <Ws2tcpip.h> // needed for ip_mreq definition for multicast | |
#include <Windows.h> | |
#else | |
#include <sys/types.h> | |
#include <sys/socket.h> | |
#include <netinet/in.h> | |
#include <arpa/inet.h> | |
#include <time.h> | |
#endif | |
#include <string.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#define MSGBUFSIZE 256 | |
int main(int argc, char *argv[]) | |
{ | |
if (argc != 3) { | |
printf("Command line args should be multicast group and port\n"); | |
printf("(e.g. for SSDP, `listener 239.255.255.250 1900`)\n"); | |
return 1; | |
} | |
char* group = argv[1]; // e.g. 239.255.255.250 for SSDP | |
int port = atoi(argv[2]); // 0 if error, which is an invalid port | |
#ifdef _WIN32 | |
// | |
// Initialize Windows Socket API with given VERSION. | |
// | |
WSADATA wsaData; | |
if (WSAStartup(0x0101, &wsaData)) { | |
perror("WSAStartup"); | |
return 1; | |
} | |
#endif | |
// create what looks like an ordinary UDP socket | |
// | |
int fd = socket(AF_INET, SOCK_DGRAM, 0); | |
if (fd < 0) { | |
perror("socket"); | |
return 1; | |
} | |
// allow multiple sockets to use the same PORT number | |
// | |
u_int yes = 1; | |
if ( | |
setsockopt( | |
fd, SOL_SOCKET, SO_REUSEADDR, (char*) &yes, sizeof(yes) | |
) < 0 | |
){ | |
perror("Reusing ADDR failed"); | |
return 1; | |
} | |
// set up destination address | |
// | |
struct sockaddr_in addr; | |
memset(&addr, 0, sizeof(addr)); | |
addr.sin_family = AF_INET; | |
addr.sin_addr.s_addr = htonl(INADDR_ANY); // differs from sender | |
addr.sin_port = htons(port); | |
// bind to receive address | |
// | |
if (bind(fd, (struct sockaddr*) &addr, sizeof(addr)) < 0) { | |
perror("bind"); | |
return 1; | |
} | |
// use setsockopt() to request that the kernel join a multicast group | |
// | |
struct ip_mreq mreq; | |
mreq.imr_multiaddr.s_addr = inet_addr(group); | |
mreq.imr_interface.s_addr = htonl(INADDR_ANY); | |
if ( | |
setsockopt( | |
fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*) &mreq, sizeof(mreq) | |
) < 0 | |
){ | |
perror("setsockopt"); | |
return 1; | |
} | |
// now just enter a read-print loop | |
// | |
while (1) { | |
char msgbuf[MSGBUFSIZE]; | |
int addrlen = sizeof(addr); | |
int nbytes = recvfrom( | |
fd, | |
msgbuf, | |
MSGBUFSIZE, | |
0, | |
(struct sockaddr *) &addr, | |
&addrlen | |
); | |
if (nbytes < 0) { | |
perror("recvfrom"); | |
return 1; | |
} | |
msgbuf[nbytes] = '\0'; | |
puts(msgbuf); | |
} | |
#ifdef _WIN32 | |
// | |
// Program never actually gets here due to infinite loop that has to be | |
// canceled, but since people on the internet wind up using examples | |
// they find at random in their own code it's good to show what shutting | |
// down cleanly would look like. | |
// | |
WSACleanup(); | |
#endif | |
return 0; | |
} |
// | |
// Simple sender.c program for UDP | |
// | |
// Adapted from: | |
// http://ntrg.cs.tcd.ie/undergrad/4ba2/multicast/antony/example.html | |
// | |
// Changes: | |
// * Compiles for Windows as well as Linux | |
// * Takes the port and group on the command line | |
// | |
// Note that what this program does should be equivalent to NETCAT: | |
// | |
// echo "Hello World" | nc -u 239.255.255.250 1900 | |
#ifdef _WIN32 | |
#include <Winsock2.h> // before Windows.h, else Winsock 1 conflict | |
#include <Ws2tcpip.h> // needed for ip_mreq definition for multicast | |
#include <Windows.h> | |
#else | |
#include <sys/types.h> | |
#include <sys/socket.h> | |
#include <netinet/in.h> | |
#include <arpa/inet.h> | |
#include <unistd.h> // for sleep() | |
#endif | |
#include <string.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
int main(int argc, char *argv[]) | |
{ | |
if (argc != 3) { | |
printf("Command line args should be multicast group and port\n"); | |
printf("(e.g. for SSDP, `sender 239.255.255.250 1900`)\n"); | |
return 1; | |
} | |
char* group = argv[1]; // e.g. 239.255.255.250 for SSDP | |
int port = atoi(argv[2]); // 0 if error, which is an invalid port | |
// !!! If test requires, make these configurable via args | |
// | |
const int delay_secs = 1; | |
const char *message = "Hello, World!"; | |
#ifdef _WIN32 | |
// | |
// Initialize Windows Socket API with given VERSION. | |
// | |
WSADATA wsaData; | |
if (WSAStartup(0x0101, &wsaData)) { | |
perror("WSAStartup"); | |
return 1; | |
} | |
#endif | |
// create what looks like an ordinary UDP socket | |
// | |
int fd = socket(AF_INET, SOCK_DGRAM, 0); | |
if (fd < 0) { | |
perror("socket"); | |
return 1; | |
} | |
// set up destination address | |
// | |
struct sockaddr_in addr; | |
memset(&addr, 0, sizeof(addr)); | |
addr.sin_family = AF_INET; | |
addr.sin_addr.s_addr = inet_addr(group); | |
addr.sin_port = htons(port); | |
// now just sendto() our destination! | |
// | |
while (1) { | |
char ch = 0; | |
int nbytes = sendto( | |
fd, | |
message, | |
strlen(message), | |
0, | |
(struct sockaddr*) &addr, | |
sizeof(addr) | |
); | |
if (nbytes < 0) { | |
perror("sendto"); | |
return 1; | |
} | |
#ifdef _WIN32 | |
Sleep(delay_secs * 1000); // Windows Sleep is milliseconds | |
#else | |
sleep(delay_secs); // Unix sleep is seconds | |
#endif | |
} | |
#ifdef _WIN32 | |
// | |
// Program never actually gets here due to infinite loop that has to be | |
// canceled, but since people on the internet wind up using examples | |
// they find at random in their own code it's good to show what shutting | |
// down cleanly would look like. | |
// | |
WSACleanup(); | |
#endif | |
return 0; | |
} |
is that really works?
after a day of setting it is still standing there and here is the sender output: " sendto: Success " but nothing at listener???
@iamfahad43 I used it two weeks ago and had no problems, check your routing is what I would recommend. You can try running the application as an admin or enabling the passthrough through your firewall port.
Thanks :) Couldn't figure out how to use UDP in C
Due to binding to INADDR_ANY
in listener here, the listener receives not only multicast traffic but also unicast from any IP.
setsockopt: No error
Thanks for this example. Can this be used to have a single sender and multiple receivers, all on the same machine/interface? I am going to try it to find out, but if someone is listening, please let me know if this is possible.
I test, It Works.
LOL Love the message in LN 100 of sender.c